Results 1 to 4 of 4

Thread: How to use Checkboxes in QMenu?

  1. #1
    Join Date
    Jun 2015
    Posts
    3
    Qt products
    Qt5
    Platforms
    Windows

    Question How to use Checkboxes in QMenu?

    Hi Everyone.

    I have problem with my program in Qt5. I use QSpreadsheetHeaderView class which is subclass of QHeaderView.

    .cpp:
    Qt Code:
    1. #include <QPainter>
    2. #include <QCursor>
    3. #include <QHoverEvent>
    4. #include <QMenu>
    5. #include <QRegExp>
    6. #include <QApplication>
    7. #include <QSignalMapper>
    8. #include <QWidgetAction>
    9. #include "QSpreadsheetHeaderView.h"
    10. #include "mainwindow.h"
    11.  
    12. QSpreadsheetHeaderView::QSpreadsheetHeaderView(Qt::Orientation orientation, QWidget * parent)
    13. : QHeaderView(orientation, parent)
    14. {
    15. // Required to refresh button menu when the mouse leave the header.
    16. setAttribute(Qt::WA_Hover, true);
    17. }
    18.  
    19. void QSpreadsheetHeaderView::mousePressEvent ( QMouseEvent * event )
    20. {
    21. QHeaderView::mousePressEvent(event);
    22.  
    23. int logicalIndex = logicalIndexAt(event->pos());
    24.  
    25. if (buttonMenuRect(logicalIndex).contains(event->pos())) {
    26. QMenu menu(this);
    27. QAction *hideCol = menu.addAction("Hide");
    28. QAction *sortAZ = menu.addAction("Sort A->Z");
    29. QAction *sortZA = menu.addAction("Sort Z->A");
    30. QMenu * format= menu.addMenu(tr("&Filter"));
    31. QAction *all = format->addAction("All");
    32. format->addSeparator();
    33.  
    34. QSignalMapper *mapper = new QSignalMapper(this);
    35. for(int i = 0; i < model()->columnCount(); i++)
    36. {
    37. QAction *others = format->addAction(model()->headerData(i, Qt::Horizontal).toString());
    38. format->addAction(others);
    39.  
    40. QWidgetAction * addition = new QWidgetAction(&menu);
    41. checkBox = new QCheckBox(&menu);
    42. checkBox->setText(model()->headerData(i, Qt::Horizontal).toString());
    43. addition->setDefaultWidget(checkBox);
    44. menu.addAction(addition);
    45. mapper->setMapping(addition, i);
    46. }
    47.  
    48. // Disable hide column if only one column remains. Otherwise
    49. // the gui is no more available to show them back.
    50. hideCol->setEnabled(hiddenSectionCount() < count() - 1);
    51.  
    52. QAction *res = menu.exec(mapToGlobal(event->pos()));
    53.  
    54. if (res == hideCol) {
    55. hideSection(logicalIndex);
    56. updateSection(logicalIndex-1);
    57. }
    58. if (res == sortAZ)
    59. model()->sort(logicalIndex, Qt::AscendingOrder);
    60. if (res == sortZA)
    61. model()->sort(logicalIndex, Qt::DescendingOrder);
    62. }
    63.  
    64. // Catch previous arrow mouse click.
    65. if (prevRect(logicalIndex).contains(event->pos())) {
    66. showSection(logicalIndex - 1);
    67. updateSection(logicalIndex - 2);
    68. }
    69.  
    70. // Catch next arrow mouse click.
    71. if (nextRect(logicalIndex).contains(event->pos())) {
    72. showSection(logicalIndex + 1);
    73. updateSection(logicalIndex + 2);
    74. }
    75. }
    76.  
    77. void QSpreadsheetHeaderView::mouseMoveEvent(QMouseEvent * event)
    78. {
    79. QHeaderView::mouseMoveEvent(event);
    80.  
    81. // Required to refresh the button menu enable/disable state.
    82. int logicalIndex = logicalIndexAt(event->pos());
    83. updateSection(logicalIndex);
    84. }
    85.  
    86. void QSpreadsheetHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
    87. {
    88. painter->save();
    89.  
    90. QHeaderView::paintSection(painter, rect, logicalIndex);
    91.  
    92. painter->restore();
    93.  
    94. if (!rect.isValid() || isSortIndicatorShown())
    95. return;
    96.  
    97. if (isSectionHidden(logicalIndex - 1)) {
    98. drawPrevButton(painter, logicalIndex);
    99. }
    100.  
    101. if (isSectionHidden(logicalIndex + 1)) {
    102. drawNextButton(painter, logicalIndex);
    103. }
    104.  
    105. QPoint pos = mapFromGlobal(QCursor::pos());
    106. if (rect.contains(pos)) {
    107. drawMenuButton(painter, logicalIndex, buttonMenuRect(logicalIndex).contains(pos));
    108. }
    109. }
    110.  
    111. QRect QSpreadsheetHeaderView::sectionRect(int logicalIndex) const
    112. {
    113. return QRect(sectionViewportPosition(logicalIndex), 0, sectionSize(logicalIndex), height());
    114. }
    115.  
    116. QRect QSpreadsheetHeaderView::buttonMenuRect(int logicalIndex) const
    117. {
    118. QRect sr = sectionRect(logicalIndex);
    119.  
    120. return QRect(sr.right() - 5 - 13, sr.center().y() - 6, 13, 13);
    121. }
    122.  
    123. QRect QSpreadsheetHeaderView::prevRect(int logicalIndex) const
    124. {
    125. if (isSectionHidden(logicalIndex))
    126. return QRect();
    127.  
    128. QRect sr = sectionRect(logicalIndex);
    129.  
    130. return QRect(sr.left() + 1, sr.center().y() - 6, 13, 13);
    131. }
    132.  
    133. QRect QSpreadsheetHeaderView::nextRect(int logicalIndex) const
    134. {
    135. if (isSectionHidden(logicalIndex))
    136. return QRect();
    137.  
    138. QRect sr = sectionRect(logicalIndex);
    139.  
    140. return QRect(sr.right() - 13, sr.center().y() - 6, 13, 13);
    141. }
    142.  
    143. void QSpreadsheetHeaderView::drawMenuButton(QPainter *painter, int logicalIndex, bool enabled) const
    144. {
    145. QRect brect = buttonMenuRect(logicalIndex);
    146.  
    147. painter->setPen(enabled ? QColor(186,186,186) : QColor(223, 223, 223));
    148. painter->setBrush(QColor(246,246,246));
    149. painter->drawRect(brect.adjusted(0,0,-1,-1));
    150.  
    151. painter->setPen(enabled ? QColor(71,71,71) : QColor(193, 193, 193));
    152. painter->drawLine(brect.left()+3, brect.top()+5, brect.right()-3, brect.top()+5);
    153. painter->drawLine(brect.left()+4, brect.top()+6, brect.right()-4, brect.top()+6);
    154. painter->drawLine(brect.left()+5, brect.top()+7, brect.right()-5, brect.top()+7);
    155. painter->drawPoint(brect.left()+6, brect.top()+8);
    156. }
    157.  
    158. void QSpreadsheetHeaderView::drawPrevButton(QPainter *painter, int logicalIndex) const
    159. {
    160. QRect rect = prevRect(logicalIndex);
    161.  
    162. painter->setPen(QColor(71,71,71));
    163. painter->drawLine(rect.left()+1, rect.center().y() - 3, rect.left()+1, rect.center().y() + 3);
    164. painter->drawLine(rect.left()+2, rect.center().y() - 2, rect.left()+2, rect.center().y() + 2);
    165. painter->drawLine(rect.left()+3, rect.center().y() - 1, rect.left()+3, rect.center().y() + 1);
    166. painter->drawPoint(rect.left()+4, rect.center().y());
    167. }
    168.  
    169. void QSpreadsheetHeaderView::drawNextButton(QPainter *painter, int logicalIndex) const
    170. {
    171. QRect rect = nextRect(logicalIndex);
    172.  
    173. painter->setPen(QColor(71,71,71));
    174. painter->drawLine(rect.right()-2, rect.center().y() - 3, rect.right()-2, rect.center().y() + 3);
    175. painter->drawLine(rect.right()-3, rect.center().y() - 2, rect.right()-3, rect.center().y() + 2);
    176. painter->drawLine(rect.right()-4, rect.center().y() - 1, rect.right()-4, rect.center().y() + 1);
    177. painter->drawPoint(rect.right()-5, rect.center().y());
    178. }
    To copy to clipboard, switch view to plain text mode 

    .h
    Qt Code:
    1. #ifndef QSPREADSHEETHEADERVIEW
    2. #define QSPREADSHEETHEADERVIEW
    3.  
    4. #include <QHeaderView>
    5. #include <QCheckBox>
    6.  
    7. /*!
    8.   \class QSpreadsheetHeaderView
    9.   \brief The QSpreadsheetHeaderView class is a special QHeaderView that mimic Google Spreadsheet header.
    10.   version 1.0
    11.   \sa QHeaderView
    12. */
    13. class QSpreadsheetHeaderView : public QHeaderView
    14. {
    15. Q_OBJECT
    16.  
    17. public:
    18. QSpreadsheetHeaderView(Qt::Orientation orientation, QWidget * parent = 0);
    19. QCheckBox *checkBox;
    20. //protected:
    21. void mousePressEvent(QMouseEvent * event);
    22. void mouseMoveEvent(QMouseEvent * event);
    23. void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
    24.  
    25. QRect sectionRect(int logicalIndex) const;
    26. QRect buttonMenuRect(int logicalIndex) const;
    27. QRect prevRect(int logicalIndex) const;
    28. QRect nextRect(int logicalIndex) const;
    29.  
    30. void drawMenuButton(QPainter *painter, int logicalIndex, bool enabled) const;
    31. void drawPrevButton(QPainter *painter, int logicalIndex) const;
    32. void drawNextButton(QPainter *painter, int logicalIndex) const;
    33. private:
    34.  
    35. };
    36.  
    37. #endif // QSPREADSHEETHEADERVIEW
    To copy to clipboard, switch view to plain text mode 

    I add to the menu checkboxes that represent column of the table. I know that every time I use function checboxes are creating once again. I tried signal/slots, implementation of checkboxes array, but my knowledge does not allow to solve this problem. I would like to save value of checkboxes after leaving menu. Also i need to connect this checkboxes with hiding colums. Can someone help me?
    Last edited by Stravinsky; 11th June 2015 at 14:35.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to use Checkboxes in QMenu?

    Any reason you are not using a checkable action?

    Cheers,
    _

  3. #3
    Join Date
    Jun 2015
    Posts
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to use Checkboxes in QMenu?

    I already implement menu. I have problem with staying on top of the menu when I want to check more than one checkable action. When i use QCheckBox i dont have this problem. Do you know how to select multiple actions without hiding the menu?.

  4. #4
    Join Date
    Jun 2015
    Posts
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to use Checkboxes in QMenu?

    I fixed this problem.

    I used 2 signal&slots. One for non checkable action and second for checkable. The second one have menu->show() in slot to keep menu on top.


    Qt Code:
    1. void QSpreadsheetHeaderView::mousePressEvent ( QMouseEvent * event )
    2. {
    3. QHeaderView::mousePressEvent(event);
    4.  
    5. logicalIndex = logicalIndexAt(event->pos());
    6.  
    7. if (buttonMenuRect(logicalIndex).contains(event->pos())) {
    8.  
    9. if(set_checkbox==false)
    10. {
    11. menu = new QMenu(this);
    12.  
    13. sortAZ = menu->addAction("Sortuj A->Z");
    14. sortZA = menu->addAction("Sortuj Z->A");
    15. clear_sort = menu->addAction("Anuluj");
    16. menu->addSeparator();
    17. hideCol = menu->addAction("Ukryj kolumnÄ™");
    18. clear_hideCol = menu->addAction("Odkryj wszystkie");
    19.  
    20. for(int i = 0; i <model()->columnCount(); i++)
    21. {
    22. actions[i] = new QAction(menu);
    23. actions[i] = menu->addAction(model()->headerData(i, Qt::Horizontal).toString());
    24. actions[i]->setCheckable(true);
    25. connect(actions[i],SIGNAL(triggered(bool)),this,SLOT(hide_selected_column(bool)));
    26. if(i<columns_min)actions[i]->setChecked(true);
    27.  
    28. }
    29.  
    30. set_checkbox=true;
    31. connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(action(QAction*)));
    32. }
    33.  
    34. // Disable hide column if only one column remains. Otherwise
    35. // the gui is no more available to show them back.
    36. hideCol->setEnabled(hiddenSectionCount() < count() - 1);
    37. if(hideCol->isEnabled()==false)
    38. {
    39. for(int i = 0; i <model()->columnCount(); i++)
    40. {
    41. if(actions[i]->isChecked()==true)
    42. {
    43. previous_sender=actions[i];
    44. freeze=true;
    45. actions[i]->setEnabled(false);
    46. break;
    47. }
    48. }
    49. }
    50.  
    51. menu->popup(mapToGlobal(event->pos()));
    52. }
    53.  
    54. // Catch previous arrow mouse click.
    55. else if (prevRect(logicalIndex).contains(event->pos()) && set_checkbox==true) {
    56. showSection(logicalIndex - 1);
    57. actions[logicalIndex - 1]->setChecked(true);
    58. updateSection(logicalIndex - 2);
    59. if(freeze==true) { previous_sender->setEnabled(true); freeze=false;}
    60. }
    61.  
    62. // Catch next arrow mouse click.
    63. else if (nextRect(logicalIndex).contains(event->pos()) && set_checkbox==true) {
    64. showSection(logicalIndex + 1);
    65. actions[logicalIndex + 1]->setChecked(true);
    66. updateSection(logicalIndex + 2);
    67. if(freeze==true) { previous_sender->setEnabled(true); freeze=false; }
    68. }
    69.  
    70.  
    71. }
    To copy to clipboard, switch view to plain text mode 

    Slot for non checkable:

    Qt Code:
    1. void QSpreadsheetHeaderView::action(QAction *action) {
    2.  
    3.  
    4. if (action == hideCol)
    5. {
    6. hideSection(logicalIndex);
    7. actions[logicalIndex]->setChecked(false);
    8. updateSection(logicalIndex-1);
    9. }
    10.  
    11. if (action == sortAZ)
    12. model()->sort(logicalIndex, Qt::AscendingOrder);
    13.  
    14. if (action == sortZA)
    15. model()->sort(logicalIndex, Qt::DescendingOrder);
    16.  
    17. if (action == clear_hideCol){
    18. for(int i = 0; i <model()->columnCount(); i++)
    19. {
    20. showSection(i);
    21. actions[i]->setChecked(true);
    22. actions[i]->setEnabled(true);
    23. if(freeze==true) { previous_sender->setEnabled(true); freeze=false;}
    24. }
    25. }
    26.  
    27. if (action == clear_sort){
    28.  
    29. }
    30.  
    31. }
    To copy to clipboard, switch view to plain text mode 

    and checkable:
    Qt Code:
    1. void QSpreadsheetHeaderView::hide_selected_column(bool checked)
    2. {
    3. menu->show();
    4. QAction * senderCHECK = qobject_cast<QAction *>(this->sender());
    5.  
    6. for(int i=0;i<23;i++)
    7. {
    8. if(senderCHECK==actions[i])
    9. {
    10. if(checked==false && freeze==false)
    11. {
    12. hideSection(i);
    13. actions[i]->setChecked(false);
    14. }
    15.  
    16. else if(checked==true && freeze==true)
    17. {
    18. hideCol->setEnabled(true);
    19. previous_sender->setEnabled(true);
    20. showSection(i);
    21. actions[i]->setChecked(true);
    22. freeze=false;
    23.  
    24. }
    25.  
    26. else if(checked==true)
    27. {
    28. showSection(i);
    29. actions[i]->setChecked(true);
    30. }
    31. }
    32. }
    33.  
    34. if(count()-hiddenSectionCount()==1)
    35. {
    36. freeze=true;
    37. hideCol->setEnabled(false);
    38. for(int i=0;i<23;i++)
    39. {
    40. if(actions[i]->isChecked()==true)
    41. {
    42. previous_sender=actions[i];
    43. actions[i]->setEnabled(false);
    44. break;
    45. }
    46. }
    47. }
    48. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QTableWidget with checkboxes.
    By chris_helloworld in forum Qt Programming
    Replies: 0
    Last Post: 13th January 2011, 16:42
  2. checkboxes in a tableview,
    By mimmo_kallon in forum Newbie
    Replies: 3
    Last Post: 13th March 2008, 20:01
  3. QTableView and checkboxes
    By ibergmark in forum Qt Programming
    Replies: 3
    Last Post: 23rd February 2008, 16:20
  4. checkboxes
    By abrou in forum Newbie
    Replies: 2
    Last Post: 1st February 2008, 19:52
  5. Checkboxes in QAbstractITemModel
    By Valheru in forum Qt Programming
    Replies: 5
    Last Post: 28th November 2007, 21:23

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.