Qt 窗口与对话框 #
窗口类型概览 #
Qt 提供了多种窗口类型,用于构建不同的用户界面:
text
┌─────────────────────────────────────────────────────────────┐
│ Qt 窗口类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ QWidget │
│ ├── 所有窗口和控件的基类 │
│ ├── 可以作为独立窗口使用 │
│ └── 可以作为其他控件的容器 │
│ │
│ QMainWindow │
│ ├── 主窗口类 │
│ ├── 包含菜单栏、工具栏、状态栏 │
│ └── 适合作为应用程序主窗口 │
│ │
│ QDialog │
│ ├── 对话框基类 │
│ ├── 模态或非模态显示 │
│ └── 用于临时交互 │
│ │
└─────────────────────────────────────────────────────────────┘
QMainWindow 主窗口 #
基本结构 #
text
┌─────────────────────────────────────────────────────────────┐
│ 菜单栏 (QMenuBar) │
├─────────────────────────────────────────────────────────────┤
│ 工具栏 (QToolBar) │
├─────────────────────────────────────────────────────────────┤
│ │
│ │
│ 中央控件 (Central Widget) │
│ │
│ │
├─────────────────────────────────────────────────────────────┤
│ 状态栏 (QStatusBar) │
└─────────────────────────────────────────────────────────────┘
│ 停靠窗口 (QDockWidget) │
└─────────────────────────────────────────────────────────────┘
创建主窗口 #
cpp
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void onNewFile();
void onOpenFile();
void onSaveFile();
void onAbout();
private:
void createMenuBar();
void createToolBar();
void createStatusBar();
void createDockWidgets();
QTextEdit *textEdit;
};
#endif // MAINWINDOW_H
cpp
// mainwindow.cpp
#include "mainwindow.h"
#include <QMenu>
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>
#include <QDockWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle("My Application");
resize(800, 600);
// 创建中央控件
textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
createMenuBar();
createToolBar();
createStatusBar();
createDockWidgets();
}
MainWindow::~MainWindow()
{
}
void MainWindow::createMenuBar()
{
// 文件菜单
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
QAction *newAction = fileMenu->addAction(tr("&New"));
newAction->setShortcut(QKeySequence::New);
connect(newAction, &QAction::triggered, this, &MainWindow::onNewFile);
QAction *openAction = fileMenu->addAction(tr("&Open"));
openAction->setShortcut(QKeySequence::Open);
connect(openAction, &QAction::triggered, this, &MainWindow::onOpenFile);
QAction *saveAction = fileMenu->addAction(tr("&Save"));
saveAction->setShortcut(QKeySequence::Save);
connect(saveAction, &QAction::triggered, this, &MainWindow::onSaveFile);
fileMenu->addSeparator();
QAction *exitAction = fileMenu->addAction(tr("E&xit"));
exitAction->setShortcut(QKeySequence::Quit);
connect(exitAction, &QAction::triggered, this, &QWidget::close);
// 帮助菜单
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
QAction *aboutAction = helpMenu->addAction(tr("&About"));
connect(aboutAction, &QAction::triggered, this, &MainWindow::onAbout);
}
void MainWindow::createToolBar()
{
QToolBar *toolbar = addToolBar(tr("Main Toolbar"));
toolbar->addAction(QIcon(":/icons/new.png"), tr("New"));
toolbar->addAction(QIcon(":/icons/open.png"), tr("Open"));
toolbar->addAction(QIcon(":/icons/save.png"), tr("Save"));
toolbar->addSeparator();
toolbar->addAction(QIcon(":/icons/cut.png"), tr("Cut"));
toolbar->addAction(QIcon(":/icons/copy.png"), tr("Copy"));
toolbar->addAction(QIcon(":/icons/paste.png"), tr("Paste"));
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
void MainWindow::createDockWidgets()
{
QDockWidget *dock = new QDockWidget(tr("Explorer"), this);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QWidget *dockContent = new QWidget;
dock->setWidget(dockContent);
addDockWidget(Qt::LeftDockWidgetArea, dock);
}
void MainWindow::onNewFile()
{
textEdit->clear();
statusBar()->showMessage(tr("New file created"));
}
void MainWindow::onOpenFile()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"));
if (!fileName.isEmpty()) {
// 打开文件
statusBar()->showMessage(tr("File opened: %1").arg(fileName));
}
}
void MainWindow::onSaveFile()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"));
if (!fileName.isEmpty()) {
// 保存文件
statusBar()->showMessage(tr("File saved: %1").arg(fileName));
}
}
void MainWindow::onAbout()
{
QMessageBox::about(this, tr("About"), tr("My Application v1.0"));
}
QDialog 对话框 #
模态与非模态 #
cpp
// 模态对话框 - 阻塞父窗口
QDialog dialog(this);
dialog.setWindowTitle("Modal Dialog");
dialog.exec(); // 阻塞直到对话框关闭
// 非模态对话框 - 不阻塞父窗口
QDialog *dialog = new QDialog(this);
dialog->setWindowTitle("Modeless Dialog");
dialog->setAttribute(Qt::WA_DeleteOnClose); // 关闭时自动删除
dialog->show(); // 非阻塞显示
标准对话框 #
cpp
// 消息框
QMessageBox::information(this, "Title", "Information message");
QMessageBox::warning(this, "Title", "Warning message");
QMessageBox::critical(this, "Title", "Critical message");
QMessageBox::question(this, "Title", "Question?");
// 带按钮的消息框
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Confirm", "Are you sure?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
// 用户点击了 Yes
}
// 文件对话框
QString fileName = QFileDialog::getOpenFileName(this, "Open File",
"/home", "Images (*.png *.jpg);;All Files (*)");
QString fileName = QFileDialog::getSaveFileName(this, "Save File",
"/home", "Documents (*.txt)");
QStringList fileNames = QFileDialog::getOpenFileNames(this, "Open Files",
"/home", "Images (*.png *.jpg)");
// 颜色对话框
QColor color = QColorDialog::getColor(Qt::red, this, "Select Color");
// 字体对话框
bool ok;
QFont font = QFontDialog::getFont(&ok, QFont("Arial", 12), this);
if (ok) {
// 用户选择了字体
}
// 输入对话框
QString text = QInputDialog::getText(this, "Input", "Enter name:");
int value = QInputDialog::getInt(this, "Input", "Enter age:", 0, 0, 150);
double dvalue = QInputDialog::getDouble(this, "Input", "Enter value:");
QString item = QInputDialog::getItem(this, "Select", "Choose:",
QStringList() << "A" << "B" << "C", 0, false);
自定义对话框 #
cpp
// customdialog.h
#ifndef CUSTOMDIALOG_H
#define CUSTOMDIALOG_H
#include <QDialog>
#include <QLineEdit>
#include <QSpinBox>
#include <QDialogButtonBox>
class CustomDialog : public QDialog
{
Q_OBJECT
public:
explicit CustomDialog(QWidget *parent = nullptr);
QString getName() const;
int getAge() const;
private:
QLineEdit *nameEdit;
QSpinBox *ageSpinBox;
QDialogButtonBox *buttonBox;
};
#endif // CUSTOMDIALOG_H
cpp
// customdialog.cpp
#include "customdialog.h"
#include <QVBoxLayout>
#include <QFormLayout>
CustomDialog::CustomDialog(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("Custom Dialog");
nameEdit = new QLineEdit;
ageSpinBox = new QSpinBox;
ageSpinBox->setRange(0, 150);
buttonBox = new QDialogButtonBox(
QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QFormLayout *formLayout = new QFormLayout;
formLayout->addRow(tr("Name:"), nameEdit);
formLayout->addRow(tr("Age:"), ageSpinBox);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(formLayout);
mainLayout->addWidget(buttonBox);
}
QString CustomDialog::getName() const
{
return nameEdit->text();
}
int CustomDialog::getAge() const
{
return ageSpinBox->value();
}
cpp
// 使用自定义对话框
CustomDialog dialog(this);
if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getName();
int age = dialog.getAge();
qDebug() << name << age;
}
QWidget 基础窗口 #
作为独立窗口 #
cpp
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("QWidget Window");
window.resize(300, 200);
QVBoxLayout *layout = new QVBoxLayout(&window);
QLabel *label = new QLabel("Hello QWidget!");
layout->addWidget(label);
QPushButton *button = new QPushButton("Click Me");
layout->addWidget(button);
window.show();
return app.exec();
}
窗口属性 #
cpp
QWidget *widget = new QWidget;
// 窗口标题
widget->setWindowTitle("My Window");
// 窗口大小
widget->resize(400, 300);
widget->setMinimumSize(200, 150);
widget->setMaximumSize(800, 600);
widget->setFixedSize(400, 300); // 固定大小
// 窗口位置
widget->move(100, 100);
widget->setGeometry(100, 100, 400, 300); // x, y, width, height
// 窗口状态
widget->show();
widget->hide();
widget->showMaximized();
widget->showMinimized();
widget->showFullScreen();
widget->showNormal();
// 窗口标志
widget->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
// 窗口模态
widget->setWindowModality(Qt::ApplicationModal); // 应用级模态
widget->setWindowModality(Qt::WindowModal); // 窗口级模态
widget->setWindowModality(Qt::NonModal); // 非模态
// 窗口透明度
widget->setWindowOpacity(0.8); // 80% 不透明度
// 窗口图标
widget->setWindowIcon(QIcon(":/icons/app.png"));
窗口标志 #
cpp
// 常用窗口标志
Qt::Window // 普通窗口
Qt::Dialog // 对话框
Qt::Tool // 工具窗口
Qt::SplashScreen // 启动画面
Qt::FramelessWindowHint // 无边框窗口
Qt::WindowStaysOnTopHint // 始终置顶
Qt::WindowMinMaxButtonsHint // 最小化最大化按钮
Qt::WindowCloseButtonHint // 关闭按钮
// 组合使用
widget->setWindowFlags(
Qt::Window |
Qt::WindowTitleHint |
Qt::WindowCloseButtonHint |
Qt::WindowStaysOnTopHint
);
窗口关闭事件 #
cpp
// 重写 closeEvent
void MainWindow::closeEvent(QCloseEvent *event)
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Confirm",
"Are you sure you want to quit?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
// 保存设置等清理工作
event->accept();
} else {
event->ignore();
}
}
多窗口管理 #
cpp
// 主窗口管理多个子窗口
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
void openChildWindow()
{
ChildWindow *child = new ChildWindow(this);
child->setAttribute(Qt::WA_DeleteOnClose);
child->show();
m_childWindows.append(child);
}
private:
QList<QWidget*> m_childWindows;
};
下一步 #
现在你已经掌握了窗口和对话框的使用,接下来学习 基础控件,了解 Qt 提供的各种常用控件!
最后更新:2026-03-29