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();
posted @ 2021-11-23 11:21  薛定谔の三味  阅读(70)  评论(0编辑  收藏  举报