Results 1 to 20 of 20

Thread: Has anyone done dynamic column spanning with a QTableWidget?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Nov 2008
    Posts
    183
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Has anyone done dynamic column spanning with a QTableWidget?

    I need to use QTableWidget to create what us old timers call a control break report. Yes, it has to be a table, not just a text thing or a list. There are other things we wish to be able to do and columns are a nice way of getting alignment across languages and fonts. The database has millions of rows and we will only display 30 or so at a time for obvious reasons. Since many of you reading this may be kids who never had a report writing or logic course I will try to draw it a bit here.


    some-long-multi-cell-here-which-repeats-occasionally
    xxxx xxxx xxxx xxxx xxxx xxxx xxxx
    xxxx xxxx xxxx xxxx
    xxxx xxxx xxxx xxxx
    xxxx xxxx xxxx xxxx xxxx xxxx
    xxxx xxxx xxxx xxxx
    xxxx xxxx xxxx xxxx xxxx xxxx xxxx

    I don't believe the empty cells will be a problem given a custom model. I'm trying to avoid having to do a custom item delegate just to get that dynamic cell spanning though. Any ideas?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    If you're using a custom model, then you want QTableView, not QTableWidget, no?

    Could you not reimplement QAbstractItemModel::span() to do this? (Duh, I should RTFM - "Note: Currently, span is not used." That's exactly what you need).

    What you're asking for sort of breaks the model / view separation. I think you might be able to accomplish what you want by implementing a signal in a custom model that is emitted whenever the Qt::DisplayRole is requested for one of these header row indexes in the QAbstractTableModel::data() method. The widget that contains your QTableView could listen for this signal and set the column span appropriately.

    Something like:

    Qt Code:
    1. QVariant MyCustomModel::data( const QModelIndex & index, int role )
    2. {
    3. if ( Qt::DisplayRole == role )
    4. {
    5. v = "whatever";
    6. if ( indexIsAHeaderRow( index ) )
    7. emit setColumnSpanForHeaderRow( index.row(), index.column() );
    8. }
    9. return v;
    10. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Nov 2008
    Posts
    183
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    Quote Originally Posted by d_stranz View Post
    If you're using a custom model, then you want QTableView, not QTableWidget, no?

    Could you not reimplement QAbstractItemModel::span() to do this? (Duh, I should RTFM - "Note: Currently, span is not used." That's exactly what you need).

    What you're asking for sort of breaks the model / view separation. I think you might be able to accomplish what you want by implementing a signal in a custom model that is emitted whenever the Qt::DisplayRole is requested for one of these header row indexes in the QAbstractTableModel::data() method. The widget that contains your QTableView could listen for this signal and set the column span appropriately.

    Something like:

    Qt Code:
    1. QVariant MyCustomModel::data( const QModelIndex & index, int role )
    2. {
    3. if ( Qt::DisplayRole == role )
    4. {
    5. v = "whatever";
    6. if ( indexIsAHeaderRow( index ) )
    7. emit setColumnSpanForHeaderRow( index.row(), index.column() );
    8. }
    9. return v;
    10. }
    To copy to clipboard, switch view to plain text mode 

    Thanks. I will give it a whirl. Yes, I meant View. Shouldn't type posts first thing Sunday morning I guess.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    In my opinion the proper way to solve the problem is to implement a custom view based on QTableView. Could be that it is enough to just reimplement visualRect() so that it takes into consideration "dynamic spanning" needs of the model.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    Hmm, might work. I suppose it depends on whether the table draws the grid lines before or after the cell contents, and if the grid is drawn first, on whether the painting clears the visual rect before painting it with its contents. This would be a good excuse to implement the span() method in the model.

    Documentation of QTableView::visualRect() seems to be missing from the Qt 5.2 docs, even though as a pure virtual method in QAbstractItemView it has to be implemented in QTableView.
    Last edited by d_stranz; 20th October 2014 at 20:50.

  6. #6
    Join Date
    Sep 2014
    Posts
    27
    Thanks
    2
    Thanked 2 Times in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    I was able to accomplish this in 2 parts.
    First, I implemented span() for my model, which would look something like this:
    Qt Code:
    1. QSize MyModel::span(QModelIndex index) {
    2. if(isSpanningColumn(index)) {
    3. return QSize(spanAmount, 1);
    4. }
    5. return QSize(1, 1);
    6. }
    To copy to clipboard, switch view to plain text mode 

    Then I reimplemented the setModel() method in my view:
    Qt Code:
    1. void MyTableView::setModel(QAbstractItemModel* model){
    2. QTableView::setModel(model);
    3. for(int col = 0; col < model->columnCount(); col++){
    4. for (int row = 0; row < model->rowCount(); row++){
    5. QSize span = model->span(model->index(row, col));
    6. if(span != QSize(1,1)) //Preform this check so you don't get a bunch of warnings about setting a span of 1 being ignored
    7. setSpan(row, col, span.height(), span.width());
    8. }
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 

    I hope that helps

  7. #7
    Join Date
    Nov 2008
    Posts
    183
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default SOLVED: Has anyone done dynamic column spanning with a QTableWidget?

    Thanks to all who replied. I ended up using the solution provided by d_stranz today. Here is a side note though. I found this out completely by accident since I put a debug print in the slot.

    The view/model in Qt 4.8.x (and probably 5.x as well) is a vicious CPU squanderer. When I was poking through the doc I wondered why there were no signals going from the model which could be caught by the view indicating cell(x,y) had changed. In part I guess this was due to my confusion about the infintesimally small lifespan of QModelIndex. After stumbling on this with my slot I put a debug print in ::data() of the model to verify.

    The reason we have no signals for data changes is because the view goes into an infinite loop of fetching data from the model for all visible cells. This seems to be SO not Qt. The model should have signal(s) which get emitted when data has changed and the view using the model should catch those. If you pull up something static, such as an XML or spreadsheet file, or a periscope over a section of database tables, the displayed data will not change, but the view will sit there sucking the battery life out of every device.

    Now I need to figure out how to mark this as solved.

    Thanks again.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: SOLVED: Has anyone done dynamic column spanning with a QTableWidget?

    Quote Originally Posted by RolandHughes View Post
    The reason we have no signals for data changes (...)
    We don't? What is QAbstractItemModel::dataChanged() then?

    (...) because the view goes into an infinite loop of fetching data from the model for all visible cells.
    Infinite loop? Have you verified properly that what you say was true? I'm sure it is not for a regular table with a regular delegate and a regular model. If you get such behavior then you probably introduced the loop yourself.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Nov 2008
    Posts
    183
    Thanks
    13
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    I emailed several others and they conducted their own tests with their own code and got the same results. We didn't share any code. Just be sure to use the tableview with the abstract table model when you conduct your test.

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Has anyone done dynamic column spanning with a QTableWidget?

    Quote Originally Posted by RolandHughes View Post
    I emailed several others and they conducted their own tests with their own code and got the same results. We didn't share any code.
    Well, apparently you all got wrong results.

    Qt Code:
    1. #include <QtGui>
    2.  
    3. class Model : public QAbstractTableModel {
    4. public:
    5. Model() {}
    6. int rowCount(const QModelIndex &parent = QModelIndex()) const {
    7. if(parent.isValid()) return 0;
    8. return 1;
    9. }
    10. int columnCount(const QModelIndex &parent = QModelIndex()) const { return 1; }
    11.  
    12. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
    13. Q_UNUSED(index);
    14. if(role != Qt::DisplayRole) return QVariant();
    15. qDebug() << Q_FUNC_INFO;
    16. return "A";
    17. }
    18. };
    19.  
    20. int main(int argc, char **argv) {
    21. QApplication app(argc, argv);
    22. Model model;
    23. QTableView view;
    24. view.setModel(&model);
    25. view.show();
    26. return app.exec();
    27. }
    To copy to clipboard, switch view to plain text mode 

    This test application clearly indicates there is no loop. If you want you can even disrupt the dataChanged() signal connection, modify the model and see that the view doesn't update until something else forces the view to ask explicitly for the item data.

    I do agree though that the default table view and the default delegate read the model data more than one time. This is probably related to auto-sizing columns and rows but this is only my guess.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QTableWidget : dynamic colomn size
    By ArnaudC in forum Qt Programming
    Replies: 0
    Last Post: 11th September 2013, 14:44
  2. Dynamic sorting using proper column after adding a row.
    By kremuwa in forum Qt Programming
    Replies: 1
    Last Post: 28th September 2010, 23:50
  3. Dynamic Sizing of QTableView Column Widths
    By tntcoda in forum Qt Programming
    Replies: 1
    Last Post: 17th June 2009, 18:30
  4. spanning in QTableWidget acting weird
    By ferrari in forum Qt Programming
    Replies: 0
    Last Post: 15th October 2008, 11:31
  5. Replies: 6
    Last Post: 5th March 2006, 21:05

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.