Reading QTableView row contents with the same order as are seen NOT stored
-
wrote on 23 Jan 2017, 11:28 last edited by alizadeh91
We have a QTableView which are filled with some arbitrary data. User can move rows of the table internally by drag and drop.
We want to read cell contents in the same order as are seen in the QTableView (as seen in the view NOT stored in the model). Currently by calling model->data() we access the cell contents as are stored in the model NOT as seen in the view (ordered are changed by row internal moves).
How is it possible to read cell contents such this way?
-
wrote on 23 Jan 2017, 11:54 last edited by
QTableWidget inherits QTableView so they are the same thing. I believe accessing the
model()
of QTableWidget is what you want -
QTableWidget inherits QTableView so they are the same thing. I believe accessing the
model()
of QTableWidget is what you wantwrote on 23 Jan 2017, 12:01 last edited by@VRonin The model is not in the same order as view (row orders are changed in view by drag-drop). So, I need a way to read values with same order as QTableWidget.
-
Hi,
The model content should have been moved following your drag & drop action so @VRonin is right.
-
Hi,
The model content should have been moved following your drag & drop action so @VRonin is right.
wrote on 23 Jan 2017, 14:00 last edited by@SGaist No, By internal moves between rows in table, the model content is not changed and only the view content is changed.
-
@SGaist No, By internal moves between rows in table, the model content is not changed and only the view content is changed.
wrote on 23 Jan 2017, 14:06 last edited byactually the model is not affected by reordering by internal moves in the view
-
wrote on 23 Jan 2017, 14:47 last edited by VRonin
The model is affected indeed, try this one, it works for me:
#include <QApplication> #include <QTableWidget> #include <QDebug> #include <QVBoxLayout> #include <QPushButton> int main(int argc, char* argv[]) { QApplication a(argc, argv); QWidget base; QTableWidget* tablWid = new QTableWidget(&base); tablWid->setDragDropMode(QAbstractItemView::InternalMove); ////////////////////////////////////////////////////////////////////////// // Fill the model with some data tablWid->model()->insertColumn(0); tablWid->model()->insertRows(0,10); for (int i = 0; i < 10; ++i) tablWid->model()->setData(tablWid->model()->index(i, 0), "Item " + QString::number(i)); ////////////////////////////////////////////////////////////////////////// QPushButton* dumpButton = new QPushButton("Dump Model", &base); QObject::connect(dumpButton, &QPushButton::clicked, [tablWid]()->void { for (int j = 0; j < tablWid->model()->rowCount();++j){ qDebug() << tablWid->model()->index(j, 0).data().toString(); } }); QVBoxLayout* baseLay = new QVBoxLayout(&base); baseLay->addWidget(tablWid); baseLay->addWidget(dumpButton); base.show(); return a.exec(); }
-
The model is affected indeed, try this one, it works for me:
#include <QApplication> #include <QTableWidget> #include <QDebug> #include <QVBoxLayout> #include <QPushButton> int main(int argc, char* argv[]) { QApplication a(argc, argv); QWidget base; QTableWidget* tablWid = new QTableWidget(&base); tablWid->setDragDropMode(QAbstractItemView::InternalMove); ////////////////////////////////////////////////////////////////////////// // Fill the model with some data tablWid->model()->insertColumn(0); tablWid->model()->insertRows(0,10); for (int i = 0; i < 10; ++i) tablWid->model()->setData(tablWid->model()->index(i, 0), "Item " + QString::number(i)); ////////////////////////////////////////////////////////////////////////// QPushButton* dumpButton = new QPushButton("Dump Model", &base); QObject::connect(dumpButton, &QPushButton::clicked, [tablWid]()->void { for (int j = 0; j < tablWid->model()->rowCount();++j){ qDebug() << tablWid->model()->index(j, 0).data().toString(); } }); QVBoxLayout* baseLay = new QVBoxLayout(&base); baseLay->addWidget(tablWid); baseLay->addWidget(dumpButton); base.show(); return a.exec(); }
wrote on 24 Jan 2017, 05:27 last edited by@VRonin Sorry, I've meant to move sections (vertical header) so change the code this way:
#include <QApplication> #include <QTableWidget> #include <QDebug> #include <QVBoxLayout> #include <QPushButton> #include <QHeaderView> int main(int argc, char* argv[]) { QApplication a(argc, argv); QWidget base; QTableWidget* tablWid = new QTableWidget(&base); // tablWid->setDragDropMode(QAbstractItemView::InternalMove); tablWid->verticalHeader()->setSectionsMovable(true); tablWid->verticalHeader()->setDragEnabled(true); ////////////////////////////////////////////////////////////////////////// // Fill the model with some data tablWid->model()->insertColumn(0); tablWid->model()->insertRows(0,10); for (int i = 0; i < 10; ++i) tablWid->model()->setData(tablWid->model()->index(i, 0), "Item " + QString::number(i)); ////////////////////////////////////////////////////////////////////////// QPushButton* dumpButton = new QPushButton("Dump Model", &base); QObject::connect(dumpButton, &QPushButton::clicked, [tablWid]()->void { for (int j = 0; j < tablWid->model()->rowCount();++j){ qDebug() << tablWid->model()->index(j, 0).data().toString(); } }); QVBoxLayout* baseLay = new QVBoxLayout(&base); baseLay->addWidget(tablWid); baseLay->addWidget(dumpButton); base.show(); return a.exec(); }
Now, by moving vertical sections (reordering rows), the model is not affected by reordered rows.
-
wrote on 24 Jan 2017, 10:28 last edited by VRonin
this should return the list of the row indexes as sorted in the view. Hidden rows will be placed at the beginning
QList<int> viewIndexes(const QHeaderView* const view){ if(!view) return QList<int>(); const int numSections= view->count(); QMap<int,int> sorter; for(int i=0;i<numSections;++i) sorter.insert(view->sectionPosition(i),i); return sorter.values(); }
or alternatively:
QVector<int> viewIndexes(const QHeaderView* const view){ if(!view) return QVector<int>(); const int numSections=view->count(); QVector<int> result(numSections); for(int i=0;i<numSections;++i) result[i]=i; // Use stable_sort if you want the hidden sections still placed at the beginning but in the same order as the original model std::sort(result.begin(),result.end(),[view](int a,int b)->bool{return view->sectionPosition(a)<view->sectionPosition(b);}); return result; }
You'll have to benchmark them to tell which is more efficient
7/9