我正在创建一个显示市场数据的应用程序,并以其他形式使用它。我将市场数据存储在地图中
std::map<tickerId, StockData>
。让我举一个例子,说明如何使用这张地图。
updatePrice(tickerId, latestPrice)
updatePosition(tickerId, price)
和updateStockScreen(tickerId, price)
。此外,从位置更新中分离Gui更新非常重要,因为GUI不是应用程序的主要优势。对有用书籍的一些参考也很受欢迎。
我很新,并试图通过我的小知识实现太多,所以如果我问过愚蠢/形容不对的问题,请原谅我。
由于 希夫
答案 0 :(得分:11)
在概念上听起来就像你想要一个线程上的模型和另一个线程上的视图,我在一个点上看到了它。
如果是这样......并且您的模型通过视图小部件是只读的,那么是的,您必须锁定。我认为这样做会破坏模型/视图分离所提供的“解耦”的优雅。但它可以起作用。
但是......如果您的模型是通过视图进行读写,则由于通知槽的排队特性,无法正确执行 。这是我在qt-interest邮件列表上关于该主题的邮件列表对话的存档:
http://blog.hostilefork.com/qt-model-view-different-threads/
“简短版本是我认为模型不可行 在非GUI线程上进行修改......无论模型是否为
数据已通过读/写锁保护。如果我正在收集什么 是正确的,那么Qt应该有一个断言模型和 它的视图具有相同的线程亲和力(现在似乎没有这样做)“
KDE开发人员进行的后续单元测试验证了这一点。
我觉得解决这个问题的最佳方法是将模型和视图保持在同一个线程上,并且只修改GUI线程中的模型。因此,如果工作线程希望更改它,那么它应该使用信号。
工作人员是否需要保留自己创建模型的数据副本(或者当用户通过视图更改模型时是否需要通知以使其保持最新)取决于您的应用。如果我理解正确的话,听起来好像你可能只是通过信号/插槽传送更新并将其遗忘在工作人员身上......
答案 1 :(得分:1)
即使模型是只读的,我今天也学到了另一个潜在的问题。我使用另一个线程来修改模型中的数据(实际上,我的程序超过20个线程,它们都很好),然后Qt计时器更新。这非常有效,但我遇到了一个问题,那就是:
您无法锁定rowCount
/ columnCount
和data()
。
Qt按顺序工作,这意味着在人类语言中,它会问你有多大&#34;然后问'#34;你在这个位置有什么数据&#34;,这些都容易破裂。
考虑:
int FilesQueue::rowCount(const QModelIndex &/*parent*/) const
{
std::lock_guard<decltype(mainQueueMutex)> lg(mainQueueMutex);
return filesQueue.size();
}
QVariant FilesQueue::data(const QModelIndex &index, int role) const
{
std::lock_guard<decltype(mainQueueMutex)> lg(mainQueueMutex);
if ( role == Qt::DisplayRole) {
return filesQueue[index.row()]->getFilename();
}
}
Qt会像这样打电话:
//...
obj->rowCount();
obj->data(...);
//...
我在整个地方都有断言失败,因为简单地说,在rowCount()
和data()
之间,有一个线程正在改变数据的大小!它打破了这个计划。所以这发生了:
//...
obj->rowCount();
//another thread: filesQueue.erase(...)
obj->data(...);
//...
我对此问题的解决方案是再次在data()方法中验证大小:
QVariant FilesQueue::data(const QModelIndex &index, int role) const
{
std::lock_guard<decltype(mainQueueMutex)> lg(mainQueueMutex);
//solution is here:
if(static_cast<int>(filesQueue.size()) <= index.row())
return QVariant();
if ( role == Qt::DisplayRole) {
return filesQueue[index.row()]->getFilename();
}
}
我生命中有3个小时我永远不会回来:-)