我想编写一个创建按钮并将其连接到带有字符串的插槽的方法:
void Widget::createButton(const char *member)
{
QPushButton *button = new QPushButton(this);
QSignalMapper *signalMapper = new QSignalMapper(this);
signalMapper->setMapping(button, "Test");
connect(signalMapper, SIGNAL(mapped(QString)), this, member);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
}
void Widget::sendCom(QString data)
{
std::cout << data << std::endl;
}
在Widget
的实例(只是QWidget
的子类)上我做了:
widget->createButton(SLOT(sendCom(QString))
没有映射它工作得很好,我从类似的代码片段复制了映射语法,也可以正常工作。编译时没有错误,但是当我按下按钮时,我最终会出现分段错误。有任何想法吗?
编辑:像peppe建议我运行valgrind,这是输出
==31303== Invalid read of size 8
==31303== at 0x3E1632DBF0: QAbstractButton::text() const (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x407A66: Widget::sendCom(QString) (widget.cpp:36)
==31303== by 0x40804E: Widget::qt_metacall(QMetaObject::Call, int, void**) (moc_widget.cpp:72)
==31303== by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6DEE4: QSignalMapper::mapped(QString const&) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6E009: QSignalMapper::map(QObject*) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6F23F: QSignalMapper::qt_metacall(QMetaObject::Call, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E165DCE51: QAbstractButton::clicked(bool) (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x3E1632E75A: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x3E1632FADA: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x3E1632FD4B: QAbstractButton::mouseReleaseEvent(QMouseEvent*) (in /usr/lib64/libQtGui.so.4.6.2)
==31303== Address 0x8 is not stack'd, malloc'd or (recently) free'd
==31303==
==31303==
==31303== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==31303== Access not within mapped region at address 0x8
==31303== at 0x3E1632DBF0: QAbstractButton::text() const (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x407A66: Widget::sendCom(QString) (widget.cpp:36)
==31303== by 0x40804E: Widget::qt_metacall(QMetaObject::Call, int, void**) (moc_widget.cpp:72)
==31303== by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6DEE4: QSignalMapper::mapped(QString const&) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6E009: QSignalMapper::map(QObject*) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6F23F: QSignalMapper::qt_metacall(QMetaObject::Call, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E0FB6A7DE: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib64/libQtCore.so.4.6.2)
==31303== by 0x3E165DCE51: QAbstractButton::clicked(bool) (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x3E1632E75A: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x3E1632FADA: ??? (in /usr/lib64/libQtGui.so.4.6.2)
==31303== by 0x3E1632FD4B: QAbstractButton::mouseReleaseEvent(QMouseEvent*) (in /usr/lib64/libQtGui.so.4.6.2)
这有助于查找地址,但我仍然不知道如何调试。
编辑:问题解决了。我将代码缩短为更精确,但这隐藏了实际原因
Create Button actually looked like this:
void Widget::createButton(const QString &text, int x, int y, const char *member, QString &data)
{
QPushButton *button = new QPushButton(this);
signalMapper = new QSignalMapper(this);
signalMapper->setMapping(button, data);
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(sendCom(QString)));
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
button->setText(text);
button->move(x, y);
button->show();
}
void Widget::sendCom(QString data)
{
QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
std::cout << qPrintable(data) << std::endl;
std::cout << qPrintable(clickedButton->text()) << std::endl;
}
qobject_cast导致了SIGSEGV。它仍然要澄清它为什么会这样做。