Как сфокусировать menuBar () с помощью Qt

У меня есть рабочее приложение. Я добавил 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, чтобы видеть, когда фокус находится на панели меню. И эта коробка появляется только в половине случаев. Это выглядит так:

  1. Приложение запущено, меню скрыто
  2. Я нажимаю ALT, отображается меню, нет окна сообщения, нет фокуса
  3. Я нажимаю ALT, меню скрыто
  4. Я нажимаю ALT, отображается меню, окно сообщения, фокус
  5. Я нажимаю ALT, меню скрыто
  6. Я нажимаю ALT, отображается меню, нет окна сообщения, нет фокуса
  7. Я нажимаю ALT, меню скрыто
  8. Я нажимаю ALT, отображается меню, окно сообщения, фокус
  9. и т.п.

Как убедиться, что при отображении строки меню она всегда имеет фокус?

2

Решение

Я хотел сделать то же самое. Мое решение, полный пример, как суть:

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;
}
};
1

Другие решения

Вы пробовали просто добавить 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 !");
}
}
}
0

По вопросам рекламы [email protected]