Как использовать сигналы QMenu? - PullRequest
0 голосов
/ 30 сентября 2018

Очень просто подключиться к QMenu::triggered или QMenu::hovered сигналам, позвонив по номеру QObject::connect и передать соответствующие QAction.

ОднакоЯ не знаю, как использовать сигнал QMenu::aboutToHide, так как этому сигналу не передается никаких действий.

Как использовать сигналы QMenu::aboutToHide и QMenu::aboutToShow, или они простовиртуальные функции, которые могут быть переопределены?

1 Ответ

0 голосов
/ 30 сентября 2018

Сигналы в мире Qt не являются функциями, никогда не вызывайте их.Сигналы уведомляют о том, что что-то случилось с объектом QObject, и при необходимости отправляют информацию.

В случае triggered и hovered необходимо отправить QAction из-за нескольких QAction с в QMenu, тогда разработчик подумал, что необходимо знать, с какимиQAction взаимодействовал.С другой стороны, с aboutToShow и aboutToHide сигнал не отправляет ничего, потому что он хочет уведомить о том, что если QMenu был показан или скрыт, соответственно.Нужно ли знать, что QMenu был показан или скрыт, если он это сделал?нет, поскольку отправитель сделал это, я не использую другие свойства, которых у нас нет под рукой.

Пример использования:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;

    QMenu *foo_menu = w.menuBar()->addMenu("Foo Menu");
    for(const QString & name: {"action1", "action2", "action3"}){
        foo_menu->addAction(name);
    }
    QObject::connect(foo_menu, &QMenu::aboutToShow, [](){
        qDebug()<<"aboutToShow";
    });
    QObject::connect(foo_menu, &QMenu::aboutToHide, [](){
        qDebug()<<"aboutToHide";
    });
    QObject::connect(foo_menu, &QMenu::triggered, [](QAction *action){
        qDebug()<< "triggered: " <<action->text();
    });
    QObject::connect(foo_menu, &QMenu::hovered, [](QAction *action){
        qDebug()<< "hovered: " <<action->text();
    });
    w.show();

    return a.exec();
}

А что произойдет, если у вас естьнесколько QMenu, которые подключаются к одному и тому же слоту?Как я знаю, что QMenu был показан или скрыт?

Решение состоит в том, чтобы использовать sender(), который принадлежит к классу QObject, который возвращает объект, испустивший сигнал, в этомкейс QMenu.

Пример:

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QDebug>

class MainWindow: public QMainWindow{
public:
    MainWindow(QWidget *parent=nullptr):
        QMainWindow(parent)
    {
        for(const QString & name_of_menubar: {"bar1", "bar2", "bar3"}){
            QMenu *menu = menuBar()->addMenu(name_of_menubar);
            connect(menu, &QMenu::aboutToShow, this, &MainWindow::on_aboutToShow);
            connect(menu, &QMenu::aboutToHide, this, &MainWindow::on_aboutToHide);
            for(const QString & name: {"action1", "action2", "action3"}){
                menu->addAction(name);
            }
        }
    }
private slots:
    void on_aboutToShow(){
        if(QMenu *menu = qobject_cast<QMenu *>(sender()))
            qDebug()<<"aboutToShow" << menu->title();
    }
    void on_aboutToHide(){
        if(QMenu *menu = qobject_cast<QMenu *>(sender()))
            qDebug()<<"aboutToHide" << menu->title();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
...