QT开发:深入掌握 QtGui 和 QtWidgets 窗口管理:QMainWindow、QDialog 和 QWidget 的高级应用

目录

引言

1. QMainWindow:高级窗口类

基本结构

菜单栏、工具栏和状态栏

菜单栏

工具栏

状态栏

中心部件和可停靠窗口

中心部件

可停靠窗口

示例代码与详解

2. QDialog:对话框窗口类

模态和非模态对话框

模态对话框

非模态对话框

自定义对话框的创建

示例代码与详解

3. QWidget:基础窗口类

基本窗口功能

自定义控件的创建与布局管理

示例代码与详解

4. 综合示例:结合 QMainWindow、QDialog 和 QWidget 开发一个完整的应用程序

主窗口代码

查找对话框代码

综合示例代码

代码解析

主窗口(MainWindow)

槽函数(Slots)

查找对话框(FindDialog)

查找文本功能

完整示例代码

5. 总结

关键要点


引言

        Qt 是一个功能强大的跨平台 C++ 应用程序开发框架,广泛应用于桌面、移动和嵌入式开发。它提供了丰富的功能模块,其中 QtGui 和 QtWidgets 是核心的图形用户界面模块。本篇技术博客将深入讲解 QtGui 和 QtWidgets 模块中窗口管理的关键类:QMainWindowQDialogQWidget,帮助你掌握这些类的基本概念和高级应用技术,旨在让你在学习后能够轻松开发 Qt 应用。

1. QMainWindow:高级窗口类

QMainWindow 是一个高级的窗口类,提供了一个默认的布局,该布局包含一个中心窗口部件和可选的菜单栏、工具栏、状态栏和停靠窗口。这个类是 Qt 应用程序的主窗口的最佳选择。

基本结构

QMainWindow 由以下主要部分组成:

  • 菜单栏 (QMenuBar)
  • 工具栏 (QToolBar)
  • 状态栏 (QStatusBar)
  • 中心部件(Central Widget)
  • 可停靠窗口 (QDockWidget)

菜单栏、工具栏和状态栏

菜单栏

        菜单栏通常位于窗口顶部,用于组织和管理应用程序的菜单项,如下在Qt中使用QMenuBarQMenuQAction类创建一个菜单栏,并添加一个"File"菜单,以及一个"Exit"动作项。

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 创建菜单栏
    QMenuBar *menuBar = new QMenuBar(this);
    setMenuBar(menuBar);

    // 添加"File"菜单
    QMenu *fileMenu = menuBar->addMenu("File");

    // 添加"Exit"动作
    QAction *exitAction = fileMenu->addAction("Exit");
    connect(exitAction, &QAction::triggered, this, &QMainWindow::close);
}


展示如下:

工具栏

工具栏通常包含一组操作按钮,用于快速访问常用功能。

  // 创建工具栏
    QToolBar *toolBar = new QToolBar(this);
    addToolBar(toolBar);

   // 向工具栏添加"Exit"动作
    toolBar->addAction(exitAction);
状态栏

状态栏通常位于窗口底部,用于显示状态信息。

QStatusBar *statusBar = new QStatusBar(this);
setStatusBar(statusBar);
statusBar->showMessage("Ready");

中心部件和可停靠窗口

中心部件

中心部件是 QMainWindow 的核心区域,用于显示主要的应用内容。可以通过 setCentralWidget 方法设置中心部件。

QTextEdit *textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
可停靠窗口

可停靠窗口是 QMainWindow 的可选部分,用户可以将其停靠在主窗口的边缘,也可以浮动。

QDockWidget *dockWidget = new QDockWidget("Dockable", this);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);

QLabel *label = new QLabel("Dockable content", this);
dockWidget->setWidget(label);

示例代码与详解

以下是一个完整的示例,展示了如何使用 QMainWindow 创建一个带有菜单栏、工具栏、状态栏、中心部件和可停靠窗口的主窗口:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QLabel>
#include <QAction>
#include <QDockWidget>
#include <QTextEdit>

