关于多线程:来自非 GUI 线程的 QStandardItemModel* 没有发出 itemChanged 信号

QStandardItemModel* from non-GUI thread didn`t emit itemChanged signal

我已经开始使用 QtCuncurrent::run 在非 GUI 线程中加载数据库。
在这个 nonGui 线程中,我必须创建 QStandardItemModel* ,然后我在 GUI 线程中收到模型

1
model = modelWatcher.result();

在 QFutureWatcher finished() 信号上。它工作得很好(UI 已成功构建),但 itemChanged() 信号不会在项目数据更改时发出(复选框状态已更改)。当我在 GUI 线程中创建模型时,没有冲突。没有断言的连接工作失败:

1
2
bool ok = connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(onFolderStateChanged(QStandardItem*)), static_cast<Qt::ConnectionType>(Qt::UniqueConnection));
Q_ASSERT(ok);

正如我在那个线程中看到的(没有代码示例,我误解了主要思想)我无法在 nonGui 线程中创建模型(Qt5Gui 的一部分)。但它对我有用! Ui 已构建)我还必须声明发送的类型:

1
qRegisterMetaType<QStandardItemModel*>("QStandardItemModel*");

我的其他发送如下:

1
qRegisterMetaType<QList<QTreeWidgetItem*> >("QList<QTreeWidgetItem*>");

效果很好(尽管它也是 Qt5Gui 的一部分)。

我没有t understand how can I **get the model from nonGui thread with full functionality** like itemChanged signals?
It
类似 emit mysignal(QStandardItemModel*); 的东西?
在那种情况下,为什么其他任务在没有任何发射的情况下也能正常工作?包括 currentChanged 信号等。


当我从非Gui线程发送模型时,一些信号丢失了,因为模型指针和相关数据如果我没记错的话是不正确的。还有 QStandardItemModel - 是 Qt5Gui 的一部分,它不是线程安全的。这意味着,模型和视图应该在 GUI 线程中收集,并且数据必须从工作线程发送并绑定到 GUI 线程中的模型。在我的情况下这并不简单 - 我有一棵大树,我不想创建自己的结构来解析树 - 但它是一种"真正的方式")。
我正在使用更简单的决定 - 我只是将 parentItem 指针发送到 GUI 线程中的新模型 - 它可以工作。
如果有人知道如何从简单的工作线程发送树结构 - 请在这个线程中告诉它)
在任何情况下 - 在线程之间使用文本表示的数据传输 - 它更优选的方法(如 JSON/XML...任何你自己的表示,基于项目的索引,列在``QList>` 等......)


你试过这个吗?

1
2
3
bool ok = connect(model, SIGNAL(itemChanged(QStandardItem*)), this,
SLOT(onFolderStateChanged(QStandardItem*)),
static_cast<Qt::ConnectionType>(Qt::AutoConnection | Qt::UniqueConnection));