我有一个使用Qt的C ++程序,它的GUI QObject具有链接到函数(foo
)的ComboBox(简称为bar()
)。此QObject称为对象A
。
组合框在构造函数中链接:
connect(foo, SIGNAL(currentIndexChanged(int)), SLOT(bar(int)));
在bar(int)
中,此函数在函数末尾被调用:
inspector->update();
在检查器的update
函数中,发生这种情况:
A
被删除(delete A;
,几乎是它是由new
创建的)。
创建了一个与A
类型相同的新实例,我们称之为对象B
。
这已初始化并且可以运行一会儿,然后一切都变得非常错误。
程序出现段错误,但仅是由于Qt错误。 GDB并没有多大帮助,但是通过Valgrind memcheck运行程序会产生大量无效读取,例如:
==23410== Invalid read of size 8
==23410== at 0xFE92D7A: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.9.5)
==23410== by 0x79DDC94: QComboBox::currentIndexChanged(QString const&) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.9.5)
==23410== by 0x79DFB2D: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.9.5)
...
==23410== Address 0x3218ca68 is 8 bytes inside a block of size 48 free'd
==23410== at 0x4C3123B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23410== by 0xFE9119A: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.9.5)
==23410== by 0x7913D4B: QWidget::~QWidget() (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.9.5)
在我看来,好像foo
的信号被再次发送,并试图调用不存在的对象bar()
的{{1}}。但这怎么可能呢?当然A
也应该阻止任何信号通过吗?另外,我只更改一次组合框的值-为什么会发送多个信号?
我尝试了阻止信号,并且尝试了重新整理内容,但没有成功。
这里是整个相关的Valgrind memcheck log。
这是Qt的错误吗?还是我做错了什么?非常感谢您提供任何帮助,包括进一步调试的帮助。
答案 0 :(得分:0)
尝试执行以下操作:
首先将成员searchQuery: ""
添加到您的班级。
在构造函数中,将QMetaObject::Connection foo_barConnect;
保存在connect
中:
foo_barConnect
foo_barConnect = connect(foo, SIGNAL(currentIndexChanged(int)), SLOT(bar(int)));
函数的update()
之前添加:delete
// Check if `foo_barConnect` is valid (connected)
if(foo_barConnect){
// Disconnect foo_bar connection
disconnect(foo_barConnect);
}
对象并且需要连接,请不要忘记重新new
并将连接存储在connect
中。希望它对您有帮助。