2

学习QT系列03 - 应用、窗口和控件

 1 year ago
source link: https://blog.devwiki.net/2023/07/11/study-qt-03-qapplication-qWindow-qwidget.html#cl-8
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

学习QT系列03 - 应用、窗口和控件

发表于2023-07-11 | 更新于 2023-07-11 | QT
字数总计: 10424 | 阅读时长: 7分钟 | 阅读量: 25

DevWiki Blog

20230711192732.png

在前面的学习中:学习QT系列2 - CMake - DevWiki Blog,我们学习Qt项目的结构和构建语言Cmake。本文学习一个Qt应用的基本组成,包含窗口和控件系统。

在前面的项目中,main.cpp包含了Qt 应用的一些定义:

https://git.devwiki.net/Qt/FirstQt/src/branch/master/main.cpp
#include "mainwindow.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "FirstQt_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    MainWindow w;
    w.show();
    return a.exec();
}

在上述代码中我们看到一个Qt 的GUI 应用包含:

  • QApplication : 一个应用程序类的实例化对象
  • MainWindow : 一个 QMainWindow的实例化对象

而MainWindow的源码如下:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

说明 MainWindow 是继承自 QMainWindow 类,且声明了 MainWindow的 ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget"/>
  <widget class="QMenuBar" name="menubar"/>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

在上述代码中,MainWindow包含了:

  • QWidget : 一个名为中间的控件
  • QMenu : 一个菜单条
  • QStatusBar : 一个状态条

image.png

综上所述,一个通用的 Qt 界面应用包含:

  • QApplication :表示一个 Qt 应用程序的实例化对象
  • QMainWindow : 一个主窗口。
  • QWidget :若干个控件。

1. Qt 的Application类

在上述代码中,QApplication a(argc, argv);实例化了一个 QApplication 对象,查看官方的接口文档可知 QApplication 关系图如下:

db5dc26bd0eb7378ab2f181e2b4b8d00.svg
  • QObject:Qt对象模型的基类,它提供了许多面向对象编程的特性,如信号与槽机制、对象树等
  • QCoreApplication : 继承自QObject的类,用于创建和管理一个应用程序。它提供了一些应用程序级别的功能,如事件循环和事件处理。
  • QGuiApplication : 继承自QCoreApplication的类,用于创建和管理一个具有图形界面的应用程序。它在QCoreApplication的基础上添加了一些与图形界面相关的功能,如窗口系统集成和事件过滤。
  • QApplication : 继承自QGuiApplication的类,用于创建和管理一个具有图形界面的桌面应用程序。它在QGuiApplication的基础上添加了一些与桌面应用程序相关的功能,如窗口管理、菜单和工具栏等。

这些类之间的继承关系表示了它们之间的层次关系和共享的功能。由此可见:

  • 如果我们不需要应用界面,则使用 QCoreApplication类来实例化。
  • 如果需要自定义窗口管理,则可使用QGuiApplication类。
  • 如果我们需要通用的窗口管理和事件处理实现界面,则使用 QApplication类。

2. Qt应用的窗口Window

在概述章节中我们知道 QMainWindow是Qt 应用的主窗口,查询官方的文档可知其关系如下:

5ef69618f5878c8b8de855534b742335.svg

从上图我们可以看到其之间的关系:

  • QObject:是Qt框架中所有类的基类,它提供了对象的基本功能和特性。
  • QSurface:是一个抽象类,继承自QObject,用于表示可绘制的表面。
  • QWindow:是继承自QObject和QSurface的类,表示一个窗口对象,继承了它们的功能和特性。
  • QPaintDevice:是一个抽象类,继承自QObject,用于表示可绘制的设备。
  • QPaintDeviceWindow:是继承自QWindow和QPaintDevice的类,表示一个可绘制的窗口设备。
  • QOpenGLWindow:是继承自QPaintDeviceWindow的类,表示一个使用OpenGL进行绘制的窗口。
  • QRasterWindow:是继承自QPaintDeviceWindow的类,表示一个使用光栅化方式(即像素级别的绘制)进行绘制的窗口。
  • QWidget:是继承自QObject和QPaintDevice的类,表示一个可视化的窗口部件。它是QObject和QPaintDevice的子类,继承了它们的功能和特性。
  • QMainWindow:是继承自QWidget的类,表示一个主窗口部件,通常用作应用程序的主界面。
  • QMdiSubWindow:是继承自QWidget的类,表示一个多文档界面(MDI)中的子窗口。
  • QDialog:是继承自QWidget的类,表示一个对话框窗口,用于与用户进行交互

其中的QDialog还有不同的实现子类,继承关系如下:

37ce44e9935d5ac96d0246e7bc97c894.svg
  • QColorDialog 是一个用于选择颜色的对话框。
  • QErrorMessage 是一个用于显示错误信息的对话框。
  • QFileDialog 是一个用于选择文件或目录的对话框。
  • QFontDialog 是一个用于选择字体的对话框。
  • QInputDialog 是一个用于获取用户输入的对话框。
  • QMessageBox 是一个用于显示消息框的对话框。
  • QProgressDialog 是一个用于显示进度对话框的对话框。
  • QWizard 是一个用于创建向导对话框的对话框。

