У меня есть рабочее приложение. Я добавил 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, чтобы видеть, когда фокус находится на панели меню. И эта коробка появляется только в половине случаев. Это выглядит так:
Как убедиться, что при отображении строки меню она всегда имеет фокус?
Я хотел сделать то же самое. Мое решение, полный пример, как суть:
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;
}
};
Вы пробовали просто добавить setFocus
команда?
void MainWindow::keyPressEvent( QKeyEvent *k ) {
if(k->modifiers() & Qt::AltModifier) {
menuBar()->setHidden(!menuBar()->isHidden());
menuBar()->setFocus(Qt::MenuBarFocusReason);
if(menuBar()->hasFocus()) {
QMessageBox::information(this, "Info", "Focus !");
}
}
}