[英]QMetaObject::invokeMethod() returning false when used to call QListWidget::addItem()
I am trying to add an item to a QListWidget owned by the main thread from a background thread in a threadsafe manner by using QMetaObject::invokeMethod(). 我试图通过使用QMetaObject :: invokeMethod()以线程安全的方式将一个项目添加到后台线程从主线程拥有的QListWidget中。
QMetaObject::invokeMethod() works and returns true when I use it to call clear() on the QListWidget but returns false when I use it to call addItem(), as seen in this code: QMetaObject :: invokeMethod()可以正常工作,当我使用它调用QListWidget上的clear()时返回true,但是当我使用它调用addItem()时返回false,如以下代码所示:
void BlockingInvokeStringArg(QObject* widget, const char* functionName, const string& arg = "")
{
QString argAsQString(arg.c_str());
QGenericArgument genericArg = arg.empty() ? QGenericArgument() : Q_ARG(QString, argAsQString);
if (!QMetaObject::invokeMethod(widget, functionName, Qt::BlockingQueuedConnection, genericArg))
{
throw runtime_error("QMetaObject::invokeMethod() returned false");
}
}
void BacktestGui::on_buttonRunBacktest_clicked()
{
auto runBacktest = [&]()
{
// Does not throw:
BlockingInvokeStringArg(m_ui.listSymbols, "clear");
// Throws:
BlockingInvokeStringArg(m_ui.listSymbols, "addItem", "ItemName");
// Does not throw but may be thread-unsafe due to a background thread interacting with a GUI component owned by the main thread:
m_ui.listSymbols->addItem("ItemName");
};
QtConcurrent::run(runBacktest);
}
Why does QMetaObject::invokeMethod() return true when calling clear() on a QListWidget but return false when calling addItem()? 为什么在QListWidget上调用clear()时QMetaObject :: invokeMethod()返回true,而在调用addItem()时返回false?
If QMetaObject::invokeMethod() cannot be used to call addItem(), do you know a threadsafe alternative for adding an item to a QListWidget from a background thread? 如果QMetaObject :: invokeMethod()无法用于调用addItem(),您是否知道从后台线程向QListWidget添加项目的线程安全替代方法?
invokeMethod() is able to invoke a signal or a slot. invokeMethod()能够调用信号或插槽。 QListWidget::clear() is a slot, so that works.
QListWidget :: clear()是一个插槽,因此可以正常工作。 QListWidget::addItem() is not a slot, therefore you can't invoke it.
QListWidget :: addItem()不是插槽,因此您不能调用它。
The solution is simple. 解决方案很简单。 Write a slot that takes the QListWidget as an argument and which calls addItem() on it, and invoke that slot.
编写一个使用QListWidget作为参数并在其上调用addItem()的插槽,然后调用该插槽。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.