class MainWindow : public QMainWindow {
public:
    MainWindow() {
        // 设置中心部件
        QTextEdit *textEdit = new QTextEdit(this);
        setCentralWidget(textEdit);

        // 创建菜单栏
        QMenuBar *menuBar = new QMenuBar(this);
        setMenuBar(menuBar);

        // 添加菜单项和动作
        QMenu *fileMenu = menuBar->addMenu("File");
        QAction *exitAction = fileMenu->addAction("Exit");
        connect(exitAction, &QAction::triggered, this, &QMainWindow::close);

        // 创建工具栏
        QToolBar *toolBar = new QToolBar(this);
        addToolBar(toolBar);
        toolBar->addAction(exitAction);

        // 创建状态栏
        QStatusBar *statusBar = new QStatusBar(this);
        setStatusBar(statusBar);
        statusBar->showMessage("Ready");

        // 创建可停靠窗口
        QDockWidget *dockWidget = new QDockWidget("Dockable", this);
        addDockWidget(Qt::LeftDockWidgetArea, dockWidget);

        QLabel *label = new QLabel("Dockable content", this);
        dockWidget->setWidget(label);
    }
};

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

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

这个示例展示了如何使用 QMainWindow 及其主要组件来创建一个功能齐全的主窗口。

2. QDialog:对话框窗口类

QDialog 是一个用于对话框窗口的基类。对话框可以是模态的(阻塞所有其他窗口)或非模态的(不阻塞其他窗口)。常用于提示信息、用户输入等场景。

模态和非模态对话框

模态对话框

模态对话框在显示期间会阻塞所有其他窗口,用户必须与之交互才能继续使用应用程序。可以通过 exec() 方法执行模态对话框。

CustomDialog dialog;
if (dialog.exec() == QDialog::Accepted) {
    qDebug() << "Dialog accepted";
}
非模态对话框

非模态对话框不会阻塞其他窗口,用户可以自由切换到其他窗口。可以通过 show() 方法显示非模态对话框。

CustomDialog *dialog = new CustomDialog(this);
dialog->show();

自定义对话框的创建

创建自定义对话框通常涉及添加控件(如标签、按钮)并使用布局管理器组织这些控件。

示例代码与详解

以下是一个完整的示例,展示了如何创建一个自定义模态对话框:

#include <QApplication>
#include <QDialog>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>

class CustomDialog : public QDialog {
public:
    CustomDialog(QWidget *parent = nullptr) : QDialog(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);

        QLabel *label = new QLabel("This is a custom dialog", this);
        layout->addWidget(label);

        QPushButton *okButton = new QPushButton("OK", this);
        layout->addWidget(okButton);

        connect(okButton, &QPushButton::clicked, this, &QDialog::accept);
    }
};

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

    CustomDialog dialog;
    if (dialog.exec() == QDialog::Accepted) {
        qDebug() << "Dialog accepted";
    }

    return app.exec();
}

这个示例展示了如何创建一个简单的模态对话框,包括一个标签和一个按钮。当用户点击按钮时,对话框关闭并返回 Accepted 状态。

3. QWidget:基础窗口类

QWidget 是所有用户界面对象的基类。所有窗口和控件都是 QWidget 的子类。可以直接使用 QWidget 创建自定义窗口或控件。

基本窗口功能

QWidget 提供了基本的窗口功能,如设置大小、标题、布局管理等。

QWidget *widget = new QWidget();
widget->resize(400, 300);
widget->setWindowTitle("Custom Widget");

自定义控件的创建与布局管理

自定义控件通常是通过继承 QWidget 并重写其绘制和事件处理方法来实现的。布局管理器用于组织控件的布局。

示例代码与详解

以下是一个完整的示例,展示了如何创建一个自定义窗口,包括标签和按钮,并使用布局管理器管理它们的布局:

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>

class CustomWidget : public QWidget {
public:
    CustomWidget(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);

        QLabel *label = new QLabel("This is a custom widget", this);
        layout->addWidget(label);

        QPushButton *button = new QPushButton("Click me", this);
        layout->addWidget(button);

