将小部件信号与父小部件插槽连接时没有这样的插槽
No such slot when connecting widget signal with parent widget slot
我有以下 classes:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QStringList pluginsToStart, QWidget *parent = 0);
~MainWindow();
// some other stuff
public slots:
void on_timeDataChanged(logging::TimeValueVector<bool>& aData);
void on_importStarted();
}
和
class DataImporterWidget : public PluginWidget
{
Q_OBJECT
public:
explicit DataImporterWidget(QWidget *parent = 0);
~DataImporterWidget();
void initConnections(QMap<QString, PluginWidget*> pluginWidgetMap);
在方法 initConnections 中,我希望小部件像这样初始化信号槽连接:
void DataImporterWidget::initConnections(QMap<QString, PluginWidget*> pluginWidgetMap)
{
for(Importer* importer : this->getImporterMap().values())
{
connect(importer, SIGNAL(signal_timeDataChanged(logging::TimeValueVector<bool>&)),
parentWidget(), SLOT(on_timeDataChanged(logging::TimeValueVector<bool>&)));
}
connect(this, SIGNAL(signal_importStarted()), parentWidget(), SLOT(on_importStarted()));
}
Importer 是一个 QGroupBox 和一个基础 class 派生子 classes 指定具体的数据导入器类型。
它是这样工作的:如果我按下一个按钮,就会创建一个 DataImporterWidget 并将其作为 QMdiSubWindow 添加到 QMdiArea。创建 DataImporterWidget 时,我调用了 initConnections() 方法来设置信号槽连接。
现在,当我 运行 程序时,我收到以下消息:
QObject::connect: No such slot
QMdiSubWindow::on_timeDataChanged(logging::TimeValueVector<bool>&) in src/dataimporter/DataImporterWidget.cpp:81
QObject::connect: No such slot QMdiSubWindow::on_importStarted() in src/dataimporter/DataImporterWidget.cpp:85
QObject::connect: (sender name: 'DataImporterWidget')
我不明白为什么我得到它,因为插槽在那里。即使我将 parentWidget 投射到 MainWindow,我也会得到同样的错误。
PluginWidget 只是一个 class 派生自 QWidget 的基础,它包含我使用的插件的一些通用功能。
我将 Q_OBJECT 放在每个基础上并导出 class 但仍然出现此错误。但是,如果我在主窗口中设置连接,它工作得很好,但我想知道为什么上面的解决方案不起作用。
不要从子对象创建连接,而是在创建子对象后从父对象代码创建它。
这样你就不需要转换任何类型了。
您没有显示大量重要代码(例如创建 DataImporterWidget
、将 MainWindow
设置为其父级、您调用 initConnections
的地方...)。然而,你说
If I use the new signal slot syntax, my program crashes with a
segmentation fault...
如果它崩溃了,那么您必须找到原因。使用旧的信号槽连接语法并不能治愈疾病,它只会延迟它的表现。根据 this,您得到段错误的原因可能是 parentWidget() == nullptr
或 parent
尚未初始化。
我的建议是,检查你的代码,并在调用 initConnections()
之前创建并指定用户 DataImporterWidget
的父级。
我找到问题了。原因是,MainWidget class 拥有一个 QMdiArea,我在其中添加了我的 PluginWidgets。所以,当我创建 PluginWidget 时,我将 MainWidget 设置为它的父级,但是一旦我将它添加到 QMdiArea,它也成为 QMdiSubWindow 的子级。 parentWidget 永远不会为空,但它是错误的 ...
我有以下 classes:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QStringList pluginsToStart, QWidget *parent = 0);
~MainWindow();
// some other stuff
public slots:
void on_timeDataChanged(logging::TimeValueVector<bool>& aData);
void on_importStarted();
}
和
class DataImporterWidget : public PluginWidget
{
Q_OBJECT
public:
explicit DataImporterWidget(QWidget *parent = 0);
~DataImporterWidget();
void initConnections(QMap<QString, PluginWidget*> pluginWidgetMap);
在方法 initConnections 中,我希望小部件像这样初始化信号槽连接:
void DataImporterWidget::initConnections(QMap<QString, PluginWidget*> pluginWidgetMap)
{
for(Importer* importer : this->getImporterMap().values())
{
connect(importer, SIGNAL(signal_timeDataChanged(logging::TimeValueVector<bool>&)),
parentWidget(), SLOT(on_timeDataChanged(logging::TimeValueVector<bool>&)));
}
connect(this, SIGNAL(signal_importStarted()), parentWidget(), SLOT(on_importStarted()));
}
Importer 是一个 QGroupBox 和一个基础 class 派生子 classes 指定具体的数据导入器类型。 它是这样工作的:如果我按下一个按钮,就会创建一个 DataImporterWidget 并将其作为 QMdiSubWindow 添加到 QMdiArea。创建 DataImporterWidget 时,我调用了 initConnections() 方法来设置信号槽连接。
现在,当我 运行 程序时,我收到以下消息:
QObject::connect: No such slot
QMdiSubWindow::on_timeDataChanged(logging::TimeValueVector<bool>&) in src/dataimporter/DataImporterWidget.cpp:81
QObject::connect: No such slot QMdiSubWindow::on_importStarted() in src/dataimporter/DataImporterWidget.cpp:85
QObject::connect: (sender name: 'DataImporterWidget')
我不明白为什么我得到它,因为插槽在那里。即使我将 parentWidget 投射到 MainWindow,我也会得到同样的错误。
PluginWidget 只是一个 class 派生自 QWidget 的基础,它包含我使用的插件的一些通用功能。 我将 Q_OBJECT 放在每个基础上并导出 class 但仍然出现此错误。但是,如果我在主窗口中设置连接,它工作得很好,但我想知道为什么上面的解决方案不起作用。
不要从子对象创建连接,而是在创建子对象后从父对象代码创建它。 这样你就不需要转换任何类型了。
您没有显示大量重要代码(例如创建 DataImporterWidget
、将 MainWindow
设置为其父级、您调用 initConnections
的地方...)。然而,你说
If I use the new signal slot syntax, my program crashes with a segmentation fault...
如果它崩溃了,那么您必须找到原因。使用旧的信号槽连接语法并不能治愈疾病,它只会延迟它的表现。根据 this,您得到段错误的原因可能是 parentWidget() == nullptr
或 parent
尚未初始化。
我的建议是,检查你的代码,并在调用 initConnections()
之前创建并指定用户 DataImporterWidget
的父级。
我找到问题了。原因是,MainWidget class 拥有一个 QMdiArea,我在其中添加了我的 PluginWidgets。所以,当我创建 PluginWidget 时,我将 MainWidget 设置为它的父级,但是一旦我将它添加到 QMdiArea,它也成为 QMdiSubWindow 的子级。 parentWidget 永远不会为空,但它是错误的 ...