目录
菜单栏
工具栏
状态栏
总体效果
在QWidget中实现菜单栏、工具栏、状态栏
其他
子窗口获取父窗口指针
QWidget阻塞模式
本篇演示的例子是在QMainWindow中进行的,在QWidget中可采取另外的方法,在文末会涉及。
步骤:创建菜单栏->创建菜单项->创建子项(动作QAction)->(QAction设置图片->QAction设置快捷键->)将子项添加到菜单项->将菜单项添加到菜单栏
其中设置图片时要先将图片加载到qrc中,如果图片较多可以单独创建一个文件夹。
代码:
QMenuBar pMenuBar = menuBar();
//菜单-文件
QMenu *pMenuBarFile= new QMenu(QStringLiteral("文件(&F)"));
QAction *pActionOpen = new QAction(QStringLiteral("打开"), this);
pActionOpen->setIcon(QIcon(":/ReplicationTool/png/open.png"));
pActionOpen->setShortcut(Qt::CTRL | Qt::Key_O);
pMenuBarFile->addAction(pActionOpen);
pMenuBar->addMenu(pMenuBarFile);
//...
//继续添加其他菜单项
效果:
要实现带图片的工具栏图标,并且文字要显示图标下面,我们选择使用QToolButton。如果使用QAction则图片和文字只能显示一个。用QAction的步骤与创建菜单栏的一致。
步骤:创建工具栏->创建工具栏按钮->添加图片->设置文字->设置图片与文字的位置->将工具栏按钮放进工具栏
代码:
QToolBar pToolBar = addToolBar("toolBar");
QToolButton *pActionOpenBar = new QToolButton(this);
pActionOpenBar->setIcon(QIcon(":/ReplicationTool/png/open.png"));
pActionOpenBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
pActionOpenBar->setText(QStringLiteral("打开"));
pToolBar->addWidget(pActionOpenBar);
//添加其他按钮...
//添加分隔符
pToolBar->addSeparator();
效果:
另外设置图片大小:
pActionOpenBar->setIconSize(QSize(50, 50));
步骤:创建状态栏->创建需要往上面添加的控件->将控件添加到状态栏
下面创建一个状态栏,上面显示系统状态、进度条和系统时间。
代码:
QStatusBar *pStatusBar = statusBar();
QLabel *pWelCome = new QLabel(QStringLiteral(" 就绪"));
pStatusBar->addWidget(pWelCome);
QProgressBar * pProgressBar = new QProgressBar();
pProgressBar->setRange(0,100);
pProgressBar->setValue(20);
pProgressBar->setMaximumWidth(200);
pStatusBar->addPermanentWidget(pProgressBar);
pTimeLabel = new QLabel();
pStatusBar->addPermanentWidget(pTimeLabel);
QTimer *pTimer = new QTimer(this);
timeUpdate_Slot();
pTimer->start(1000);
connect(pTimer, SIGNAL(timeout()),this,SLOT(timeUpdate_Slot()));
//更新时间的槽函数中的代码
QDateTime currentTime = QDateTime::currentDateTime();
QString timeStr = currentTime.toString(QStringLiteral("yyyy年MM月dd日 hh:mm:ss"));
pTimeLabel->setText(timeStr);
效果:
再加上两个悬浮窗口 ,就可以组成一个经典软件界面。
由于Qwidget没有menuBar(),addToolBar(),statusBar(),因此我们创建好后要给他指定位置。
一个好的方法就是先在界面上拖几个QFrame到指定位置,分别放菜单栏、工具栏、状态栏 ,如下
拖进去后适当调整一下高度,长可以在代码中调整。
然后分别以对应的QFrame为父窗口new出菜单栏、工具栏、状态栏对象,下面以菜单栏为例:
//将菜单放入QFrame并设置与界面等宽
ui.frameMenu->resize(this->geometry().width(), ui.frameMenu->height());
QMenuBar *pMenuBar = new QMenuBar(ui.frameMenu);
pMenuBar->setFixedSize(ui.frameMenu->width(), ui.frameMenu->height());
//剩下操作与QMainWindow中一致
//略...
可采取如下安全强制转换的方式
MainDlg *pMainDlg = qobject_cast(this->parentWidget());
然后再通过指针去调用父窗口方法,但该方法必须为public的。
或者直接发信号给父窗口,让父窗口去调用其方法。
QDialog可以直接用exec(),而QWidget的show()是非阻塞的。
解决方案是:
假设要在WidgetA中弹出阻塞的WidgetB,则
1 在WidgetA中创建WidgetB时以WidgetA为父窗口
2 在WidgetB的构造函数里设置相关属性
代码:
//widgeta.cpp
WidgetB *pWidgetB = new WidgetB(this);
pWidgetB->show();
//widgetb.cpp
WidgetB::WidgetB(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
this->setWindowFlags(Qt::Dialog);
this->setWindowModality(Qt::WindowModal);
//...
}