        connect(button, &QPushButton::clicked, this, &CustomWidget::onButtonClicked);
    }

private slots:
    void onButtonClicked() {
        qDebug() << "Button clicked";
    }
};

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

    CustomWidget widget;
    widget.show();

    return app.exec();
}

这个示例展示了如何使用 QWidget 创建一个自定义窗口,并通过布局管理器组织控件的布局。

4. 综合示例:结合 QMainWindow、QDialog 和 QWidget 开发一个完整的应用程序

为了更好地展示 QMainWindowQDialogQWidget 的综合应用,我们将开发一个简单的文本编辑器应用程序。这个应用程序包含以下功能:

  • 主窗口(QMainWindow)带有菜单栏、工具栏和状态栏。
  • 文件打开和保存功能。
  • 查找对话框(QDialog)。
  • 自定义控件(QWidget)显示文本统计信息。

主窗口代码

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>
#include <QDockWidget>
#include <QLabel>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow() {
        // 设置中心部件
        textEdit = new QTextEdit(this);
        setCentralWidget(textEdit);

        // 创建菜单栏
        QMenuBar *menuBar = new QMenuBar(this);
        setMenuBar(menuBar);

        // 添加文件菜单和动作
        QMenu *fileMenu = menuBar->addMenu("File");
        QAction *openAction = fileMenu->addAction("Open");
        QAction *saveAction = fileMenu->addAction("Save");
        QAction *exitAction = fileMenu->addAction("Exit");
        connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
        connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
        connect(exitAction, &QAction::triggered, this, &QMainWindow::close);

        // 创建工具栏
        QToolBar *toolBar = new QToolBar(this);
        addToolBar(toolBar);
        toolBar->addAction(openAction);
        toolBar->addAction(saveAction);

        // 创建状态栏
        QStatusBar *statusBar = new QStatusBar(this);
        setStatusBar(statusBar);
        statusBar->showMessage("Ready");

        // 创建可停靠窗口
        QDockWidget *dockWidget = new QDockWidget("Statistics", this);
        addDockWidget(Qt::RightDockWidgetArea, dockWidget);

        statsLabel = new QLabel(this);
        dockWidget->setWidget(statsLabel);

        // 更新统计信息
        connect(textEdit, &QTextEdit::textChanged, this, &MainWindow::updateStats);
    }

private slots:
    void openFile() {
        QString fileName = QFileDialog::getOpenFileName(this, "Open File");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
                textEdit->setPlainText(file.readAll());
                statusBar()->showMessage("File opened", 2000);
            } else {
                QMessageBox::warning(this, "Error", "Cannot open file");
            }
        }
    }

    void saveFile() {
        QString fileName = QFileDialog::getSaveFileName(this, "Save File");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                file.write(textEdit->toPlainText().toUtf8());
                statusBar()->showMessage("File saved", 2000);
            } else {
                QMessageBox::warning(this, "Error", "Cannot save file");
            }
        }
    }

    void updateStats() {
        int wordCount = textEdit->toPlainText().split(QRegExp("\\s+"), QString::SkipEmptyParts).count();
        int charCount = textEdit->toPlainText().length();
        statsLabel->setText(QString("Words: %1\nCharacters: %2").arg(wordCount).arg(charCount));
    }

private:
    QTextEdit *textEdit;
    QLabel *statsLabel;
};

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

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

查找对话框代码

#include <QApplication>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QMessageBox>

class FindDialog : public QDialog {
    Q_OBJECT

public:
    FindDialog(QTextEdit *editor, QWidget *parent = nullptr) : QDialog(parent), textEdit(editor) {
        QVBoxLayout *mainLayout = new QVBoxLayout(this);

        QHBoxLayout *findLayout = new QHBoxLayout();
        findLayout->addWidget(new QLabel("Find:", this));
        findLineEdit = new QLineEdit(this);
        findLayout->addWidget(findLineEdit);
        mainLayout->addLayout(findLayout);

        QPushButton *findButton = new QPushButton("Find", this);
        mainLayout->addWidget(findButton);
        connect(findButton, &QPushButton::clicked, this, &FindDialog::findText);

        setWindowTitle("Find");
    }

private slots:
    void findText() {
        QString textToFind = findLineEdit->text();
        if (!textEdit->find(textToFind)) {
            QMessageBox::information(this, "Find", "No more occurrences found.");
        }
    }

private:
    QTextEdit *textEdit;
    QLineEdit *findLineEdit;
};