从Application章节以及官方文档,可知:

  • 自定义窗口时使用 QGuiApplication,并自己继承 QWindow类,并实例化。
  • 使用通用窗口时使用QApplication类,并实例化或者继承 QMainWindow。

自定义窗口的使用如下:

#include <QGuiApplication>
#include <QWindow>
#include <QPainter>

class CustomWindow : public QWindow
{
public:
    CustomWindow() {}

protected:
    void paintEvent(QPaintEvent *) override {
        QPainter painter(this);
        painter.fillRect(0, 0, width(), height(), Qt::blue);
    }
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    CustomWindow window;
    window.setTitle("Custom Window");
    window.resize(400, 300);
    window.show();

    return app.exec();
}

3. Qt的控件系统

在概述中,我们知道QMainWindow中包含了若干个 Widget。查询官方文档 QWideget 可知它们的关系如下:

bdc7b66cc17a8119dd02ce568b4b0533.svg

具体子控件如下:

  • QAbstractButton : 按钮的抽象基类,提供了按钮的基本功能和特性。
  • QAbstractSlider : 滑动条的抽象基类,提供了滑动条的基本功能和特性。
  • QAbstractSpinBox:抽象基类,用于创建可编辑的数值输入框。
  • QCalendarWidget:日历控件,用于显示和选择日期。
  • QComboBox:下拉框控件,提供了一个可选择的列表和一个可编辑的文本框。
  • QDesignerActionEditorInterface:设计师动作编辑器接口,用于自定义设计师中的动作编辑器。
  • QDesignerFormWindowInterface:设计师窗口接口,用于自定义设计师中的窗口。
  • QDesignerObjectInspectorInterface:设计师对象检查器接口,用于自定义设计师中的对象检查器。
  • QDesignerPropertyEditorInterface:设计师属性编辑器接口,用于自定义设计师中的属性编辑器。
  • QDesignerWidgetBoxInterface:设计师部件盒接口,用于自定义设计师中的部件盒。
  • QDesktopWidget:桌面部件,用于获取桌面的相关信息和进行屏幕布局。
  • QDialog:对话框窗口,用于与用户进行交互。
  • QDialogButtonBox:对话框按钮部件,用于显示和管理对话框中的按钮。
  • QDockWidget:可停靠的窗口部件,可以在主窗口中自由移动和停靠。
  • QFocusFrame:焦点框部件,用于显示当前焦点部件的焦点框。
  • QFrame:框架部件,用于创建一个矩形框架,可以用作容器或分隔线。
  • QGroupBox:分组框,用于将相关的控件组合在一起。
  • QKeySequenceEdit:键序列编辑框部件,用于接收和编辑键盘快捷键序列。
  • QLineEdit:单行文本输入框,用于接收用户的文本输入。
  • QMacCocoaViewContainer:Mac平台上的Cocoa视图容器,用于在Qt应用程序中嵌入Cocoa视图。
  • QMacNativeWidget:Mac平台上的本地部件,用于在Qt应用程序中嵌入Mac本地窗口。
  • QMainWindow:主窗口部件,通常用作应用程序的主界面。
  • QMdiSubWindow:多文档界面(MDI)中的子窗口。
  • QMenu:菜单部件,用于显示和选择菜单项。
  • QMenuBar:菜单栏部件,用于显示和管理菜单。
  • QOpenGLWidget:OpenGL部件,用于在Qt应用程序中进行OpenGL绘图。
  • QProgressBar:进度条部件,用于显示任务的进度。
  • QQuickWidget:用于在QWidget中嵌入QML界面的部件。它提供了一种将Qt Quick(QML)与传统的QWidget应用程序结合起来的方式。
  • QRubberBand:橡皮筋部件,用于在屏幕上绘制可调整大小的矩形框。
  • QSizeGrip:尺寸调整手柄,用于在窗口的边界上显示可调整大小的手柄。
  • QSplashScreen:启动画面,用于在应用程序启动时显示一个启动画面。
  • QSplitterHandle:分隔器手柄,用于在分隔器控件中显示可调整大小的手柄。
  • QStatusBar:状态栏部件,用于在主窗口底部显示状态信息。
  • QSvgWidget:SVG部件,用于显示可缩放矢量图形(SVG)。
  • QTabBar:选项卡栏部件,用于显示和管理选项卡。
  • QTabWidget:选项卡部件,用于显示多个页面,每个页面对应一个选项卡。
  • QToolBar:工具栏部件,用于显示和管理工具按钮。
  • QWizardPage:向导页面,用于创建多步骤的向导界面。

3.1 QAbstractButton

QAbstractButton 是按钮的抽象基类,提供了按钮的基本功能和特性。根据不同的特性有以下几个子类:

  • QCheckBox:复选框部件,用于表示一个可选的选择状态。
  • QPushButton:按钮部件,用于触发操作或执行特定的功能。

    • QCommandLinkButton:提供了一个带有标题和描述的按钮,通常用于表示一个重要的操作或命令。
  • QRadioButton:单选按钮部件,用于表示一组互斥的选项,只能选择其中一个。
  • QToolButton:工具按钮部件,用于显示和执行特定的工具或操作。

