Results 1 to 14 of 14

Thread: Advanced QTableView

  1. #1
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question Advanced QTableView

    Hi all,

    I'm trying to create an "extended" QTableView that has some useful features for me : a footer row, like the header, but in the bottom ( for column summary, counter, .. ) and a "banded header" ( in top of column headers, grouping columns in logical blocks ).

    I'm trying this ExtendedView header & footer to be similar in aspect to band header & footer of ExpressQuantumGrid from www.devexpress.com ( http://www.devexpress.com/Products/VCL/ExQuantumGrid/ )

    I thought 2 possible solutions :

    - Copy & Paste QTableView/QHeaderView QT Code & modify to achieve this behaviour ( I've been looking QT code and it seems is like putting "my parts" in a wasp's nest... ) So I discarded ( by now ) this one.

    - The easiest one for me : Create a new QExtendedTableView, subclassing QWidget and putting inside a QVBoxLayout containing a fixed height QHeaderView ( top header ), the central QTableView and a QHeaderView ( Footer ). Models are not a problem, I've solved this part yet ( the 3 widgets show correctly their own data )

    But band header & footer ignore my atempts to move them as if they were part of the grid. I've tried some "hacks" but I've the following problems :

    - Header/Footer does'nt follow my model SizeHints ( all columns in header & footer are allways shown with their default width ). Anyway, the models take column info from the same source of the grid, so MUST have the same sizes.

    - How do i make scroll those header/footer at the same time the TableView scrolls ?

    - How can I handle the propagation of grid's column resizing to band header & footer. And of course, band resizing must affect table header & footer...

    Anybody can give me orientation ?

  2. #2
    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: Advanced QTableView

    Quote Originally Posted by jpujolf View Post
    - Copy & Paste QTableView/QHeaderView QT Code & modify to achieve this behaviour ( I've been looking QT code and it seems is like putting "my parts" in a wasp's nest... )
    It's practically impossible to do that because of the use of PIMPLs by Qt widgets.

    - The easiest one for me : Create a new QExtendedTableView, subclassing QWidget and putting inside a QVBoxLayout containing a fixed height QHeaderView ( top header ), the central QTableView and a QHeaderView ( Footer ). Models are not a problem, I've solved this part yet ( the 3 widgets show correctly their own data )
    Not the best idea, you'll be practically reimplementing the whole view interface.

    Why not try another approach - simply insert a second header view in the layout of the view just under the viewport?

    But band header & footer ignore my atempts to move them as if they were part of the grid. I've tried some "hacks" but I've the following problems :
    You can always hide them...


    - Header/Footer does'nt follow my model SizeHints ( all columns in header & footer are allways shown with their default width ). Anyway, the models take column info from the same source of the grid, so MUST have the same sizes.
    I'm not sure (you can verify that by looking into Qt sources), but I think you should calculate section sizes yourself according to the width of columns.

    - How do i make scroll those header/footer at the same time the TableView scrolls ?
    Signals & slots.

    - How can I handle the propagation of grid's column resizing to band header & footer. And of course, band resizing must affect table header & footer...
    Signals & slots again...

  3. #3
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Post Re: Advanced QTableView

    Quote Originally Posted by wysota View Post
    It's practically impossible to do that because of the use of PIMPLs by Qt widgets.
    PIMPLs ?? What do you mean. I've looked inside and it's difficult, so it's my last option... ( but you can never say is impossible... )

    Not the best idea, you'll be practically reimplementing the whole view interface.
    I disagree. I don't need ALL the interface. I f you do something like this, you have all the interface, but are allways maintaining it as a single Widget :

    Qt Code:
    1. MTableView::MTableView ( QWidget * parent ) : QWidget ( parent )
    2. {
    3. // 3 parts : TOP, CENTRAL & FOOTER
    4. QVBoxLayout * vboxLayout = new QVBoxLayout ( this );
    5. vboxLayout->setSpacing(0);
    6. vboxLayout->setMargin(0);
    7. vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
    8.  
    9. // TOP : Band headers
    10. QHeaderView * tTopBand = new QHeaderView ( Qt::Horizontal, this );
    11. tTopBand->setObjectName ( QString::fromUtf8 ( MTable_TOPBAND ) );
    12. tTopBand->setMinimumHeight ( 20 );
    13. tTopBand->setMaximumHeight ( 20 );
    14. QSizePolicy spTop ( QSizePolicy::Expanding, QSizePolicy::Fixed );
    15. spTop.setHorizontalStretch(0);
    16. spTop.setVerticalStretch(0);
    17. tTopBand->setSizePolicy ( spTop );
    18. vboxLayout->addWidget ( tTopBand );
    19.  
    20. // CENTRAL : Data & column headers
    21. QTableView * tMainGrid = new QTableView ( this );
    22. tMainGrid->setObjectName ( QString::fromUtf8 ( MTable_CENTRAL ) );
    23. QSizePolicy spCentral ( QSizePolicy::Expanding, QSizePolicy::Expanding );
    24. spCentral.setHorizontalStretch(0);
    25. spCentral.setVerticalStretch(0);
    26. tMainGrid->setSizePolicy ( spCentral );
    27. vboxLayout->addWidget ( tMainGrid );
    28.  
    29. tMainGrid->setSelectionBehavior ( QAbstractItemView::SelectRows );
    30. tMainGrid->setSelectionMode ( QAbstractItemView::SingleSelection );
    31.  
    32. tMainGrid->verticalHeader()->setDefaultSectionSize ( 20 );
    33. tMainGrid->verticalHeader()->setMinimumSectionSize ( 20 );
    34. tMainGrid->horizontalHeader()->setDefaultSectionSize ( 120 );
    35. tMainGrid->horizontalHeader()->setMinimumSectionSize ( 20 );
    36.  
    37. // FOOTER : Summary @ column footers
    38. QHeaderView * tFooter = new QHeaderView ( Qt::Horizontal, this );
    39. tFooter->setObjectName ( QString::fromUtf8 ( MTable_FOOTER ) );
    40. tFooter->setMinimumHeight ( 20 );
    41. tFooter->setMaximumHeight ( 20 );
    42. QSizePolicy spFooter ( QSizePolicy::Expanding, QSizePolicy::Fixed );
    43. spFooter.setHorizontalStretch(0);
    44. spFooter.setVerticalStretch(0);
    45. tFooter->setSizePolicy ( spFooter );
    46. vboxLayout->addWidget ( tFooter );
    47.  
    48. // connections
    49. connect ( tMainGrid->horizontalHeader(), SIGNAL(sectionResized(int,int,int)) ,
    50. tTopBand, SLOT(resizeSection(int,int,int)));
    51. connect ( tMainGrid->horizontalHeader(), SIGNAL(sectionResized(int,int,int)) ,
    52. tFooter , SLOT(resizeSection(int,int,int)));
    53. }
    To copy to clipboard, switch view to plain text mode 

    I only need that the improved table acts as a single widget, allowing the final developer to easily create layouts with the designer & then having a richer table in his project.

    Why not try another approach - simply insert a second header view in the layout of the view just under the viewport?
    Well. I'm working this way because I'm creating a complex framework that loads .ui files, changing QTableView elements by "MTableView" ( my class ). I use inside my app this class and I can assume has an smaller interface.

    You can always hide them...
    Why I must hide a compoenent I'm fighting to show ? I want to show this :

    - 1 horizontal "band header" ( each band contains 1 or more columns grouped ) BEFORE the table header
    - The QTableView itself ( column headers & data )
    - 1 table footer, for summarys. I can assume the scroll bar is between data & footer, by now it's not a problem.

    I'm not sure (you can verify that by looking into Qt sources), but I think you should calculate section sizes yourself according to the width of columns.
    OK, I agree too, but I must receive some signals when column header change thier size, and I don't receive nothing.

    - How can I handle the propagation of grid's column resizing to band header & footer. And of course, band resizing must affect table header & footer...

    Signals & slots again...
    OK, but which signals ?? I've tried some combinations and I'm receiving no one...

    Thanks

  4. #4
    Join Date
    Jan 2006
    Location
    Cambridge, MA
    Posts
    32
    Thanked 7 Times in 6 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Advanced QTableView

    For the features you want take a look at QicsTable by ICS. Its a source licensed commercial product, but it will save you a lot of time. Its stupports all the features you mention and its made for subclassing and extension.

    http://www.ics.com/support/docs/qicstableapi/index.html

    www.ics.com/qt

    --Justin

  5. #5
    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: Advanced QTableView

    Quote Originally Posted by jpujolf View Post
    PIMPLs ?? What do you mean.
    Private implementations. All the Q***Private classes.

    I've looked inside and it's difficult, so it's my last option... ( but you can never say is impossible... )
    I can say it's impossible, PIMPLs are not part of the public API, so you'd have to embed half of Qt code into your widget and I don't think you want a widget with 3MB legacy in it

    I disagree. I don't need ALL the interface. I f you do something like this, you have all the interface, but are allways maintaining it as a single Widget :
    Well said - a widget, but not as a view. The view API is not part of the public API of the widget, so you can't make simple signal-slot connections or use the widget as a custom widget in Designer without messing around with its internals.

    I only need that the improved table acts as a single widget, allowing the final developer to easily create layouts with the designer & then having a richer table in his project.
    As written above, the widget will not have the API of a view, so the final developer will only have access to its QWidget API from the Designer (unless you forward all the view functionality to the widget's public API practically reimplementing the view architecture, as I mentioned in the previous post).

    Why I must hide a compoenent I'm fighting to show ?
    I understood you want to replace the original header view with your own header and footer. Hiding the original header would be a simple way to get rid of it. Maybe I misunderstood you.

    OK, I agree too, but I must receive some signals when column header change thier size, and I don't receive nothing.

    OK, but which signals ?? I've tried some combinations and I'm receiving no one...
    QHeaderView::sectionResized() is an obvious candidate...
    Last edited by wysota; 18th December 2006 at 21:47.

  6. The following user says thank you to wysota for this useful post:

    jpujolf (19th December 2006)

  7. #6
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Advanced QTableView

    Hi all,

    Finally I didi it !! I want to post here, the connections and simple code I wrote to obtain the result I was asking for. If somebody has the same problem, perhaps can be a guide.

    Qt Code:
    1. MTableView::MTableView ( QWidget * parent ) : QWidget ( parent )
    2. {
    3. m_LeftOffset = -12;
    4. m_bResizing = false;
    5.  
    6. // 3 items : TOP BAND HEADER, CENTRAL GRID & BOTTOM FOOTER
    7. QVBoxLayout * vboxLayout = new QVBoxLayout ( this );
    8. vboxLayout->setSpacing(0);
    9. vboxLayout->setMargin(0);
    10. vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
    11.  
    12. // TOP : Band headers
    13. QHeaderView * tTopBand = new QHeaderView ( Qt::Horizontal, this );
    14. tTopBand->setObjectName ( QString::fromUtf8 ( MTable_TOPBAND ) );
    15. tTopBand->setMinimumHeight ( 20 );
    16. tTopBand->setMaximumHeight ( 20 );
    17. tTopBand->setOffset ( m_LeftOffset );
    18. QSizePolicy spTop ( QSizePolicy::Expanding, QSizePolicy::Fixed );
    19. spTop.setHorizontalStretch(0);
    20. spTop.setVerticalStretch(0);
    21. tTopBand->setSizePolicy ( spTop );
    22. vboxLayout->addWidget ( tTopBand );
    23.  
    24. // CENTRAL : Data & column headers
    25. QTableView * tMainGrid = new QTableView ( this );
    26. tMainGrid->setObjectName ( QString::fromUtf8 ( MTable_CENTRAL ) );
    27. QSizePolicy spCentral ( QSizePolicy::Expanding, QSizePolicy::Expanding );
    28. spCentral.setHorizontalStretch(0);
    29. spCentral.setVerticalStretch(0);
    30. tMainGrid->setSizePolicy ( spCentral );
    31. vboxLayout->addWidget ( tMainGrid );
    32.  
    33. tMainGrid->setSelectionBehavior ( QAbstractItemView::SelectRows );
    34. tMainGrid->setSelectionMode ( QAbstractItemView::SingleSelection );
    35. tMainGrid->verticalHeader()->setDefaultSectionSize ( 20 );
    36. tMainGrid->verticalHeader()->setMinimumSectionSize ( 20 );
    37. tMainGrid->horizontalHeader()->setDefaultSectionSize ( 120 );
    38. tMainGrid->horizontalHeader()->setMinimumSectionSize ( 20 );
    39. tMainGrid->setVerticalScrollMode ( QAbstractItemView::ScrollPerPixel );
    40.  
    41. // FOOTER : Summay @ column footers
    42. QHeaderView * tFooter = new QHeaderView ( Qt::Horizontal, this );
    43. tFooter->setObjectName ( QString::fromUtf8 ( MTable_FOOTER ) );
    44. tFooter->setMinimumHeight ( 20 );
    45. tFooter->setMaximumHeight ( 20 );
    46. tFooter->setOffset ( m_LeftOffset );
    47. tFooter->setResizeMode ( QHeaderView::Fixed );
    48. QSizePolicy spFooter ( QSizePolicy::Expanding, QSizePolicy::Fixed );
    49. spFooter.setHorizontalStretch(0);
    50. spFooter.setVerticalStretch(0);
    51. tFooter->setSizePolicy ( spFooter );
    52. vboxLayout->addWidget ( tFooter );
    53.  
    54. connect ( tMainGrid->horizontalHeader(), SIGNAL(sectionResized(int,int,int)),
    55. this, SLOT(SectionResized(int,int,int)) );
    56. connect ( tMainGrid->horizontalHeader(), SIGNAL(sectionAutoResize(int,QHeaderView::ResizeMode)) ,
    57. this, SLOT(SectionAutoResize(int,QHeaderView::ResizeMode)) );
    58.  
    59. connect ( tTopBand, SIGNAL(sectionResized(int,int,int)), this, SLOT(BandSectionResized(int,int,int)) );
    60. connect ( tMainGrid->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(ScrollHorizontal(int)) );
    61. }
    62.  
    63. void MTableView::BandSectionResized ( int logicalIndex, int /* oldSize */, int newSize )
    64. {
    65. if ( m_bResizing ) return;
    66. m_bResizing = true;
    67. QHeaderView * pTabHeader = this->GetMainGrid()->horizontalHeader();
    68. pTabHeader->resizeSection ( logicalIndex, newSize );
    69. m_bResizing = false;
    70. }
    71.  
    72. void MTableView::SectionResized ( int logicalIndex, int /* oldSize */, int newSize )
    73. {
    74. QHeaderView * pHeader = qFindChild<QHeaderView *> ( this, MTable_TOPBAND );
    75. pHeader->resizeSection ( logicalIndex, newSize );
    76. pHeader = qFindChild<QHeaderView * > ( this, MTable_FOOTER );
    77. pHeader->resizeSection ( logicalIndex, newSize );
    78. }
    79. void MTableView::SectionAutoResize ( int logicalIndex, QHeaderView::ResizeMode /* mode */ )
    80. {
    81. QHeaderView * pTabHeader = this->GetMainGrid()->horizontalHeader();
    82. QHeaderView * pHeader = qFindChild<QHeaderView *> ( this, MTable_TOPBAND );
    83. pHeader->resizeSection ( logicalIndex, pTabHeader->sectionSize ( logicalIndex ) );
    84. pHeader = qFindChild<QHeaderView * > ( this, MTable_FOOTER );
    85. pHeader->resizeSection ( logicalIndex, pTabHeader->sectionSize ( logicalIndex ) );
    86. }
    87.  
    88. void MTableView::ScrollHorizontal ( int /* scrollValue */ )
    89. {
    90. QHeaderView * pTabHeader = this->GetMainGrid()->horizontalHeader();
    91. QHeaderView * pHeader = qFindChild<QHeaderView *> ( this, MTable_TOPBAND );
    92. pHeader->setOffset ( pTabHeader->offset() + m_LeftOffset );
    93. pHeader = qFindChild<QHeaderView * > ( this, MTable_FOOTER );
    94. pHeader->setOffset ( pTabHeader->offset() + m_LeftOffset );
    95. }
    To copy to clipboard, switch view to plain text mode 

    And that's all, I have now a widget that simulates the grid I needed. I can access programmatically to the "real" grid, the band header & the footer, but all the stuff for resizing/ scrolling automation is done. That was my problem.

    I think that complex problems must be solved at morning. After lunch, the brain becomes a bit lazy .

    Now I have to make little changes to span "header band" columns and take m_LeftOffset value directly from table ( this value is, by now, hard coded, but could change ).

    When I finish all the stuff, I will attach an screenshot, to show you the results. Cheers !!

    Jordi.
    Last edited by jpujolf; 19th December 2006 at 12:24. Reason: spelling error

  8. The following user says thank you to jpujolf for this useful post:

    heddev (5th April 2013)

  9. #7
    Join Date
    Jul 2006
    Location
    Catalunya - Spain
    Posts
    117
    Thanks
    16
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Advanced QTableView

    The promised Screenshot of improved table.
    Attached Images Attached Images

  10. #8
    Join Date
    Aug 2006
    Location
    Germany
    Posts
    15
    Thanks
    1
    Thanked 3 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Advanced QTableView

    hi jpujolf,

    that looks good. Could you show more code of the class?
    I know its some time ago since you posted your work here.

    thank you in advance!

  11. #9
    Join Date
    Oct 2009
    Location
    Vienna, Austria
    Posts
    57
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Advanced QTableView

    Quote Originally Posted by wysota View Post
    Well said - a widget, but not as a view. The view API is not part of the public API of the widget, so you can't make simple signal-slot connections or use the widget as a custom widget in Designer without messing around with its internals.
    As written above, the widget will not have the API of a view, so the final developer will only have access to its QWidget API from the Designer (unless you forward all the view functionality to the widget's public API practically reimplementing the view architecture, as I mentioned in the previous post).
    QHeaderView::sectionResized() is an obvious candidate...
    What are then the alternatives to implement a footer row?

  12. #10
    Join Date
    Feb 2010
    Location
    Sydney, Australia
    Posts
    111
    Thanks
    18
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Advanced QTableView

    HierarchicalHeaderView 1.3.2 might be worth a look. I haven't used it or looked a the code though - just came across it and remembered this post.

  13. #11
    Join Date
    Oct 2009
    Location
    Vienna, Austria
    Posts
    57
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Advanced QTableView

    Quote Originally Posted by stefanadelbert View Post
    HierarchicalHeaderView 1.3.2 might be worth a look. I haven't used it or looked a the code though - just came across it and remembered this post.
    I checked it and as far as I can see it does not cover how to implement a footer line.

  14. #12
    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: Advanced QTableView

    You have to place the footer manually in the view. QAbstractScrollArea::setViewportMargins() can be helpful with doing that.

  15. #13
    Join Date
    Oct 2009
    Location
    Vienna, Austria
    Posts
    57
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Advanced QTableView

    Quote Originally Posted by wysota View Post
    You have to place the footer manually in the view. QAbstractScrollArea::setViewportMargins() can be helpful with doing that.
    Is there any code example available on how to do this?

  16. #14
    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: Advanced QTableView

    Quote Originally Posted by doberkofler View Post
    Is there any code example available on how to do this?
    I'll try to come up with an example later today.

  17. The following user says thank you to wysota for this useful post:

    doberkofler (19th April 2010)

Similar Threads

  1. Set height of QTableView to fit exact number of rows.
    By Ben.Hines in forum Qt Programming
    Replies: 3
    Last Post: 17th January 2019, 01:49
  2. QTableView sorting
    By gabriels in forum Qt Programming
    Replies: 11
    Last Post: 6th October 2010, 17:13
  3. QTableView currentChanged <> selecting header
    By Everall in forum Qt Programming
    Replies: 4
    Last Post: 1st April 2009, 08:24
  4. QTableView paints too much
    By Jimmy2775 in forum Qt Programming
    Replies: 2
    Last Post: 26th July 2006, 18:42
  5. Multi-line messages in QTableView
    By Conel in forum Qt Programming
    Replies: 6
    Last Post: 13th April 2006, 13:49

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.