综合示例代码

以下是完整的应用程序代码,结合了 QMainWindowQDialogQWidget 的所有功能:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>
#include <QDockWidget>
#include <QLabel>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>

class FindDialog : public QDialog {
    Q_OBJECT

public:
    FindDialog(QTextEdit *editor, QWidget *parent = nullptr) : QDialog(parent), textEdit(editor) {
        QVBoxLayout *mainLayout = new QVBoxLayout(this);

        QHBoxLayout *findLayout = new QHBoxLayout();
        findLayout->addWidget(new QLabel("Find:", this));
        findLineEdit = new QLineEdit(this);
        findLayout->addWidget(findLineEdit);
        mainLayout->addLayout(findLayout);

        QPushButton *findButton = new QPushButton("Find", this);
        mainLayout->addWidget(findButton);
        connect(findButton, &QPushButton::clicked, this, &FindDialog::findText);

        setWindowTitle("Find");
    }

private slots:
    void findText() {
        QString textToFind = findLineEdit->text();
        if (!textEdit->find(textToFind)) {
            QMessageBox::information(this, "Find", "No more occurrences found.");
        }
    }

private:
    QTextEdit *textEdit;
    QLineEdit *findLineEdit;
};

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow() {
        // 设置中心部件
        textEdit = new QTextEdit(this);
        setCentralWidget(textEdit);

        // 创建菜单栏
        QMenuBar *menuBar = new QMenuBar(this);
        setMenuBar(menuBar);

        // 添加文件菜单和动作
        QMenu *fileMenu = menuBar->addMenu("File");
        QAction *openAction = fileMenu->addAction("Open");
        QAction *saveAction = fileMenu->addAction("Save");
        QAction *exitAction = fileMenu->addAction("Exit");
        connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
        connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
        connect(exitAction, &QAction::triggered, this, &QMainWindow::close);

        // 添加编辑菜单和查找动作
        QMenu *editMenu = menuBar->addMenu("Edit");
        QAction *findAction = editMenu->addAction("Find");
        connect(findAction, &QAction::triggered, this, &MainWindow::showFindDialog);

        // 创建工具栏
        QToolBar *toolBar = new QToolBar(this);
        addToolBar(toolBar);
        toolBar->addAction(openAction);
        toolBar->addAction(saveAction);
        toolBar->addAction(findAction);

        // 创建状态栏
        QStatusBar *statusBar = new QStatusBar(this);
        setStatusBar(statusBar);
         statusBar->showMessage("Ready");

        // 创建可停靠窗口
        QDockWidget *dockWidget = new QDockWidget("Statistics", this);
        addDockWidget(Qt::RightDockWidgetArea, dockWidget);

        statsLabel = new QLabel(this);
        dockWidget->setWidget(statsLabel);

        // 更新统计信息
        connect(textEdit, &QTextEdit::textChanged, this, &MainWindow::updateStats);
    }

private slots:
    void openFile() {
        QString fileName = QFileDialog::getOpenFileName(this, "Open File");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
                textEdit->setPlainText(file.readAll());
                statusBar()->showMessage("File opened", 2000);
                updateStats();
            } else {
                QMessageBox::warning(this, "Error", "Cannot open file");
            }
        }
    }

    void saveFile() {
        QString fileName = QFileDialog::getSaveFileName(this, "Save File");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                file.write(textEdit->toPlainText().toUtf8());
                statusBar()->showMessage("File saved", 2000);
            } else {
                QMessageBox::warning(this, "Error", "Cannot save file");
            }
        }
    }

    void showFindDialog() {
        FindDialog dialog(textEdit, this);
        dialog.exec();
    }

    void updateStats() {
        int wordCount = textEdit->toPlainText().split(QRegExp("\\s+"), QString::SkipEmptyParts).count();
        int charCount = textEdit->toPlainText().length();
        statsLabel->setText(QString("Words: %1\nCharacters: %2").arg(wordCount).arg(charCount));
    }

