Answer the question
In order to leave comments, you need to log in
Qt QTreeView group highlighting checkbox items by itemChanged?
Good afternoon!
The essence of the question is this: there was a QTreeWidget - a good high-level class for working with a tree in the UI. Everything was fine. But it was necessary to make multithreading in the application so that the user does not see how the application "hangs" while doing work, but sees something like a progress bar, etc. - in general, one UI thread, one data processing.
Unfortunately, I don't know if it's possible to send QTreeWidgetItem* items from another thread (not ui). The matter is that at creation, QTreeWidgetItem* demands to specify parent item, ie. element in a UI QTreeWidget. The data stream, of course, does not know about it. Is it possible to create a "tree" QTreeWidgetItems that is not attached to the ui? I did not find such a way, so I had to use QTreeView:
There is a code that worked in QTreeWidget and should work in QTreeView - or rather its "model" part - QStandardItem*:
Qt::CheckState state = item->checkState();
if ( state == Qt::Checked || state == Qt::Unchecked ) {
for ( int i = 0; i < item->rowCount(); i++ ) {
QStandardItem* child = item->child(i);
if ( child->isCheckable() && child->checkState() != state )
child->setCheckState(state);
}
}
QStandardItem* parent = item->parent();
if ( parent && parent->isCheckable() ) {
state = parent->child(0)->checkState();
if ( state == Qt::PartiallyChecked )
parent->setCheckState( state );
else {
int i = 1;
while ( i < parent->rowCount() && parent->child(i)->checkState() == state )
i++;
if ( i != parent->rowCount() )
state = Qt::PartiallyChecked;
parent->setCheckState( state );
}
}
QStandardItemModel* model = new QStandardItemModel;
QStandardItem* parentItem = model->invisibleRootItem();
QList<QStandardItem*> itemList1;
QList<QStandardItem*> itemList2;
QList<QStandardItem*> itemList3;
QStandardItem* item1 =new QStandardItem;
QStandardItem* item2 =new QStandardItem;
QStandardItem* item3 =new QStandardItem;
for(;;) // example
{
QStandardItem* item1 =new QStandardItem(LPCWSTR2QString(mbxItem->Text));
item1->setToolTip(QString::fromStdWString(itemPath0.bstrVal));
item1->setFlags(item1->flags() | Qt::ItemIsUserCheckable);
item1->setCheckState(Qt::Unchecked);
itemList1 << item1;
}
parentItem->appendRows(itemList1);
itemList1.clear();
// и т.д. - всего три вложенных списка, отображается модель нормально
ui.treeView->setModel(model);
// и коннект:
QStandardItemModel* model = read2UI();
bool ok = connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(onItemChanged(QStandardItem*)));
Q_ASSERT(ok);
update(model);
QList<QTreeWidgetitem*>
from the thread that works with the data to the UI thread? (I don't want to "re-implement" the standard behavior for QTreeView). treeView->appendRows(QList<QStandardItem*>).
Answer the question
In order to leave comments, you need to log in
Issue resolved.
The thing is that in qt you need to add items to the parent on each "iteration", and not a list.
Those. create a model
parentItem->appendRows(itemList1);, and so:
for (int i = 0; i < 3; ++i)
{
item1 = new QStandardItem;
item1->setText("item1-" + QString::number(i));
parentItem->appendRow(item1);
for (int i = 0; i < 3; ++i)
{
item2 = new QStandardItem;
item2->setText("item2-" + QString::number(i));
item1->appendRow(item2);
for (int i = 0; i < 3; ++i)
{
item3 = new QStandardItem;
item3->setText("item3-" + QString::number(i));
item2->appendRow(item3);
}
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question