关系图如下:

a29f8144e4fd20529641e047212746d3.svg

其中 QRadioButton可使用QButtonGroup来进行分组。QButtonGroup是Qt框架中的一个类,用于管理一组互斥的按钮,例如QRadioButton。它提供了以下功能:

  • 确保在同一时间只能选择一种选项。
  • 跟踪选中的按钮,并提供方法来获取当前选中的按钮。
  • 允许通过索引或ID来访问按钮。
  • 发出信号来指示按钮的选中状态发生变化。

通过将QRadioButton添加到QButtonGroup中,可以确保在同一组中只能选择一个单选按钮。这意味着,当一个单选按钮被选中时,其他的单选按钮都会自动取消选中状态。
可以使用QButtonGroup的addButton()方法将单选按钮添加到分组中,或使用QButtonGroup的构造函数来创建一个分组,并在创建单选按钮时指定分组。

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QRadioButton>
#include <QPushButton>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget window;
    window.setWindowTitle("QRadioButton Example");

    QVBoxLayout *layout = new QVBoxLayout(&window);

    QRadioButton *radioBtn1 = new QRadioButton("Option 1");
    QRadioButton *radioBtn2 = new QRadioButton("Option 2");
    QRadioButton *radioBtn3 = new QRadioButton("Option 3");

    layout->addWidget(radioBtn1);
    layout->addWidget(radioBtn2);
    layout->addWidget(radioBtn3);

    QButtonGroup *buttonGroup = new QButtonGroup(&window);
    buttonGroup->addButton(radioBtn1);
    buttonGroup->addButton(radioBtn2);
    buttonGroup->addButton(radioBtn3);

    QPushButton *submitBtn = new QPushButton("Submit", &window);
    layout->addWidget(submitBtn);

    QObject::connect(submitBtn, &QPushButton::clicked, [&]() {
        QString selectedOption;
        for (QRadioButton *radioButton : buttonGroup->buttons()) {
            if (radioButton->isChecked()) {
                selectedOption = radioButton->text();
                break;
            }
        }
        qDebug() << "Selected Option: " << selectedOption;
    });

    window.show();

    return app.exec();
}

运行效果如下:

image.png

3.2 QAbstractSlider

QAbstractSlider 是滑动条的抽象基类,提供了滑动条的基本功能和特性。它具有以下主要属性:

  • value:QAbstractSlider 维护的有界整数值。
  • minimum:最小可能值。
  • maximum:最大可能值。
  • singleStep:一个抽象滑块提供的两个自然步长中较小的步长,通常对应用户按下箭头键。
  • pageStep:一个抽象滑块提供的两个自然步长中较大的步长,通常对应用户按下 PageUp 或 PageDown 键。
  • tracking:是否启用滑块跟踪。
  • sliderPosition:滑块的当前位置。如果启用了跟踪(默认情况下),则它与 value 相同。
  • setValue() 允许您将当前值设置为允许范围内的任何整数,而不仅仅是 minimum() + n * singleStep()(其中 n 是整数值)。某些小部件可以允许用户设置任何值;其他小部件可能只提供 singleStep() 或 pageStep() 的倍数。

其具体实现类包含:

72ffd77d99ad8d2f464da3bfbad50d51.svg
  • QDial 是一个圆形的滑块部件。
  • QScrollBar 是一个滚动条部件。
  • QSlider 是一个水平或垂直的滑块部件。

3.3 QAbstractSpinBox

QAbstractSpinBox是抽象基类,用于创建可编辑的数值输入框。这个类的主要属性包括:

  • text:在 QAbstractSpinBox 中显示的文本。
  • alignment:QAbstractSpinBox 中文本的对齐方式。
  • wrapping:QAbstractSpinBox 是否从最小值到最大值循环,反之亦然。

其具体的实现类有三个:

  • QSpinBox 是一个用于输入整数值的部件。它提供了一个可编辑的文本框和一对上下箭头按钮,用于增加或减少当前值。用户可以直接在文本框中输入整数值,也可以使用按钮进行步进操作。
  • QDoubleSpinBox 是一个用于输入浮点数值的部件。它类似于 QSpinBox,但允许用户输入带小数点的数字。用户可以通过文本框或按钮进行数值的增加或减少。
  • QDateTimeEdit 是一个用于输入日期和时间的部件。它提供了一个可编辑的文本框和一个下拉的日历控件,用于选择日期和时间。用户可以直接在文本框中输入日期和时间,也可以通过日历控件进行选择。

5bb8155e65508327b60af9f53435db6f.svg

本文学习了Qt应用的 Application,Window 和 Widget系统,接下来会学习窗口的详细说明以及如何布局.

如果你觉得本文对你有帮忙,可关注我的公众号:【DevWiki】获取更多文章。

WeiXin-DevWiki-Common.jpg

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK