Qt 4.4.0
I need to create a palette toolbar like CorelDRAW has. It can be expanded to show all the colors and minimized into one column/row. I've tried both ways, using QGridLayout and setting positions and sizes of all widgets manually but nothing works normally
Just copy this code into your IDE and u'll see:
PaletteToolbarButton.h
Qt Code:
  1. #ifndef PALETTETOOLBARBUTTON_H
  2. #define PALETTETOOLBARBUTTON_H
  3.  
  4. #include <QFrame>
  5.  
  6. class PaletteToolbarButton : public QFrame
  7. {
  8. Q_OBJECT
  9. public:
  10. PaletteToolbarButton(const QColor& newcolor = Qt::white, QWidget *parent = 0, const QSize& size = QSize(20,20), bool select = false);
  11. QColor color() const
  12. {
  13. return curColor;
  14. }
  15. bool isSelected() const
  16. {
  17. return selected;
  18. }
  19. public slots:
  20. void setColor(const QColor&);
  21. void setSelected(bool sel = true);
  22. signals:
  23. void clicked(const QColor&);
  24. protected:
  25. void paintEvent ( QPaintEvent * event );
  26. void mousePressEvent ( QMouseEvent * event );
  27. private:
  28. QColor curColor;
  29. bool selected;
  30. };
  31.  
  32. #endif // PALETTETOOLBARBUTTON_H
To copy to clipboard, switch view to plain text mode 
PaletteToolbarButton.cpp
Qt Code:
  1. #include <QtGui>
  2. #include "PaletteToolbarButton.h"
  3.  
  4. PaletteToolbarButton::PaletteToolbarButton(const QColor& newcolor, QWidget *parent, const QSize& size, bool select)
  5. : QFrame(parent), selected(select)
  6. {
  7. newcolor.isValid()? curColor = newcolor : curColor = Qt::transparent;
  8. setMinimumSize(size);
  9. setMaximumSize(size);
  10. }
  11. void PaletteToolbarButton::setColor(const QColor& newcolor)
  12. {
  13. if (newcolor.isValid() && newcolor != curColor)
  14. {
  15. curColor = newcolor;
  16. update ();
  17. }
  18. }
  19. void PaletteToolbarButton::setSelected(bool sel)
  20. {
  21. selected = sel;
  22. update();
  23. }
  24. void PaletteToolbarButton::paintEvent ( QPaintEvent * event )
  25. {
  26. if (selected)
  27. setFrameStyle(QFrame::WinPanel | QFrame::Raised);
  28. else setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
  29. QFrame::paintEvent(event);
  30. QPainter painter(this);
  31. if (curColor == Qt::transparent)
  32. {
  33. painter.setBrush(Qt::white);
  34. painter.setPen(Qt::black);
  35. painter.drawRect(1,1,width()-3,height()-3);
  36. painter.drawLine(1,1,width()-2,height()-2);
  37. painter.drawLine(1,height()-2,width()-2,1);
  38. }
  39. else
  40. {
  41. painter.setBrush(curColor);
  42. painter.setPen(Qt::NoPen);
  43. painter.drawRect(2,2,width()-4,height()-4);
  44. }
  45. }
  46. void PaletteToolbarButton::mousePressEvent ( QMouseEvent * event )
  47. {
  48. if (event->button() == Qt::LeftButton)
  49. emit clicked(curColor);
  50. }
To copy to clipboard, switch view to plain text mode 
PaletteToolbar.h
Qt Code:
  1. #ifndef PALETTETOOLBAR_H
  2. #define PALETTETOOLBAR_H
  3.  
  4. #include <QToolBar>
  5. #include "PaletteToolbarButton.h"
  6.  
  7. class PaletteToolbar : public QToolBar
  8. {
  9. Q_OBJECT
  10. public:
  11. PaletteToolbar(const QList<QColor>& colorList = QList<QColor>(), const QString& title = "Palette", QWidget* parent = 0);
  12. void addColor(const QColor&, int before = -1);//-1 means "add after the last one"
  13. void removeColor(const QColor&);
  14. bool isExpanded() const
  15. {return expanded;}
  16. QColor color() const
  17. { return selButton->color(); }
  18. public slots:
  19. void setExpanded(bool);
  20. void setSelColor(const QColor&);
  21. signals:
  22. void expands(bool);
  23. void colorChosen(const QColor&);
  24. private slots:
  25. void arrangeButtons();
  26. void expandButtonTriggered();
  27. protected:
  28. void resizeEvent ( QResizeEvent * event ) ;
  29. private:
  30. bool expanded;
  31. bool arranging;
  32. QList<PaletteToolbarButton*> buttonList;
  33. PaletteToolbarButton* selButton;
  34. QWidget* layoutWidget;
  35. QToolButton* expandButton;
  36. QToolButton* customizeButton;
  37. };
  38.  
  39. #endif // PALETTETOOLBAR_H
To copy to clipboard, switch view to plain text mode 
PaletteToolbar.cpp
Qt Code:
  1. #include <QtGui>
  2. #include "PaletteToolbar.h"
  3. PaletteToolbar::PaletteToolbar(const QList<QColor>& colorList, const QString& title, QWidget* parent)
  4. : QToolBar(title,parent), expanded(false), arranging(false)
  5. {
  6. setFloatable(false);
  7. layoutWidget = new QWidget(this);
  8. QAction* actExpand = new QAction(this);
  9. expandButton = new QToolButton(layoutWidget);
  10. expandButton->setDefaultAction(actExpand);
  11. connect(actExpand, SIGNAL(triggered()), this, SLOT(expandButtonTriggered()));
  12. addWidget(layoutWidget);
  13. foreach(QColor color, colorList)
  14. {
  15. PaletteToolbarButton* newButton = new PaletteToolbarButton(color,layoutWidget);
  16. buttonList.append(newButton);
  17. connect(newButton,SIGNAL(clicked(const QColor&)),this,SLOT(setSelColor(const QColor&)));
  18. }
  19. expandButton->setMinimumSize(buttonList.first()->minimumSize());
  20. expandButton->setMaximumSize(buttonList.first()->maximumSize());
  21. if (buttonList.size()) selButton = buttonList.first();
  22. }
  23. void PaletteToolbar::addColor(const QColor&, int before)
  24. {}
  25. void PaletteToolbar::removeColor(const QColor&)
  26. {}
  27. void PaletteToolbar::setExpanded(bool newexp)
  28. {
  29. if (expanded != newexp)
  30. {
  31. expanded = newexp;
  32. arrangeButtons();
  33. emit expands(newexp);
  34. }
  35. }
  36. void PaletteToolbar::setSelColor(const QColor& newcolor)
  37. {
  38. selButton->setSelected(false);
  39. selButton = static_cast<PaletteToolbarButton*> (sender());
  40. selButton->setSelected(true);
  41. emit colorChosen(newcolor);
  42. }
  43. void PaletteToolbar::resizeEvent ( QResizeEvent * event )
  44. {
  45. QToolBar::resizeEvent(event);
  46. if (!arranging)
  47. arrangeButtons();
  48. }
  49. void PaletteToolbar::expandButtonTriggered()
  50. {
  51. if (expanded)
  52. setExpanded(false);
  53. else setExpanded(true);
  54. }
  55. void PaletteToolbar::arrangeButtons()
  56. {
  57. if (buttonList.size()!=0)
  58. {
  59. arranging = true;
  60. delete layoutWidget->layout();
  61. QGridLayout* grid = new QGridLayout;
  62. grid->setSpacing(2);
  63. int cellWidth = buttonList.first()->minimumWidth()+2;
  64. int cellHeight = buttonList.first()->minimumHeight()+2;
  65. bool vert = orientation()==Qt::Vertical;
  66. switch(static_cast<QMainWindow*>(parentWidget())->toolBarArea(this))
  67. {
  68. case Qt::LeftToolBarArea:
  69. expandButton->setArrowType(expanded? Qt::LeftArrow : Qt::RightArrow);
  70. break;
  71. case Qt::RightToolBarArea:
  72. expandButton->setArrowType(expanded? Qt::RightArrow : Qt::LeftArrow);
  73. break;
  74. case Qt::BottomToolBarArea:
  75. expandButton->setArrowType(expanded? Qt::DownArrow : Qt::UpArrow);
  76. break;
  77. case Qt::TopToolBarArea:
  78. expandButton->setArrowType(expanded? Qt::UpArrow : Qt::DownArrow);
  79. break;
  80. }
  81. int ButtonsInRow,ButtonsInCol;
  82. if (!expanded)
  83. {
  84. if (vert)
  85. {
  86. ButtonsInRow = 1;
  87. ButtonsInCol = height() / cellHeight;
  88. }
  89. else //horizontal
  90. {
  91. ButtonsInCol = 1;
  92. ButtonsInRow = width() / cellWidth;
  93. }
  94. }
  95. else //ToolBar is expanded
  96. {
  97. if (vert)
  98. {
  99. ButtonsInCol = height() / cellHeight;
  100. ButtonsInRow = (buttonList.size() + 1) / ButtonsInCol;
  101. if ((buttonList.size() + 1) % ButtonsInCol) ++ButtonsInRow;
  102. }
  103. else //horizontal
  104. {
  105. ButtonsInRow = width() / cellWidth;
  106. ButtonsInCol = (buttonList.size() + 1) / ButtonsInRow;
  107. if ((buttonList.size() + 1) % ButtonsInRow) ++ButtonsInCol;
  108. }
  109. }
  110. int Row = 0,Col = 0,i=0;
  111. foreach(PaletteToolbarButton* button,buttonList)
  112. {
  113. grid->addWidget(button,Row,Col);++i;
  114. if (vert)
  115. {
  116. ++Row;
  117. if (Row >= ButtonsInCol - 1)
  118. {
  119. if (Col >= ButtonsInRow - 1)
  120. {
  121. break;
  122. }
  123. else
  124. {
  125. ++Col;
  126. Row = 0;
  127. }
  128. }
  129. }
  130. else //horizontal
  131. {
  132. ++Col;
  133. if (Col >= ButtonsInRow - 1)
  134. {
  135. if (Row >= ButtonsInCol - 1)
  136. {
  137. break;
  138. }
  139. else
  140. {
  141. ++Row;
  142. Col = 0;
  143. }
  144. }
  145. }
  146. }//foreach
  147. grid->addWidget(expandButton,Row,Col);
  148. layoutWidget->setLayout(grid);
  149. arranging = false;
  150. }//if (buttonList.size()!=0)
  151. }
To copy to clipboard, switch view to plain text mode 
in the constructor of the class derived from QMainWindow:
Qt Code:
  1. QStringList names = QColor::colorNames();
  2. QList<QColor> colorlist;
  3. foreach(QString name, names)
  4. {
  5. colorlist.append(QColor(name));
  6. }
  7. palette = new PaletteToolbar(colorlist);
  8. addToolBar(Qt::RightToolBarArea,palette);
To copy to clipboard, switch view to plain text mode 
thanks in advance!