private:
    QTextEdit *textEdit;
    QLabel *statsLabel;
};

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

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

代码解析

这个综合示例展示了如何结合使用 QMainWindowQDialogQWidget 来开发一个功能齐全的文本编辑器应用程序。以下是对各个部分的详细解析:

主窗口(MainWindow)
  • QMainWindow 初始化:在构造函数中,我们初始化了 QMainWindow 的各个组件,包括菜单栏、工具栏、状态栏、中心部件和可停靠窗口。
  • 菜单栏:创建了一个菜单栏,并添加了文件菜单和编辑菜单。文件菜单包含打开、保存和退出动作;编辑菜单包含查找动作。
  • 工具栏:创建了一个工具栏,并添加了打开、保存和查找动作。工具栏可以快速访问常用功能。
  • 状态栏:创建了一个状态栏,并在状态栏上显示初始消息“Ready”。
  • 中心部件:设置了一个 QTextEdit 作为中心部件,用于显示和编辑文本内容。
  • 可停靠窗口:创建了一个 QDockWidget 作为可停靠窗口,用于显示文本统计信息(字数和字符数)。
  • 信号槽连接:通过信号槽连接机制,关联了各种用户操作(如打开文件、保存文件、查找文本)和相应的槽函数。
槽函数(Slots)
  • openFile:打开文件对话框,让用户选择要打开的文件,并将文件内容读取到 QTextEdit 中。
  • saveFile:保存文件对话框,让用户选择保存文件的位置,并将 QTextEdit 中的内容写入文件。
  • showFindDialog:显示查找对话框(FindDialog),让用户输入要查找的文本。
  • updateStats:更新文本统计信息,包括字数和字符数,并显示在可停靠窗口的标签中。
查找对话框(FindDialog)
  • QDialog 初始化:在构造函数中,我们初始化了 QDialog 的各个组件,包括标签、文本输入框和查找按钮。
  • 布局管理:使用垂直布局和水平布局组合,组织对话框中的控件。
  • 信号槽连接:通过信号槽连接机制,关联查找按钮的点击操作和 findText 槽函数。
查找文本功能
  • findText:获取用户输入的查找文本,并在 QTextEdit 中查找。如果查找到文本,将其选中并滚动到可视区域;如果未找到更多匹配项,显示提示信息。

完整示例代码

以下是完整的应用程序代码,包括主窗口、查找对话框和所有功能的实现:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>
#include <QDockWidget>
#include <QLabel>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QRegExp>

