Qt 我可以使用全局插槽吗?

Qt 我可以使用全局插槽吗?,qt,qt-signals,qt-slot,Qt,Qt Signals,Qt Slot,我可以在Qt中使用全局插槽吗 我正在尝试使用此代码,但它似乎不起作用 slots void f(int i); void connect(QSpinBox *spinBox) { QObject::connect(spinBox, SIGNAL(valueChanged(int)), NULL, SLOT(f(int))); } void f(int i) { // ... } 评论中已经指出:没有全球时段 另一方面,由于Qt5,您可以将任何方法连接到信号,即使它没有标记

我可以在Qt中使用全局插槽吗

我正在尝试使用此代码,但它似乎不起作用

slots void f(int i);

void connect(QSpinBox *spinBox)
{
    QObject::connect(spinBox, SIGNAL(valueChanged(int)), NULL, SLOT(f(int)));
}

void f(int i)
{
    // ...
}

评论中已经指出:没有全球时段


另一方面,由于Qt5,您可以将任何方法连接到信号,即使它没有标记为插槽。您甚至可以将全局函数和lambda连接到信号。因此,如果对“SLOT”的要求被放弃(并被称为“signalhandler”),它可能会提供您(可能)所要求的

示例代码
testQSpinBox.cc

// Qt header:
#include <QtWidgets>

// function with matching signature
void f(int value)
{
  qDebug() << value;
}

// function with non-matching signature
void g(const char *text, int value)
{
  qDebug() << text << value;
}

int main(int argc, char **argv)
{
  qDebug() << "Version:" << QT_VERSION_STR;
  // main application
  QApplication app(argc, argv);
  qDebug() << QApplication::style()->objectName();
  // setup GUI
  QWidget qWin;
  QVBoxLayout qBox;
  QSpinBox qSpinBox1;
  qBox.addWidget(&qSpinBox1);
  QSpinBox qSpinBox2;
  qBox.addWidget(&qSpinBox2);
  QSpinBox qSpinBox3;
  qBox.addWidget(&qSpinBox3);
  qWin.setLayout(&qBox);
  qWin.show();
  // install signal handlers
  // connect f() to qSpinBox1::valueChanged
  QObject::connect(&qSpinBox1,
    (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
    &f);
  // connect lambda to qSpinBox2::valueChanged
  QObject::connect(&qSpinBox2,
    (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
    [](int value) { qDebug() << "qSpinBox2:" << value; });
  // use lambda as adapter for function g()
  QObject::connect(&qSpinBox3,
    (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
    [](int value) { g("qSpinBox3:", value); });
  // run application
  return app.exec();
}
使用g++编译和测试:

$qmake-qt5 testQSpinBox.pro
$make
g++-c-fno保持内联dllexport-D_GNU_SOURCE-pipe-O2-Wall-W-D_REENTRANT-DQT_NO_DEBUG-DQT_WIDGETS-LIB-DQT_GUI_-LIB-DQT_CORE_-LIB-I.-isystem/usr/include/qt5-isystem/usr/include/qt5/QtWidgets-isystem/usr/include/qt5/QtGui-isystem/usr/include/QtGui/QtGui-isystem/usr/include/QtCore/qtc-I/qtc-I/I/usr/qt5/qtgwin-qtoq
g++-o testQSpinBox.exe testQSpinBox.o-lQt5Widgets-lQt5Gui-lQt5Core-lGL-lpthread
$./testQSpinBox
版本:5.9.2
“融合”

(我单击每个旋转框的向上按钮,强制
valueChanged
信号。)

1
qSpinBox2:1
qSpinBox3:1
注意:

有一个专业涉及——实际上有两个:

void QSpinBox::valueChanged(int i);

void QSpinBox::valueChanged(const QString &text);
因此,如果我们在
QObject::connect()
中提供信号,则方法标识符是不明确的。我们必须提供“方法指针转换”来解决歧义:

#if 0 // Ambiguity:
QObject::connect(&qSpinBox1, &QSpinBox::valueChanged, &f);
#else // Solve ambinguity:
QObject::connect(&qSpinBox1,
  (void(QSpinBox::*)(int))&QSpinBox::valueChanged,
  &f);
#endif // 0
具有多个签名的信号是Qt中的少数例外。通常,这种难看的方法指针转换对于连接Qt5样式的信号是不必要的



顺便说一句,在我对的回答中,我编写了支持Qt4和Qt5的代码。因此,与现代Qt 5信号处理程序相反的老式Qt插槽可能很有趣。

没有全局插槽,一个选项是创建一个单例并连接到该类的插槽。或者,如果您使用的是Qt 5.6或更高版本,您可以使用lambda函数调用该函数。为什么要使用“全局插槽”?通过参数设置某个小部件的属性。请更好地解释一下,什么小部件?我不明白为什么不可能。自Qt5以来,将全局函数(或lambda)连接到信号非常容易(使用新引入的
QObject::Connect()
方法)。例如,我在对的回答中使用了函数,在对的回答中使用了lambda,但还有很多其他示例。(好的,我不在乎Qt是否在“引擎盖下”生成一个helper对象)。