我有一个有效的应用程序。我向菜单中的一些菜单添加了menuBar()。然后,我将其隐藏以释放屏幕空间。我在下面编写了代码,以便当用户按ALT键时,菜单栏在隐藏时显示,在菜单栏显示时隐藏。
void MainWindow::keyPressEvent( QKeyEvent *k ) {
if(k->modifiers() & Qt::AltModifier) {
menuBar()->setHidden(!menuBar()->isHidden());
if(menuBar()->hasFocus()) {
QMessageBox::information(this, "Info", "Focus !");
}
}
}
如您所见,我还添加了一个QMessageBox来查看menuBar何时具有焦点。并且此框仅出现一半时间。它是这样的:
如何确保显示menuBar时始终具有焦点?
最佳答案
我想做同样的事情。我的解决方案,完整的示例,作为要点:
https://gist.github.com/xim/ee56564f425151ea2fa70f730d644873
经过Qt 5.9.4测试。
由于其中包含许多其他垃圾,因此举一个最小的示例:
class AutoHidingMenuBar : public QMenuBar {
Q_OBJECT
public:
AutoHidingMenuBar() : QMenuBar() {
setMaximumHeight(0);
connect(qApp, &QApplication::focusChanged, this, &AutoHidingMenuBar::focusChanged);
}
private slots:
void focusChanged(QWidget *from, QWidget *to) {
bool inFocus = hasFocus() || isAncestorOf(focus) || hasFocusedChild();
if (inFocus && maximumHeight() == 0) {
auto action = activeAction();
setMaximumHeight(100);
if (action) {
// XXX This is a bit of a hack. We could do
// QCoreApplication::processEvents();
// setActiveAction(action);
// with almost the same effect, but then we *open* the first menu on single alt press...
auto evt = new QMouseEvent(QEvent::MouseMove, actionGeometry(action).center(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QCoreApplication::postEvent(this, evt);
}
} else if (!inFocus && maximumHeight() != 0)) {
setMaximumHeight(0);
}
}
private:
bool hasFocusedChild() {
QObjectList queue{children()};
while (!queue.empty()) {
auto child = queue.takeFirst();
auto widget = dynamic_cast<QWidget *>(child);
if (widget && widget->hasFocus())
return true;
queue.append(child->children());
}
return false;
}
};