主窗口
QMainWindow 是 Qt 中用于创建主应用程序窗口的类,提供了完整的应用程序框架。
QMainWindow 结构
┌─────────────────────────────────────┐
│ 菜单栏 (Menu Bar) │
├─────────────────────────────────────┤
│ 工具栏 (Tool Bar) │
├─────────────────────────────────────┤
│ │
│ 中央部件 (Central Widget) │
│ │
├─────────────────────────────────────┤
│ 停靠窗口 (Dock Widgets) │
├─────────────────────────────────────┤
│ 状态栏 (Status Bar) │
└─────────────────────────────────────┘
基本结构
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private:
void createMenus();
void createToolBars();
void createStatusBar();
QTextEdit *textEdit;
};
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
setWindowTitle("主窗口示例");
resize(800, 600);
// 设置中央部件
textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
createMenus();
createToolBars();
createStatusBar();
}
菜单栏
void MainWindow::createMenus()
{
// 文件菜单
QMenu *fileMenu = menuBar()->addMenu("文件(&F)");
QAction *newAction = fileMenu->addAction("新建", this, &MainWindow::newFile);
newAction->setShortcut(QKeySequence::New);
newAction->setIcon(QIcon(":/icons/new.png"));
newAction->setStatusTip("创建新文件");
QAction *openAction = fileMenu->addAction("打开...", this, &MainWindow::openFile);
openAction->setShortcut(QKeySequence::Open);
fileMenu->addSeparator();
QAction *saveAction = fileMenu->addAction("保存", this, &MainWindow::saveFile);
saveAction->setShortcut(QKeySequence::Save);
QAction *saveAsAction = fileMenu->addAction("另存为...", this, &MainWindow::saveAs);
fileMenu->addSeparator();
QAction *exitAction = fileMenu->addAction("退出", this, &QWidget::close);
exitAction->setShortcut(QKeySequence::Quit);
// 编辑菜单
QMenu *editMenu = menuBar()->addMenu("编辑(&E)");
QAction *cutAction = editMenu->addAction("剪切", textEdit, &QTextEdit::cut);
cutAction->setShortcut(QKeySequence::Cut);
QAction *copyAction = editMenu->addAction("复制", textEdit, &QTextEdit::copy);
copyAction->setShortcut(QKeySequence::Copy);
QAction *pasteAction = editMenu->addAction("粘贴", textEdit, &QTextEdit::paste);
pasteAction->setShortcut(QKeySequence::Paste);
// 帮助菜单
QMenu *helpMenu = menuBar()->addMenu("帮助(&H)");
helpMenu->addAction("关于", this, &MainWindow::about);
}
工具栏
void MainWindow::createToolBars()
{
QToolBar *fileToolBar = addToolBar("文件");
QAction *newAction = fileToolBar->addAction(
QIcon(":/icons/new.png"),
"新建",
this,
&MainWindow::newFile
);
QAction *openAction = fileToolBar->addAction(
QIcon(":/icons/open.png"),
"打开",
this,
&MainWindow::openFile
);
QAction *saveAction = fileToolBar->addAction(
QIcon(":/icons/save.png"),
"保存",
this,
&MainWindow::saveFile
);
fileToolBar->addSeparator();
// 添加其他控件到工具栏
QComboBox *zoomCombo = new QComboBox();
zoomCombo->addItems({"50%", "75%", "100%", "125%", "150%", "200%"});
zoomCombo->setCurrentText("100%");
fileToolBar->addWidget(zoomCombo);
// 设置工具栏属性
fileToolBar->setMovable(true);
fileToolBar->setFloatable(true);
fileToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::LeftToolBarArea);
}
状态栏
void MainWindow::createStatusBar()
{
// 显示临时消息
statusBar()->showMessage("就绪", 3000); // 显示3秒
// 添加永久部件
QLabel *rowLabel = new QLabel("行: 1");
QLabel *colLabel = new QLabel("列: 1");
QLabel *encodingLabel = new QLabel("UTF-8");
statusBar()->addPermanentWidget(rowLabel);
statusBar()->addPermanentWidget(colLabel);
statusBar()->addPermanentWidget(encodingLabel);
// 进度条
QProgressBar *progressBar = new QProgressBar();
progressBar->setMaximumWidth(150);
progressBar->setMaximumHeight(16);
statusBar()->addPermanentWidget(progressBar);
}
停靠窗口
void MainWindow::createDockWindows()
{
// 文件浏览器停靠窗口
QDockWidget *dock1 = new QDockWidget("文件浏览器", this);
QTreeWidget *fileTree = new QTreeWidget();
fileTree->setHeaderLabel("文件");
dock1->setWidget(fileTree);
addDockWidget(Qt::LeftDockWidgetArea, dock1);
// 属性面板停靠窗口
QDockWidget *dock2 = new QDockWidget("属性", this);
QTableWidget *propTable = new QTableWidget(5, 2);
propTable->setHorizontalHeaderLabels({"属性", "值"});
dock2->setWidget(propTable);
addDockWidget(Qt::RightDockWidgetArea, dock2);
// 输出面板停靠窗口
QDockWidget *dock3 = new QDockWidget("输出", this);
QTextEdit *outputEdit = new QTextEdit();
outputEdit->setReadOnly(true);
dock3->setWidget(outputEdit);
addDockWidget(Qt::BottomDockWidgetArea, dock3);
// 视图菜单控制停靠窗口显示
viewMenu->addAction(dock1->toggleViewAction());
viewMenu->addAction(dock2->toggleViewAction());
viewMenu->addAction(dock3->toggleViewAction());
}
完整示例
#include <QMainWindow>
#include <QTextEdit>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QDockWidget>
#include <QTreeWidget>
#include <QFileDialog>
#include <QMessageBox>
#include <QCloseEvent>
class TextEditor : public QMainWindow
{
Q_OBJECT
public:
TextEditor(QWidget *parent = nullptr);
protected:
void closeEvent(QCloseEvent *event) override;
private slots:
void newFile();
void open();
bool save();
bool saveAs();
void about();
void documentWasModified();
private:
void createActions();
void createMenus();
void createToolBars();
void createStatusBar();
void readSettings();
void writeSettings();
bool maybeSave();
void loadFile(const QString &fileName);
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
QTextEdit *textEdit;
QString curFile;
QMenu *fileMenu;
QMenu *editMenu;
QMenu *helpMenu;
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAct;
QAction *openAct;
QAction *saveAct;
QAction *saveAsAct;
QAction *exitAct;
QAction *cutAct;
QAction *copyAct;
QAction *pasteAct;
QAction *aboutAct;
QAction *aboutQtAct;
};
TextEditor::TextEditor(QWidget *parent)
: QMainWindow(parent)
{
textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
setWindowTitle("文本编辑器");
setUnifiedTitleAndToolBarOnMac(true);
}
void TextEditor::createActions()
{
newAct = new QAction(QIcon(":/images/new.png"), tr("新建"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("创建新文件"));
connect(newAct, &QAction::triggered, this, &TextEditor::newFile);
openAct = new QAction(QIcon(":/images/open.png"), tr("打开..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("打开文件"));
connect(openAct, &QAction::triggered, this, &TextEditor::open);
saveAct = new QAction(QIcon(":/images/save.png"), tr("保存"), this);
saveAct->setShortcuts(QKeySequence::Save);
saveAct->setStatusTip(tr("保存文件"));
connect(saveAct, &QAction::triggered, this, &TextEditor::save);
saveAsAct = new QAction(tr("另存为..."), this);
saveAsAct->setShortcuts(QKeySequence::SaveAs);
saveAsAct->setStatusTip(tr("以新名称保存文件"));
connect(saveAsAct, &QAction::triggered, this, &TextEditor::saveAs);
exitAct = new QAction(tr("退出"), this);
exitAct->setShortcuts(QKeySequence::Quit);
exitAct->setStatusTip(tr("退出应用程序"));
connect(exitAct, &QAction::triggered, this, &QWidget::close);
cutAct = new QAction(QIcon(":/images/cut.png"), tr("剪切"), this);
cutAct->setShortcuts(QKeySequence::Cut);
cutAct->setStatusTip(tr("剪切选中内容"));
connect(cutAct, &QAction::triggered, textEdit, &QTextEdit::cut);
copyAct = new QAction(QIcon(":/images/copy.png"), tr("复制"), this);
copyAct->setShortcuts(QKeySequence::Copy);
copyAct->setStatusTip(tr("复制选中内容"));
connect(copyAct, &QAction::triggered, textEdit, &QTextEdit::copy);
pasteAct = new QAction(QIcon(":/images/paste.png"), tr("粘贴"), this);
pasteAct->setShortcuts(QKeySequence::Paste);
pasteAct->setStatusTip(tr("粘贴剪贴板内容"));
connect(pasteAct, &QAction::triggered, textEdit, &QTextEdit::paste);
aboutAct = new QAction(tr("关于"), this);
aboutAct->setStatusTip(tr("显示应用程序信息"));
connect(aboutAct, &QAction::triggered, this, &TextEditor::about);
aboutQtAct = new QAction(tr("关于 Qt"), this);
aboutQtAct->setStatusTip(tr("显示 Qt 信息"));
connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt);
}
void TextEditor::createMenus()
{
fileMenu = menuBar()->addMenu(tr("文件(&F)"));
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("编辑(&E)"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("帮助(&H)"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
}
void TextEditor::createToolBars()
{
fileToolBar = addToolBar(tr("文件"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr("编辑"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
}
void TextEditor::createStatusBar()
{
statusBar()->showMessage(tr("就绪"));
}
下一步
继续学习绘图与图形,掌握 Qt 的 2D 绘图系统。