How to focus menuBar() with Qt

后端 未结 2 931
半阙折子戏
半阙折子戏 2021-01-21 22:38

I have a working application. I added a menuBar() to the main window with some menus. Then, I hid it to free screen space. I wrote the code below so that when user presses ALT k

相关标签:
2条回答
  • 2021-01-21 23:22

    I wanted to do the same thing. My solution, complete example, as a gist:

    https://gist.github.com/xim/ee56564f425151ea2fa70f730d644873

    Tested against Qt 5.9.4.

    As it contains a lot of other junk, a minimal example:

    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;
        }
    };
    
    0 讨论(0)
  • 2021-01-21 23:22

    Have you tried just adding the setFocus command?

    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 讨论(0)
提交回复
热议问题