Сигналы в мире 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();
}