0

ボタンを作成し、それを文字列を取るスロットに接続するメソッドを書きたいと思います。

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 の原因でした。なぜそうするのかはまだ明らかにされていません。

4

0 に答える 0