QDialog
模态
QWidget默认为非模态,QDialog默认为模态,模态会有一个返回值,可以判断接下来的操作
模态:当一个窗口以模态显示,那么所有其他窗口的事件都被阻塞(停止运行),直到模态窗口关闭
非模态:多个窗口之间互不阻塞,允许多个窗口同时与用于进行交互
半模态:会阻塞其他窗口,但与模态不同的是代码会继续往下执行,而不是停止直到窗口关闭
属性
exec() 阻塞有返回值
done(int i) 设置返回值
result() 返回返回值
setWindow
槽
accept() 返回QDialog::Accepted(1)
reject() 返回QDialog::Rejected(0)
重载QDialog实现自定义XMessageBox
右击项目添加->Add Qt Class,选择Qt GUI Class,基类选QDialog
添加一个QWidget,在其中添加一个QLabel、两个QPushButton
修改样式表时,防止父类样式影响子类样式,可以用#+对象名的方式指定对象
xmessagebox.h
#pragma once
#include <QDialog>
#include "ui_xmessagebox.h"
class XMessageBox : public QDialog
{
Q_OBJECT
public:
XMessageBox(QWidget *parent = Q_NULLPTR);
~XMessageBox();
static int info(QString txt);
private:
Ui::XMessageBox ui;
};
xmessagebox.cpp
#include "xmessagebox.h"
XMessageBox::XMessageBox(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
this->setWindowFlags(Qt::FramelessWindowHint); //去掉标题栏
this->setAttribute(Qt::WA_TranslucentBackground, true); //设置背景透明
}
XMessageBox::~XMessageBox()
{
}
int XMessageBox::info(QString txt)
{
XMessageBox box;
box.ui.label->setText(txt);
return box.exec();
}
main.cpp
#include "xmessagebox.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
XMessageBox::info(QStringLiteral("我是谁"));
return a.exec();
}
QProgressBar
线程模拟实现加载进度条
新建QtGUI项目TestPro
在ui界面放一个ProgressBar控件
testpro.h
#pragma once
#include <QtWidgets/QDialog>
#include "ui_testpro.h"
class TestPro : public QDialog
{
Q_OBJECT
public:
TestPro();
private:
Ui::TestProClass ui;
public slots:
void SetPos(int pos);
};
testpro.cpp
#include "testpro.h"
TestPro::TestPro()
{
ui.setupUi(this);
}
void TestPro::SetPos(int pos)
{
ui.progressBar->setValue(pos);
}
load.h
#pragma once
#include <QThread>
class Load : public QThread
{
Q_OBJECT
public:
Load();
~Load();
protected:
void run();
signals:
void SetPos(int pos);
};
load.cpp
#include "load.h"
Load::Load()
{
}
Load::~Load()
{
}
void Load::run()
{
for (int i = 0; i < 101; ++i)
{
SetPos(i);
msleep(10);
}
}
main.cpp
#include "testpro.h"
#include "load.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TestPro w;
Load ld;
QObject::connect(&ld, SIGNAL(SetPos(int)), &w, SLOT(SetPos(int)));
ld.start();
w.show();
return a.exec();
}
QEventLoop
实现同时处理多个事件
当进度条加载完成时,我们想让进度条逐渐透明化退出,并用一个QLabel显示透明度,这时会发现文本没有变化,这是因为当一个控件(线程)执行事件时,其他控件(线程)的事件会阻塞,这时我们可以用QEventLoop处理阻塞的事件
void Pro::SetPos(int pos)
{
ui.progressBar->setValue(pos);
if (pos == 1000)
{
for (int i = 100; i > 0; --i)
{
this->setWindowOpacity((float)i / 100.0); //设置透明度
QThread::msleep(10);
ui.label->setText(QString::number(i)); //progressBar处理完后,才会处理label
QEventLoop loop;
loop.processEvents(); //处理一次所有被阻塞的事件
}
this->close();
}
}