阅读您的问题,我不太确定您的实际问题是什么。不幸的是,由于我们公司的安全政策,i.stack.imgur.com 被屏蔽了,我只是在办公室。可能,你的快照已经为我澄清了事情。 (我回家的时候可以看看。)
但是,出于好奇,我尝试了自己的运气并想展示我所拥有的:
实际上,使用QStatusBar::insertPermanentWidget() 将小部件添加到状态栏非常容易。
不幸的是,永久小部件放置在右侧。如果要求(将其放在左侧)是必不可少的,则可以通过将两个状态栏相互嵌套来进行调整。 (实际上,其他所有布局也应该可以,但QMainWindow::setStatusBar() 需要QStatusBar*。)
内部状态栏是必须用于临时消息的状态栏。为防止重复尺寸夹点的滑稽效果,内部状态栏的尺寸夹点被禁用(使用QStatusBar::setSizeGripEnabled())。
嵌套状态栏的另一个副作用是内部状态栏左右分隔符的可视化。我认为这还不错(就美学方面而言)并且不在乎。
也许,我可以简单地使用QLabel(而不是内部状态栏)来显示消息(失去QStatusBar 提供的附加功能,例如自动清除消息的超时)。
为了提供开始按钮,我最初使用了QPushButton。记住我必须以某种方式放置开始菜单,因此我将其替换为 QToolBar,因为它可能包含 QAction,而 QAction 又准备好管理子菜单。
当我开始工作时,我意识到设置菜单时出现在开始按钮上的指示器。为了使示例尽可能短,我决定暂时使用它。
在与提问者进行了一些沟通后,我使用派生自QLabel 的类添加了一个替代实现。菜单放置必须自行完成。但最后,它并没有那么复杂......
如果定义了USE_LABEL(接近源代码的开头),则激活第 2nd 版本。
我的样本testQStartBtn.cc:
#include <QtWidgets>
#define USE_LABEL
#ifdef USE_LABEL
class StartButton: public QLabel {
private:
QMenu *_pQMenu;
public:
StartButton(QWidget *pQParent = 0): QLabel(pQParent), _pQMenu(nullptr) { }
QMenu* menu() { return _pQMenu; }
QMenu* setMenu(QMenu *pQMenu) { std::swap(_pQMenu, pQMenu); return pQMenu; }
protected:
virtual void mousePressEvent(QMouseEvent *pQEvent);
};
void StartButton::mousePressEvent(QMouseEvent *pQEvent)
{
if (_pQMenu && pQEvent->button() == Qt::LeftButton) {
if (!_pQMenu->isVisible()) {
_pQMenu->show(); // a trick to force computation of height() before
_pQMenu->popup(mapToGlobal(pos()) - QPoint(0, _pQMenu->height()));
} else _pQMenu->hide();
}
}
#endif // USE_LABEL
int main(int argc, char **argv)
{
qDebug() << "Qt Version: " << QT_VERSION_STR;
// main application
#undef qApp // undef macro qApp out of the way
QApplication qApp(argc, argv);
// setup GUI
QMainWindow qWin;
QLabel qLblCentral(QString::fromUtf8("Central\nWidget"));
qLblCentral.setAlignment(Qt::AlignCenter);
qWin.setCentralWidget(&qLblCentral);
QStatusBar qStBarLayout;
// the "Windows Start Menu" alike
#ifdef USE_LABEL
StartButton qBtnStart;
qBtnStart.setPixmap(QPixmap(
QApplication::applicationDirPath() + QString::fromLatin1("/Start.png")));
#else // (not) USE_LABEL
QToolBar qToolbarStart;
QIcon qIcnStart(
QApplication::applicationDirPath() + QString::fromLatin1("/Start.png"));
QAction qCmdStart(qIcnStart, QString::fromUtf8("Start"), &qToolbarStart);
#endif // USE_LABEL
QMenu qMenuStart;
QAction qCmdStart1(QString::fromUtf8("Command 1"), &qMenuStart);
qMenuStart.addAction(&qCmdStart1);
QAction qCmdStart2(QString::fromUtf8("Command 2"), &qMenuStart);
qMenuStart.addAction(&qCmdStart2);
QAction qCmdStart3(QString::fromUtf8("Command 3"), &qMenuStart);
qMenuStart.addAction(&qCmdStart3);
#ifdef USE_LABEL
qBtnStart.setMenu(&qMenuStart);
qStBarLayout.insertPermanentWidget(0, &qBtnStart);
#else // (not) USE_LABEL
qCmdStart.setMenu(&qMenuStart);
qToolbarStart.addAction(&qCmdStart);
qStBarLayout.insertPermanentWidget(0, &qToolbarStart);
#endif // USE_LABEL
// the rest of status bar
QStatusBar qStBar;
qStBar.showMessage(QString::fromUtf8("<- Start Menu"), 3000 /* ms */);
qStBar.setSizeGripEnabled(false);
qStBarLayout.insertPermanentWidget(1, &qStBar, 1);
qWin.setStatusBar(&qStBarLayout);
qWin.show();
// install signal handlers
QObject::connect(&qCmdStart1, &QAction::triggered,
[](bool){ qDebug() << "Command 1 triggered"; });
QObject::connect(&qCmdStart2, &QAction::triggered,
[](bool){ qDebug() << "Command 2 triggered"; });
QObject::connect(&qCmdStart3, &QAction::triggered,
[](bool){ qDebug() << "Command 3 triggered"; });
// run application
return qApp.exec();
}
我在 Windows 10(64 位)上使用 VS2013 和 Qt5.6 编译。看起来是这样的:
带有派生QLabel 的更新版本如下所示: