Qt6入门教程 9:QWidget、QMainWindow和QDialog

Qt6入门教程 9:QWidget、QMainWindow和QDialog在用 QtCreator 创建 QtWidgets 项目时 会默认提供三种基类以供选择 它们分别是 QWidget QMainWIndow 和 QDialog 其中 QMainWindow 和 QDialog 的基类都是 QWidget

目录

一.QWidget

1.窗口和控件

2.事件

二.QMainWindow

三.QDialog

1.模态对话框

1.1.模态对话框

1.2.半模态对话框

2.非模态对话框

3.小结


在用Qt Creator创建Qt Widgets项目时,会默认提供三种基类以供选择,它们分别是QWidget、QMainWIndow和QDialog,其中QMainWindow和QDialog的基类都是QWidget。

一.QWidget

QWidget是所有用户界面对象的基类,它从窗口系统中接收鼠标、键盘和其他事件,并在屏幕上绘制自己。未嵌入到父窗口的小部件称为窗口,否则称之为控件。通常窗口包含边框和标题栏,当然也可用设置窗口标志(window flags)去掉窗口的边框和标题栏。在Qt中,QMainWindow和QDialog的各种子类是最常见的窗口类型。

1.窗口和控件

通常情况下,如果需要嵌入到其他窗口中,则基于QWidget创建。 

2.事件

小部件会响应用户操作产生的各种事件。Qt通过QEvent子类实例调用特定的事件处理函数(QEvent子类中包含每个事件的详细信息),将事件传递到小部件。
下面是与QWidget相关事件的简介。
●最常用的事件处理函数
paintEvent():小部件重绘时被调用。如果要显示自定义内容,必须实现它。使用QPainter绘制只能在paintEvent()或paintEvent()调用的函数中进行。
resizeEvent():小部件大小变化时被调用
mousePressEvent():通常在两种情况下被调用。一是鼠标指针在小部件内,并了鼠标按键;二是小部件通过grabMouse()函数把鼠标抢占了。按下鼠标不放和调用grabMouse()的效果是一样的。
mouseReleaseEvent():当鼠标按键释放时被调用。小部件只有在接收了相应的鼠标按下事件,才会接收鼠标释放事件,这两事件是一一对应的关系。有一个例外,如果在按住鼠标的同时弹出菜单,则此弹出菜单会立即偷走鼠标事件(进入菜单的事件循环中)。
mouseDoubleClickEvent():在小部件中双击会被调用。双击实际上是当做两次单击处理的,如果双击的时候手抖了,可能还会收到鼠标移动事件。需要注意的是,在第二次到达之前,是无法区分单击和双击的,所以不要试图在双击事件里处理单击逻辑。
●如果要接受键盘输入,需要多实现几个事件处理函数
keyPressEvent():当键盘按键按下是被调用。长按会重复调用。
focusInEvent():当小部件获取键盘焦点时被调用。
focusOutEvent():当小部件失去键盘焦点时被调用。
●不那么常用的事处理函数
mouseMoveEvent():当鼠标按键按下且移动鼠标时被调用。这在拖拽时非常有用。如果调用了setMouseTracking(true),不用按下鼠标也能也能触发这个事件啦。
keyReleaseEvent():在键盘按键释放时被调用。
wheelEvent():当焦点在小部件上,滚动鼠标滚轮时被调用。
enterEvent():当鼠标移动到小部件时被调用。但不包括其中的子部件,比如窗口中有个按钮,鼠标移动到按钮上并不会触发窗口的enterEvent。
leaveEvent():当鼠标移动到小部件时被调用。同理,鼠标离开了子部件,不会触发父部件的leaveEvent。
moveEvent():当小部件在父窗口中移动时被调用。
closeEvent():当小部件关闭时被调用。
有些事件并没有预置的事件处理函数,处理这些事件时,需要直接重写event()。所有的事件类型,详见:Qt Assistant—>QEvent::Type
关于Qt的事件系统,后面会用一篇博客单独介绍。

二.QMainWindow

QMainWindow是Qt框架自带的一个预定义好的主窗口类。所谓主窗口,就是一个应用程序最顶层的窗口,比如Qt Creator就是一个主窗口。经典的主窗口通常是由一个标题栏,一个菜单栏,若干工具栏和一个任务栏组成。在这些子组件之间则是我们的工作区。事实上,QMainWindow正是这样的一种布局,如下图所示:

在QMainWindow中可以添加QMenuBar(菜单栏)、QToolBar(工具栏)、QStatusBar(状态栏)以及QDockWidget(停靠窗体)
QMainWindow中必须要有Central Widget(中心小部件),中心小部件可以是Qt自带控件,比如QTextEdit或QGraphicsView,也可以是自定义控件。可以通过setCentralWidget()函数来设置中心小部件。
当QMainWindow用于单文档(SDI)或多文档(MDI)应用程序,可以将QMdiArea设置为中心小部件。
下面是设置QTextEdit为中心小部件的代码。
●新建txt文件,将后缀改为pro,pro内容如下:

