Results 1 to 10 of 10

Thread: QTableWidget NW corner header item?

  1. #1
    Join Date
    Oct 2006
    Location
    Massachusetts, USA
    Posts
    19
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Question QTableWidget NW corner header item?

    Embarassing to ask, but how would I access the top left corner header item in a QTableWidget that has both a horizontal and a vertical header? This is the header item they have in common. I can use

    Qt Code:
    1. QTableWidget::setHorizontalHeaderLabels ( const QStringList & labels )
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. QTableWidget::setVerticalHeaderLabels ( const QStringList & labels )
    To copy to clipboard, switch view to plain text mode 

    but they don't seem to provide access to the item at the corner. Nor do

    Qt Code:
    1. QTableWidgetItem * QTableWidget::horizontalHeaderItem ( int column ) const
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. QTableWidgetItem * QTableWidget::verticalHeaderItem ( int row) const
    To copy to clipboard, switch view to plain text mode 

    Perhaps accessing a header itself via

    Qt Code:
    1. QHeaderView * QTableView::horizontalHeader () const
    To copy to clipboard, switch view to plain text mode 
    or
    Qt Code:
    1. QHeaderView * QTableView::verticalHeader () const
    To copy to clipboard, switch view to plain text mode 

    but then what to do with it?

    thanks!

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableWidget NW corner header item?

    What would you like to do with it? It's not a header item actually but a button (for more information, see QTableCornerButton at the beginning of src/gui/itemviews/qtableview.cpp).
    J-P Nurmi

  3. #3
    Join Date
    Oct 2006
    Location
    Massachusetts, USA
    Posts
    19
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableWidget NW corner header item?

    I'd like to set its text; that's all.

    I see the code you pointed me to -- thanks. QTableView's private cornerWidget member is the QTableCornerButton, and it oddly hides another member of the same name down the inheritance chain, namely QAbstractScrollArea::cornerWidget. Only the latter is exposed via the method cornerWidget(). Doh. QTableWidget::cornerWidget() returns not the QTableCornerButton instance, but QAbstractScrollArea::cornerWidget, which is understandably NULL. Wish there was a QTableView::cornerButton() method.

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableWidget NW corner header item?

    It's still possible with some rather ugly "hacking". One would need to use for example QObject::findChild() to get access to the private corner button. An event filter is required for "overriding" the button's paintEvent() (QTableCornerButton::paintEvent() doesn't paint the text even if the button had text set). I have attached an example.

    This is, of course, not recommended way for doing it. It is a private button and may be a subject to change in the future. I suggest sending a suggestion about the issue to the Task-Tracker.
    Attached Files Attached Files
    J-P Nurmi

  5. The following 2 users say thank you to jpn for this useful post:

    McKee (30th March 2007), ykozlov (12th November 2012)

  6. #5
    Join Date
    Oct 2006
    Location
    Massachusetts, USA
    Posts
    19
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableWidget NW corner header item?

    Wow! Nice work. Thanks for the example code.

    Another way to solve the problem is to just create a new leftmost column, for which I can set the text of the top header item. I was hoping to avoid that because my table works better with my leftmost data in the vertical header items. But it's do-able.

    I'll look into the TaskTracker suggestion.

    McKee

  7. #6
    Join Date
    Jul 2007
    Posts
    5
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableWidget NW corner header item?

    Does anyone know if there is there any way to format the NW corner button using a stylesheet? Setting the following style sheet on the NW corner button in my CTableWidget constructor doesn't seem to do anything:

    Qt Code:
    1. CTableWidget::CTableWidget( QWidget* parent ):
    2. QTableWidget( parent )
    3. {
    4. QList< QAbstractButton* > buttons = qFindChildren< QAbstractButton* >( this );
    5. for ( int i=0; i<buttons.size(); ++i )
    6. {
    7. buttons[i]->setStyleSheet( "QWidget{ background-color:red; }" );
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    I can paint the button myself using an event filter, but it doesn't seem like an end user can modify the appearance.

    TIA,

    jt

  8. #7
    Join Date
    May 2009
    Posts
    55
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableWidget NW corner header item?

    Hi,

    post code from jtaylor108 seems to work for set backgroud color. Anyway I try to change a text of top left corner but it's not changed.
    I use same code but instead setStyleSheet I used setText() but text was not set. I s there any other option how to do this? Thanks

  9. #8
    Join Date
    Sep 2008
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTableWidget NW corner header item?

    This thread has been *very* useful, so I will add some points.

    First, you can indeed use a setStyleSheet call in your table widget class to change the corner button border and background as follows:

    Qt Code:
    1. setStyleSheet("QTableCornerButton::section {border: 2px outset red; background: green;}");
    To copy to clipboard, switch view to plain text mode 

    I did not need this functionality for what I wanted to do, but it is still a useful trick to know.

    What I wanted to do was place an icon in the corner button to indicate that there is indeed a functional button at that location (many of my users did not know that clicking the corner will select all of the table cells). The 29th March 2007 posted by jpn was *extremely* helpful with a slight change. In jpn's example, he sets the button text in the TableWidget constructor like this:

    Qt Code:
    1. btn->setText("Text");
    2. opt.text = btn->text();
    To copy to clipboard, switch view to plain text mode 

    I set the button icon instead of the text:

    Qt Code:
    1. QIcon myIcon = getMyIcon(); // this function returns a QIcon
    2. btn->setIcon(myIcon);
    3. opt.icon = btn->icon();
    To copy to clipboard, switch view to plain text mode 

    The "opt.text = btn->text();" line in the eventFilter function also has to be changed to "opt.icon = btn->icon();"

    I also changed the functionality of the corner button. Instead of simply selecting all of the cells, I altered the corner button to toggle between selecting all the cells and clearing the selection.

    Here is the relevant code from my QTableWidget constructor:

    Qt Code:
    1. // Take the click signal off of the corner widget and replace it with our own
    2. // This enables toggling the selection when the corner button is clicked.
    3. // This is more ergonomic than the default behavior of only selecting all of the cells.
    4. m_toggleCornerSelection = false;
    5. QAbstractButton *btn = findChild<QAbstractButton *>();
    6. if (btn != NULL) {
    7. btn->disconnect(SIGNAL(clicked()));
    8. connect(btn, SIGNAL(clicked()), this, SLOT(handleCornerButtonClicked()));
    9. MyIcons *iconList = MyIcons::getIcons(); // our class that handles all of our icons
    10. QIcon selectIcon = iconList->getIconSet(MyIcons::SELECT_ALL);
    11. btn->setIcon(selectIcon);
    12. // btn->setText("text");
    13. btn->setToolTip("Toggle selecting all table cells");
    14. btn->installEventFilter(this);
    15.  
    16. // adjust the width of the vertical header to match the preferred corner button width
    17. // (unfortunately QAbstractButton doesn't implement any size hinting functionality)
    18. // opt.text = btn->text();
    19. opt.icon = btn->icon();
    20. QSize s = (btn->style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), btn).
    21. expandedTo(QApplication::globalStrut()));
    22. if (s.isValid()) {
    23. verticalHeader()->setMinimumWidth(s.width());
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 

    I then implemented the following code:

    Qt Code:
    1. //-----------------------------------------------------------------------------
    2. // Event filter used to draw an icon in the top-left corner of the table widget
    3. //-----------------------------------------------------------------------------
    4.  
    5. bool MySpreadsheet::eventFilter(QObject* o, QEvent* e)
    6. {
    7. if (e->type() == QEvent::Paint) {
    8. QAbstractButton* btn = qobject_cast<QAbstractButton*>(o);
    9. if (btn) {
    10. // paint by hand (borrowed from QTableCornerButton)
    11. opt.init(btn);
    12. QStyle::State styleState = QStyle::State_None;
    13. if (btn->isEnabled())
    14. styleState |= QStyle::State_Enabled;
    15. if (btn->isActiveWindow())
    16. styleState |= QStyle::State_Active;
    17. if (btn->isDown())
    18. styleState |= QStyle::State_Sunken;
    19. opt.state = styleState;
    20. opt.rect = btn->rect();
    21. // opt.text = btn->text(); // this line is the only difference to QTableCornerButton
    22. opt.icon = btn->icon(); // this line is the only difference to QTableCornerButton
    23. opt.position = QStyleOptionHeader::OnlyOneSection;
    24. QStylePainter painter(btn);
    25. painter.drawControl(QStyle::CE_Header, opt);
    26. return true; // eat event
    27. }
    28. }
    29. return false;
    30. }
    31.  
    32. ...
    33. //-----------------------------------------------------------------------------
    34. // Handle clicking the upper-left corner button. This action toggles the selection of all of the cells
    35. // off and on.
    36. //-----------------------------------------------------------------------------
    37.  
    38. void MySpreadsheet::handleCornerButtonClicked()
    39. {
    40. if (m_toggleCornerSelection) {
    41. clearSelection();
    42. } else {
    43. selectAll();
    44. }
    45. m_toggleCornerSelection = !m_toggleCornerSelection;
    46. }
    To copy to clipboard, switch view to plain text mode 

    I hope that is helpful to those who want similar functionality.

  10. #9
    Join Date
    Apr 2011
    Posts
    1
    Qt products
    Platforms
    Windows

    Default Re: QTableWidget NW corner header item?

    I am using PyQt and none of the above solutions worked for me. However I was able to successfully hide the button by sub-classing QTableView and overriding the updateGeometries function.

    Qt Code:
    1. class MyTableView(QTableView):
    2.  
    3. def updateGeometries(self):
    4. # Call the updateGeometries function defined by QTableView first
    5. super(MyTableView, self).updateGeometries()
    6. # Find the corner widget and hide it!
    7. self.findChild(QAbstractButton).setHidden(True)
    To copy to clipboard, switch view to plain text mode 

  11. #10
    Join Date
    Mar 2006
    Posts
    74
    Thanks
    1
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTableWidget NW corner header item?

    I am trying to do something similar by changing the button icon. But I am using an icon the is not square. It is twice as wide as it is high. The icon is displayed but is not taking up the whole area of the button (I have set the header width to be twice as wide as it is high). To overcome this I am using:

    Qt Code:
    1. btn->setIconSize(m_iconSize);
    2. QPixmap pixmap = btn->icon().pixmap(m_iconSize, QIcon::Normal, QIcon::On);
    3. QStylePainter painter(btn);
    4. painter.drawItemPixmap(btn->rect(), Qt::AlignCenter, pixmap);
    To copy to clipboard, switch view to plain text mode 

    Instead of

    Qt Code:
    1. btn->setIconSize(m_iconSize);
    2. QStylePainter painter(btn);
    3. painter.drawControl(QStyle::CE_Header, opt);
    To copy to clipboard, switch view to plain text mode 

    So that the icon pixmap is being directly drawn to the area where the control is. This works but not as well as I would like. Is there any way to force painter.drawControl() to draw the icon full size?

Similar Threads

  1. Replies: 0
    Last Post: 10th November 2006, 14:46
  2. QTableWidget, header behavior
    By hyling in forum Qt Programming
    Replies: 1
    Last Post: 14th October 2006, 09:03
  3. QTableWidget item checkable and combo?
    By darpan in forum Qt Programming
    Replies: 1
    Last Post: 10th October 2006, 08:12
  4. How to delete header on QTableWidget
    By jlbrd in forum Qt Programming
    Replies: 2
    Last Post: 18th July 2006, 22:00
  5. QTableView header in corner
    By danstr in forum Qt Programming
    Replies: 3
    Last Post: 18th May 2006, 21:16

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.