跳到主要内容

主窗口

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 绘图系统。