深入Qt–QMainWindow
从这篇开始对Qt基本控件、基本类库进行深入讲解,并在最后提供一个例子。
QMainWindow简介
QMainWindow类提供了一个主应用程序窗口。 主窗口为构建应用程序的用户界面提供了一个框架。Qt有用于主窗口管理的QMainWindow及其相关类。QMainWindow有自己的布局,你可以在其中添加QToolBars、QDockWidgets、QMenuBar和QStatusBar。布局有一个中心区域,可以被任何类型的小部件占用。基本布局如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0kcMV0O-1628129260763)(E:\csdn\深入Qt\QMainWindo
w.jpg)]
MainWindow的结构分为五个部分:菜单栏(Menu Bar)、工具栏(Toolbars)、停靠窗口(Dock Widgets)、状态栏(Status Bar)和中央窗口(Central Widget)。
1.菜单栏(Menu Bar)
菜单是QMenu对象,然后将多个QMenu对象放置在一个QMenuBar(菜单栏)对象中。对于每个菜单,我们再为其添置动作列表,即QAction对象。 菜单栏是MainWindow中已经有的,需要是就使用menuBar()函数来返回 。
这是本人之前写串口项目时使用到菜单栏。如果需要代码需在评论区提要求,当数量达到10以上,博主就会通过其他途径提供。
/******************* 菜单栏 ***********************/
QMenu *fileMenu = ui->menuBar->addMenu(tr("文件(F)"));
QMenu *serialMenu = ui->menuBar->addMenu(tr("串口(E)"));
QMenu *waveMenu = ui->menuBar->addMenu(tr("波形(B)"));
QMenu *moduleMenu = ui->menuBar->addMenu(tr("模块(M)"));
QMenu *helpMenu = ui->menuBar->addMenu(tr("帮助(H)"));
/******************* 文件 ***********************/
QAction *exportAction = fileMenu->addAction("导出");
connect(exportAction, SIGNAL(triggered()), this, SLOT(onExportTriggered()));
fileMenu->addSeparator();//添加分隔符
QAction *reloadAction = fileMenu->addAction("加载");
connect(reloadAction, SIGNAL(triggered()), this, SLOT(onReloadTriggered()));
/******************* 串口 ***********************/
QAction *serialAction = serialMenu->addAction("配置");
connect(serialAction, &QAction::triggered, this, [=](){
MaskForm maskForm;
XSerialDialog *dlg = new XSerialDialog(XSerialDialog::OTHER, &maskForm, Qt::Dialog | Qt::Popup);
dlg->setMinimumSize(200, 100);
maskForm.installWidget(dlg);
dlg->exec();
if(dlg)delete dlg;
});
QAction *watchAction = serialMenu->addAction("监视");
connect(watchAction, &QAction::triggered, this, [=](){
if(m_WatchWid == nullptr)
{
m_WatchWid = new WatchWidget();
}
m_WatchWid->init();
m_WatchWid->show();
});
/******************* 波形 ***********************/
QAction *resetAction = waveMenu->addAction("复位");
connect(resetAction, SIGNAL(triggered()), this, SLOT(onResetTriggered()));
waveMenu->addSeparator();//添加分隔符
QAction *stopAction = waveMenu->addAction("停止");
connect(stopAction, &QAction::triggered, this, [=](){
if(m_TestId != -1)
{
killTimer(m_TestId);
m_TestId = -1;
stopAction->setText("启动");
}
else
{
m_TestId = startTimer(5);
stopAction->setText("停止");
}
});
waveMenu->addSeparator();//添加分隔符
QAction *zoomoutAction = waveMenu->addAction("放大");
connect(zoomoutAction, &QAction::triggered, this, [=](){
if(m_Chart)
{
m_Chart->zoomIn();
}
});
waveMenu->addSeparator();//添加分隔符
QAction *zoominAction = waveMenu->addAction("缩小");
connect(zoominAction, &QAction::triggered, this, [=](){
if(m_Chart)
{
m_Chart->zoomOut();
}
});
waveMenu->addSeparator();//添加分隔符
QAction *zeroAction = waveMenu->addAction("最大");
connect(zeroAction, &QAction::triggered, this, [=](){
if(m_Chart)
{
auto xAxis = m_Chart->axes(Qt::Horizontal);
QAbstractAxis* pAxis = xAxis.back();
pAxis->setRange(0, m_XCount);
auto yAxis = m_Chart->axes(Qt::Vertical);
yAxis.back()->setRange(0, 300);
}
});
/******************* 模块 ***********************/
QAction *xxxAction = moduleMenu->addAction("xxx");
connect(xxxAction, &QAction::triggered, this, [=](){
});
moduleMenu->addSeparator();//添加分隔符
/******************* 帮助 ***********************/
QAction *aboutAction = helpMenu->addAction("关于");
connect(aboutAction, SIGNAL(triggered()), this, SLOT(onAboutTriggered()));
2.工具栏(Toolbars)
在QMainWindow类中有addToolBar()函数来添加工具栏,然后根据QToolBar类中的addAction()函数来为新建的工具栏添加动作。 工具栏需要自己新建,然后在通过addToolBar()函数添加到窗口中。
主窗口的工具栏上可以有多个工具条,通常采用一个菜单对应一个工具条的的方式,也可根据需要进行工具条的划分。
-
直接调用QMainWindow类的addToolBar()函数获取主窗口的工具条对象,每增加一个工具条都需要调用一次该函数。
-
插入属于工具条的动作,即在工具条上添加操作。通过QToolBar类的addAction函数添加。
-
工具条是一个可移动的窗口,它的停靠区域由QToolBar的allowAreas决定,包括:
-
Qt::LeftToolBarArea 停靠在左侧;
-
Qt::RightToolBarArea 停靠在右侧;
-
Qt::TopToolBarArea 停靠在顶部;
-
Qt::BottomToolBarArea 停靠在底部;
-
Qt::AllToolBarAreas 以上四个位置都可停靠。
使用setAllowedAreas()函数指定停靠区域:setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
使用setMoveable()函数设定工具栏的可移动性:setMoveable(false)//工具条不可移动, 只能停靠在初始化的位置上
-
//初始化动作
QAction* newAction = new QAction(tr("new"),this);
//创建一个工具栏
QToolBar toolBar = new QToolBar;
//添加工具栏到顶层窗口中
toolBar = addToolBar(tr("ToolBar"));
//为新建的工具栏添加动作
toolBar ->addAction(openAction);
3.停靠窗口(Dock Widgets)
停靠窗口对应类为QDockWidget ,关于停靠窗口,现在我们所见的许多软件都存在停靠窗口,如Visual Studio软件的类视图、属性视图和资源视图都是停靠窗口的实际案例。停靠窗口作为主窗口的一部分,可以停靠、浮动、显示隐藏等 。QDockWidget 继承于QWidget,使用时跟QWidget相差不大。
//创建QDockWidget对象
QDockWidget* DockWidget = new QDockWidget;
//设置可停靠区域
DockWidget ->setAllowedAreas(Qt::AllDockWidgetAreas);
//设置QDockWidget对象内部部件
DockWidget->setWidget(xxx);
//主窗口中添加 QDockWidget对象
addDockWidget(Qt::LeftDockWidgetArea,DockWidget);
4.状态栏(Status Bar)
派生自QWidget类,使用方法与QWidget类似,QStatusBar类常用成员函数:
//添加小部件
void addWidget(QWidget * widget, int stretch = 0)
//插入小部件
int insertWidget(int index, QWidget * widget, int stretch = 0)
//删除小部件
void removeWidget(QWidget * widget)
例子:
m_SerStatLabel = new QLabel(tr(" 串口状态:关闭 "),this);
ui->statusbar->addWidget(m_SerStatLabel);
m_SerSendLabel = new QLabel(tr("%1").sprintf(" TX: %-10u ", m_SendCnt),this);
ui->statusbar->addWidget(m_SerSendLabel);
m_SerRecvLabel = new QLabel(tr("%1").sprintf(" RX: %-10u ", m_RecvCnt),this);
ui->statusbar->addWidget(m_SerRecvLabel);
QPushButton* pBtn = new QPushButton(tr(" 计数清空 "),this);
pBtn->setStyleSheet("border:none");
ui->statusbar->addWidget(pBtn);
connect(pBtn, &QPushButton::clicked, this, [=](){
m_SendCnt = 0;
m_RecvCnt = 0;
m_SerSendLabel->setText(tr("%1").sprintf(" TX: %-10u ", 0));
m_SerRecvLabel->setText(tr("%1").sprintf(" RX: %-10u ", 0));
});
m_TimeLabel = new QLabel(QDateTime::currentDateTime().toString(" yyyy-MM-dd hh:mm:ss "),this);
ui->statusbar->addWidget(m_TimeLabel);
QString strVer = "Ver: ";
strVer += QApplication::applicationVersion();
strVer += " ";
QLabel *label = new QLabel(strVer,this);
//创建在右侧
ui->statusbar->addPermanentWidget(label);
5.中央窗口(Central Widget)
内容窗口作为主窗口的主要展示窗口,其随着主窗口的伸缩而伸缩 。使用setCentralWidget(xxx); 来设置中央窗口;