[solved] QStandardItem::insertRows: Ignoring duplicate insertion of item... 1 signal emitted to multiple objects
-
Hi,
I have an application with a list of Dialogs(DialogTrace), where each Dialog has a TreeView and 2 models(modelTree, modelTree2). These Dialogs display information coming from the same file logs. I am trying to move all the processing to a dedicate Thread that emits a <QStandartItem *> lst that contains each new row ready to be displayed on the different Dialogs.I have created a QList<DialogTrace *> ui_TraceNew; where each Item in the list is one of my Dialogs, this way I can connect the signal emitted by the Thread to each Dialog in the list . When I show() the dialogs they are independent objects as expected.
Now my problem. In order to connect the signal from the Thread to all the Dialogs in the ui_TraceNew list I wrote these connections:
connect(myTraceJob,&TraceJob::sendListItemMod1,ui_TraceNew.at(0),&DialogTrace::slotListItemMod1); connect(myTraceJob,&TraceJob::sendListItemMod2,ui_TraceNew.at(0),&DialogTrace::slotListItemMod2); connect(myTraceJob,&TraceJob::sendListItemMod1,ui_TraceNew.at(1),&DialogTrace::slotListItemMod1); connect(myTraceJob,&TraceJob::sendListItemMod2,ui_TraceNew.at(1),&DialogTrace::slotListItemMod2);
Here I just used row 0 and 1 directly to simplify but the issue is the same if I have more then 1 item in the list.
The slots in the DialogTrace are defined in this way:void DialogTrace::slotListItemMod1(int row,QList<QStandardItem *> lsta) {
modelTree->insertRow(row,lsta);
}void DialogTrace::slotListItemMod2(int row,QList<QStandardItem *> lstb) {
modelTree2->insertRow(row,lstb);
}When I run the application I have the following warning for each Item in each row :
QStandardItem::insertRows: Ignoring duplicate insertion of item...ui_TraceNew.at(0) displays all the items while ui_TraceNew.at(1) has added like.... "empty rows", no data.
I am sure I am missing something very obvious and I continue to work on it but I would appreciate if somebody can help on this.
-
Hi,
I have an application with a list of Dialogs(DialogTrace), where each Dialog has a TreeView and 2 models(modelTree, modelTree2). These Dialogs display information coming from the same file logs. I am trying to move all the processing to a dedicate Thread that emits a <QStandartItem *> lst that contains each new row ready to be displayed on the different Dialogs.I have created a QList<DialogTrace *> ui_TraceNew; where each Item in the list is one of my Dialogs, this way I can connect the signal emitted by the Thread to each Dialog in the list . When I show() the dialogs they are independent objects as expected.
Now my problem. In order to connect the signal from the Thread to all the Dialogs in the ui_TraceNew list I wrote these connections:
connect(myTraceJob,&TraceJob::sendListItemMod1,ui_TraceNew.at(0),&DialogTrace::slotListItemMod1); connect(myTraceJob,&TraceJob::sendListItemMod2,ui_TraceNew.at(0),&DialogTrace::slotListItemMod2); connect(myTraceJob,&TraceJob::sendListItemMod1,ui_TraceNew.at(1),&DialogTrace::slotListItemMod1); connect(myTraceJob,&TraceJob::sendListItemMod2,ui_TraceNew.at(1),&DialogTrace::slotListItemMod2);
Here I just used row 0 and 1 directly to simplify but the issue is the same if I have more then 1 item in the list.
The slots in the DialogTrace are defined in this way:void DialogTrace::slotListItemMod1(int row,QList<QStandardItem *> lsta) {
modelTree->insertRow(row,lsta);
}void DialogTrace::slotListItemMod2(int row,QList<QStandardItem *> lstb) {
modelTree2->insertRow(row,lstb);
}When I run the application I have the following warning for each Item in each row :
QStandardItem::insertRows: Ignoring duplicate insertion of item...ui_TraceNew.at(0) displays all the items while ui_TraceNew.at(1) has added like.... "empty rows", no data.
I am sure I am missing something very obvious and I continue to work on it but I would appreciate if somebody can help on this.
ok Update. I thought the problem was that the signals slotListItemMod1/2 passes a list of pointers to 2 or more objects....and then I add the same item (QStandardItem*) twice....so I have modified the slots this way:
void DialogTrace::slotListItemMod1(int row,QList<QStandardItem * > lsta) {
QList<QStandardItem * > lstatemp; QStandardItem *newP; foreach(QStandardItem *p,lsta){ newP = new QStandardItem(p->text()); lstatemp << newP; } modelTree->insertRow(row,lstatemp);
}
//same for the slotListItemMod2
Doing so I have the information displayed on both Dialogs and I don't have the warnings if I don't show the Dialogs(before the warnings where displayed when the model was updated even if the Dialogs were not shown).
I think I am getting close but still not enough. -
Hi,
What is happening is that you are trying to set the same item on two different models.
You should rather have your own object encapsulating the information you want to pass and build your items from them. So in the case you changes something like e.g. a QTreeView and a QStandardItemModel rather than a QTreeWidget, you can easily update your code.
-
Thanks, I am going to try this approach . My concern is that I wanted to give the Dialog the basic needed data as input for the model(item) to reduce processing in the main Thread.
Even using a dedicate Thread for all the processing data I still see that the Dialog Window moves very slowly when I drag it while I am updating the view,..so beside fixing the issue with the item/model updates I think there is something else to do on the TreeView itself, any suggestions?
I have already set:
ui->treeView->setUniformRowHeights(true); ui->treeView->setAnimated(false);
G.
-
How much data are we talking about ? At which speed ?
-
Ok, first of all, the first problem with the DIalogs(QStandardItem::insertRows: Ignoring duplicate insertion of item) is fixed , thanks for your suggestion it worked.
Now I can display the data correctly on the Dialogs w/o warnings.
For the second point and your questions. As expected the Dialog windows are still moving slowly...they move, it is not horrible but not smooth enough to be acceptable, no fast enough. I did some optimizations but now the bottle neck is the TreeView itself.
Your questions, the file I am using is a CANbus log.
The file has 40642 rows that should be displayed in 15seconds or faster(that is the realtime situation). Right now I have to delay the stream from the file otherwise the TreeView stucks until the end of the streaming, so, I use a QThread::usleep(1);
Doing so I can display the 40642 rows in 35 seconds. If I use QThread::msleep(1) the Dialogs become easier to move but it takes 55seconds to display all the rows.Any suggestions?
Thanks again.
-
Then you should rather build your own model and do batch inserts, adding items one by one is not the most efficient.
-
Ok I think we can consider this closed. I have built my own model as suggested. If somebody has the same need I had with Treeview timing...I suggest to subclass the QAbstractItemModel (see example http://doc.qt.digia.com/4.6/itemviews-simpletreemodel.html) . In the example all the data are provided to the constructor while I needed to populate data run-time(not big deal). Using your own model you can update the TreeView when you want and you do not have to do that every time an item is added to model(this was causing the problem). This way I was able to tune the right frequency to update the Treeview (I used a timer built in the model).
Thanks for the support.G.
-
You're welcome !
Since you have it working now, please update the thread title prepending [solved] so other forum users may know a solution has been found :)