QT       += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets SOURCES += \     main.cpp
#include <QApplication> #include <QMainWindow> #include <QTextEdit> int main(int argc, char *argv[]) {     QApplication a(argc, argv);     QMainWindow w;     w.setWindowTitle("https://blog.csdn.net/caoshangpa");     QTextEdit textEdit;     w.setCentralWidget(&textEdit);     w.resize(400, 300);     w.show();     return a.exec(); }

运行一下:


关于如何添加菜单栏、工具栏和状态栏将在下一篇中介绍。

三.QDialog

#include <QApplication> #include <QDialog> int main(int argc, char *argv[]) {     QApplication a(argc, argv);     QDialog w;     w.setSizeGripEnabled(true);     w.setWindowTitle("https://blog.csdn.net/caoshangpa");     w.resize(400, 300);     w.show();     return a.exec(); }


箭头所指的就是QSizeGrip,它在无边框窗口时非常有用,可以通过拖动右下角缩放窗口。状态栏(QStatusBar)自带这个小部件,所以如果你用到了状态栏,就不需要再显式的添加QSizeGrip了。

1.模态对话框

模态对话框有两种application modal(默认)和window modal,可以通过 setWindowModality()函数设置,该函数参数是枚举值,如下表所示:

参数 描述
Qt::NonModal 0 该窗口不是模式窗口,不会阻止对其他窗口的访问
Qt::WindowModal 1 阻止访问与对话相关联的窗口,比如它的父窗口
Qt::ApplicationModal 2 阻止访问应用程序的所有其他窗口

1.1.模态对话框

#include <QApplication> #include <QMainWindow> #include <QDialog> #include <QPushButton> #include <QDebug> int main(int argc, char *argv[]) {     QApplication a(argc, argv);     QMainWindow w;     QDialog d(&w);     d.setWindowTitle("CSDN");     QPushButton pushButton;     QObject::connect(&pushButton, &QPushButton::clicked, [&] {         d.exec();         qDebug() << "test";     });     pushButton.setText("Press Me");     w.setCentralWidget(&pushButton);     w.setWindowTitle("https://blog.csdn.net/caoshangpa");     w.resize(400, 300);     w.show();     return a.exec(); }

运行一下:


此时,对话框关闭后才会打印“test”

1.2.半模态对话框

#include <QApplication> #include <QMainWindow> #include <QDialog> #include <QPushButton> #include <QDebug> int main(int argc, char *argv[]) {     QApplication a(argc, argv);     QMainWindow w;     QDialog d(&w);     d.setModal(true);     // 与上面那句效果一样.     // d.setWindowModality(Qt::ApplicationModal);     d.setWindowTitle("CSDN");     QPushButton pushButton;     QObject::connect(&pushButton, &QPushButton::clicked, [&] {         d.show();         qDebug() << "test";     });     pushButton.setText("Press Me");     w.setCentralWidget(&pushButton);     w.setWindowTitle("https://blog.csdn.net/caoshangpa");     w.resize(400, 300);     w.show();     return a.exec(); }

或者去掉d.setModal(true);并将d.show()改为d.open(),因为d.open()与下面这两句等效:

d.setWindowModality(Qt::WindowModal); d.show();

运行效果与模态对话框相同。不过,对话框弹出后会立即打印“test”。

2.非模态对话框

非模态对话框是和同一个程序中其它窗口操作无关的对话框。在文字处理中的查找和替换对话框通常是非模态的,允许用户同时与应用程序的主窗口和对话框进行交互。调用show()来显示非模态对话框,并立即将控制权返回给调用者。
在上面的代码中去掉d.setModal(true);就是非模态对话框了
运行一下:

对话框弹出后,继续按钮,可以看到,非模态对话框并不会阻塞按钮对鼠标的响应。

3.小结

显示对话框的方法有show()、open()和exec()三种。
●如果对话框已经有模态特性,则用show()方法显示的对话框具有模态特性。
●如果对话框没有模态特性,则用show()方法显示的对话框没有模态特性。
●无论对话框是否有模态特性,用open()或exec()方法显示的对话框都是模态对话框,其中用open()方法显示的对话框默认是window modal,用exec()方法显示的对话框默认是application modal。
●当程序执行到show()或open()方法时,显示对话框后会继续执行后续的代码;用exec()方法显示对话框时,需关闭对话框后才执行exec()语句的后续代码。

原文链接:Qt6入门教程 9:QWidget、QMainWindow和QDialog-CSDN博客 

今天的文章 Qt6入门教程 9:QWidget、QMainWindow和QDialog分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-11 22:57
下一篇 2024-12-11 22:51

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/83303.html