class FindDialog : public QDialog {
    Q_OBJECT

public:
    FindDialog(QTextEdit *editor, QWidget *parent = nullptr) : QDialog(parent), textEdit(editor) {
        QVBoxLayout *mainLayout = new QVBoxLayout(this);

        QHBoxLayout *findLayout = new QHBoxLayout();
        findLayout->addWidget(new QLabel("Find:", this));
        findLineEdit = new QLineEdit(this);
        findLayout->addWidget(findLineEdit);
        mainLayout->addLayout(findLayout);

        QPushButton *findButton = new QPushButton("Find", this);
        mainLayout->addWidget(findButton);
        connect(findButton, &QPushButton::clicked, this, &FindDialog::findText);

        setWindowTitle("Find");
    }

private slots:
    void findText() {
        QString textToFind = findLineEdit->text();
        if (!textEdit->find(textToFind)) {
            QMessageBox::information(this, "Find", "No more occurrences found.");
        }
    }

private:
    QTextEdit *textEdit;
    QLineEdit *findLineEdit;
};

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow() {
        // 设置中心部件
        textEdit = new QTextEdit(this);
        setCentralWidget(textEdit);

        // 创建菜单栏
        QMenuBar *menuBar = new QMenuBar(this);
        setMenuBar(menuBar);

        // 添加文件菜单和动作
        QMenu *fileMenu = menuBar->addMenu("File");
        QAction *openAction = fileMenu->addAction("Open");
        QAction *saveAction = fileMenu->addAction("Save");
        QAction *exitAction = fileMenu->addAction("Exit");
        connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
        connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
        connect(exitAction, &QAction::triggered, this, &QMainWindow::close);

        // 添加编辑菜单和查找动作
        QMenu *editMenu = menuBar->addMenu("Edit");
        QAction *findAction = editMenu->addAction("Find");
        connect(findAction, &QAction::triggered, this, &MainWindow::showFindDialog);

        // 创建工具栏
        QToolBar *toolBar = new QToolBar(this);
        addToolBar(toolBar);
        toolBar->addAction(openAction);
        toolBar->addAction(saveAction);
        toolBar->addAction(findAction);

        // 创建状态栏
        QStatusBar *statusBar = new QStatusBar(this);
        setStatusBar(statusBar);
        statusBar->showMessage("Ready");

        // 创建可停靠窗口
        QDockWidget *dockWidget = new QDockWidget("Statistics", this);
        addDockWidget(Qt::RightDockWidgetArea, dockWidget);

        statsLabel = new QLabel(this);
        dockWidget->setWidget(statsLabel);

        // 更新统计信息
        connect(textEdit, &QTextEdit::textChanged, this, &MainWindow::updateStats);
    }

private slots:
    void openFile() {
        QString fileName = QFileDialog::getOpenFileName(this, "Open File");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
                textEdit->setPlainText(file.readAll());
                statusBar()->showMessage("File opened", 2000);
                updateStats();
            } else {
                QMessageBox::warning(this, "Error", "Cannot open file");
            }
        }
    }

    void saveFile() {
        QString fileName = QFileDialog::getSaveFileName(this, "Save File");
        if (!fileName.isEmpty()) {
            QFile file(fileName);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                file.write(textEdit->toPlainText().toUtf8());
                statusBar()->showMessage("File saved", 2000);
            } else {
                QMessageBox::warning(this, "Error", "Cannot save file");
            }
        }
    }

    void showFindDialog() {
        FindDialog dialog(textEdit, this);
        dialog.exec();
    }

    void updateStats() {
        int wordCount = textEdit->toPlainText().split(QRegExp("\\s+"), QString::SkipEmptyParts).count();
        int charCount = textEdit->toPlainText().length();
        statsLabel->setText(QString("Words: %1\nCharacters: %2").arg(wordCount).arg(charCount));
    }

private:
    QTextEdit *textEdit;
    QLabel *statsLabel;
};

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

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

通过这个完整的示例代码,我们展示了如何结合使用 QMainWindowQDialogQWidget 来开发一个功能齐全的文本编辑器应用程序。希望这个示例能够帮助你更好地理解 Qt 的窗口管理和控件使用技巧。

5. 总结

本篇技术博客详细介绍了 QtGui 和 QtWidgets 模块中 QMainWindowQDialogQWidget 的基本概念和高级应用技术。通过详细解析和完整的示例代码,我们展示了如何创建功能齐全的主窗口、模态和非模态对话框,以及自定义控件。希望这篇文章能够帮助你在学习后轻松掌握 Qt 的窗口管理技术,并应用于实际开发中。

关键要点

  • QMainWindow:提供了菜单栏、工具栏、状态栏、中心部件和可停靠窗口的支持,是主窗口的最佳选择。
  • QDialog:用于创建模态和非模态对话框,常用于提示信息和用户输入。
  • QWidget:所有用户界面对象的基类,可以用于创建自定义窗口和控件。
  • 综合应用:通过结合使用 QMainWindowQDialog 和 QWidget,可以开发出功能丰富且用户友好的应用程序。

通过掌握这些关键类和技术,你可以轻松开发复杂的 Qt 应用程序,并自信地应对各种用户界面需求。希望这篇文章对你的 Qt 开发之旅有所帮助!zhanshizhan'shi

猜你喜欢

转载自blog.csdn.net/martian665/article/details/142497311