memoの關于Qt的一些用法記錄
Qt自動調整窗口尺寸
之前寫過,方法就是:
QTimer::singleShot(0, this, [this]{ this->adjustSize(); });
重復記錄一下。
如何把一個Modal的窗口放到QMainWindow的中心顯示
也挺有意思。其實就是
auto* dlg = new MyDialog(nullptr); // 這里最好是設置為nullptr,后面記得delete掉。
dlg->setModal(true);
dlg->show(); // 關鍵就是這里。先show一下,然后下面去move
dlg->move(mainWindow->frameGeometry().center() - dlg->rect().center());
關于子窗口,如果是要設置為FrameLess的,如果子窗口還有parent,顯示上就會有問題。所以,我覺得設置為nullptr更好用一些。
Qt多線程的一些問題
都是熱乎的。
QThread::create
利用QThread::create可以很方便的創建一個異步調用的函數。簡單的示例如下:
auto* thread = QThread::create([]{
for (int i=0; i<100; ++i) {
// do something
QThread::msleep(100);
}
});
connect(thread, &QThread::finished, &Qbject::deleteLater); // 記得釋放掉
thread->start(); // qt文檔特別聲明:只調用1次start
connect有意思的地方
connect(thread, &Thread::finished, [thread]{qDebug() << QThread::currentThreadId(); thread->deleteLater(); });
connect(thread, &Thread::finished, this, [thread]{qDebug() << QThread::currentThreadId(); thread->deleteLater(); });
運行一下就能看到,上面的connect是在thread線程內執行的;而下面的則是在this所在的線程執行的(this多半是QMainWindow)。
加載進度窗
當然,如果只是上面這點東西,不值得記錄下來。舉個實際的例子。在QMainWindow內,我們想要實現一個加載文件的action,然后加載文件的期間可能會比較慢,在這期間放置一個加載窗在哪里搖啊搖。
首先是加載的窗口:
WaitingDialog::WaitingDialog(QWidget *parent) : QDialog(parent), ui(new Ui::WaitingDialog)
{
ui->setupUi(this);
this->setModal(true);
this->setWindowFlags(Qt::FramelessWindowHint); // 設置窗口無邊框
this->setAttribute(Qt::WA_TranslucentBackground); // 窗口的背景透明。如果gif是透明的更好
// 用movie來播放動畫
auto *movie = new QMovie(ui->label);
movie->setFileName(":/res/waiting.gif");
ui->label->setMovie(movie); // UI文件就是放了一個QLabel
movie->start();
}
然后我們就可以開始加載操作了:
// 首先顯示一個WaitingDialog
auto *dlg = new WaitingDialog(nullptr);
dlg->show();
dlg->move(this->frameGeometry().center() - dlg->rect().center());
// 創建一個線程,異步調用LoadFile的操作。
auto *thread = QThread::create([this] {
this->loadFile(); // 不可出現ui相關的操作,qt不允許子線程操作ui的。
});
// 記得加上結束后的回調,放到主線程執行。主線程可以處理UI。
connect(thread, &QThread::finished, this, [this, dlg, thread] {
this->updateUI();
dlg->close();
dlg->deleteLater(); // 別忘了刪掉等待窗口
thread->deleteLater(); // 別忘了刪掉線程
});
// 最關鍵的別忘了start。一次就好。
thread->start();

浙公網安備 33010602011771號