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
#ifndef PALETTETOOLBARBUTTON_H
#define PALETTETOOLBARBUTTON_H
#include <QFrame>
class PaletteToolbarButton
: public QFrame{
Q_OBJECT
public:
PaletteToolbarButton
(const QColor
& newcolor
= Qt
::white,
QWidget *parent
= 0,
const QSize
& size
= QSize(20,
20),
bool select
= false);
{
return curColor;
}
bool isSelected() const
{
return selected;
}
public slots:
void setColor(const QColor&);
void setSelected(bool sel = true);
signals:
void clicked(const QColor&);
protected:
private:
bool selected;
};
#endif // PALETTETOOLBARBUTTON_H
#ifndef PALETTETOOLBARBUTTON_H
#define PALETTETOOLBARBUTTON_H
#include <QFrame>
class PaletteToolbarButton : public QFrame
{
Q_OBJECT
public:
PaletteToolbarButton(const QColor& newcolor = Qt::white, QWidget *parent = 0, const QSize& size = QSize(20,20), bool select = false);
QColor color() const
{
return curColor;
}
bool isSelected() const
{
return selected;
}
public slots:
void setColor(const QColor&);
void setSelected(bool sel = true);
signals:
void clicked(const QColor&);
protected:
void paintEvent ( QPaintEvent * event );
void mousePressEvent ( QMouseEvent * event );
private:
QColor curColor;
bool selected;
};
#endif // PALETTETOOLBARBUTTON_H
To copy to clipboard, switch view to plain text mode
PaletteToolbarButton.cpp
#include <QtGui>
#include "PaletteToolbarButton.h"
PaletteToolbarButton
::PaletteToolbarButton(const QColor
& newcolor,
QWidget *parent,
const QSize
& size,
bool select
) : QFrame(parent
), selected
(select
) {
newcolor.isValid()? curColor = newcolor : curColor = Qt::transparent;
setMinimumSize(size);
setMaximumSize(size);
}
void PaletteToolbarButton::setColor(const QColor& newcolor)
{
if (newcolor.isValid() && newcolor != curColor)
{
curColor = newcolor;
update ();
}
}
void PaletteToolbarButton::setSelected(bool sel)
{
selected = sel;
update();
}
void PaletteToolbarButton
::paintEvent ( QPaintEvent * event
) {
if (selected)
if (curColor == Qt::transparent)
{
painter.setBrush(Qt::white);
painter.setPen(Qt::black);
painter.drawRect(1,1,width()-3,height()-3);
painter.drawLine(1,1,width()-2,height()-2);
painter.drawLine(1,height()-2,width()-2,1);
}
else
{
painter.setBrush(curColor);
painter.setPen(Qt::NoPen);
painter.drawRect(2,2,width()-4,height()-4);
}
}
void PaletteToolbarButton
::mousePressEvent ( QMouseEvent * event
) {
if (event->button() == Qt::LeftButton)
emit clicked(curColor);
}
#include <QtGui>
#include "PaletteToolbarButton.h"
PaletteToolbarButton::PaletteToolbarButton(const QColor& newcolor, QWidget *parent, const QSize& size, bool select)
: QFrame(parent), selected(select)
{
newcolor.isValid()? curColor = newcolor : curColor = Qt::transparent;
setMinimumSize(size);
setMaximumSize(size);
}
void PaletteToolbarButton::setColor(const QColor& newcolor)
{
if (newcolor.isValid() && newcolor != curColor)
{
curColor = newcolor;
update ();
}
}
void PaletteToolbarButton::setSelected(bool sel)
{
selected = sel;
update();
}
void PaletteToolbarButton::paintEvent ( QPaintEvent * event )
{
if (selected)
setFrameStyle(QFrame::WinPanel | QFrame::Raised);
else setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
QFrame::paintEvent(event);
QPainter painter(this);
if (curColor == Qt::transparent)
{
painter.setBrush(Qt::white);
painter.setPen(Qt::black);
painter.drawRect(1,1,width()-3,height()-3);
painter.drawLine(1,1,width()-2,height()-2);
painter.drawLine(1,height()-2,width()-2,1);
}
else
{
painter.setBrush(curColor);
painter.setPen(Qt::NoPen);
painter.drawRect(2,2,width()-4,height()-4);
}
}
void PaletteToolbarButton::mousePressEvent ( QMouseEvent * event )
{
if (event->button() == Qt::LeftButton)
emit clicked(curColor);
}
To copy to clipboard, switch view to plain text mode
PaletteToolbar.h
#ifndef PALETTETOOLBAR_H
#define PALETTETOOLBAR_H
#include <QToolBar>
#include "PaletteToolbarButton.h"
{
Q_OBJECT
public:
PaletteToolbar
(const QList<QColor>
& colorList
= QList<QColor>
(),
const QString
& title
= "Palette",
QWidget* parent
= 0);
void addColor(const QColor&, int before = -1);//-1 means "add after the last one"
void removeColor(const QColor&);
bool isExpanded() const
{return expanded;}
{ return selButton->color(); }
public slots:
void setExpanded(bool);
void setSelColor(const QColor&);
signals:
void expands(bool);
void colorChosen(const QColor&);
private slots:
void arrangeButtons();
void expandButtonTriggered();
protected:
private:
bool expanded;
bool arranging;
QList<PaletteToolbarButton*> buttonList;
PaletteToolbarButton* selButton;
};
#endif // PALETTETOOLBAR_H
#ifndef PALETTETOOLBAR_H
#define PALETTETOOLBAR_H
#include <QToolBar>
#include "PaletteToolbarButton.h"
class QToolButton;
class PaletteToolbar : public QToolBar
{
Q_OBJECT
public:
PaletteToolbar(const QList<QColor>& colorList = QList<QColor>(), const QString& title = "Palette", QWidget* parent = 0);
void addColor(const QColor&, int before = -1);//-1 means "add after the last one"
void removeColor(const QColor&);
bool isExpanded() const
{return expanded;}
QColor color() const
{ return selButton->color(); }
public slots:
void setExpanded(bool);
void setSelColor(const QColor&);
signals:
void expands(bool);
void colorChosen(const QColor&);
private slots:
void arrangeButtons();
void expandButtonTriggered();
protected:
void resizeEvent ( QResizeEvent * event ) ;
private:
bool expanded;
bool arranging;
QList<PaletteToolbarButton*> buttonList;
PaletteToolbarButton* selButton;
QWidget* layoutWidget;
QToolButton* expandButton;
QToolButton* customizeButton;
};
#endif // PALETTETOOLBAR_H
To copy to clipboard, switch view to plain text mode
PaletteToolbar.cpp
#include <QtGui>
#include "PaletteToolbar.h"
PaletteToolbar
::PaletteToolbar(const QList<QColor>
& colorList,
const QString
& title,
QWidget* parent
) : QToolBar(title,parent
), expanded
(false), arranging
(false) {
setFloatable(false);
expandButton->setDefaultAction(actExpand);
connect(actExpand, SIGNAL(triggered()), this, SLOT(expandButtonTriggered()));
addWidget(layoutWidget);
foreach
(QColor color, colorList
) {
PaletteToolbarButton* newButton = new PaletteToolbarButton(color,layoutWidget);
buttonList.append(newButton);
connect(newButton,SIGNAL(clicked(const QColor&)),this,SLOT(setSelColor(const QColor&)));
}
expandButton->setMinimumSize(buttonList.first()->minimumSize());
expandButton->setMaximumSize(buttonList.first()->maximumSize());
if (buttonList.size()) selButton = buttonList.first();
}
void PaletteToolbar::addColor(const QColor&, int before)
{}
void PaletteToolbar::removeColor(const QColor&)
{}
void PaletteToolbar::setExpanded(bool newexp)
{
if (expanded != newexp)
{
expanded = newexp;
arrangeButtons();
emit expands(newexp);
}
}
void PaletteToolbar::setSelColor(const QColor& newcolor)
{
selButton->setSelected(false);
selButton = static_cast<PaletteToolbarButton*> (sender());
selButton->setSelected(true);
emit colorChosen(newcolor);
}
{
if (!arranging)
arrangeButtons();
}
void PaletteToolbar::expandButtonTriggered()
{
if (expanded)
setExpanded(false);
else setExpanded(true);
}
void PaletteToolbar::arrangeButtons()
{
if (buttonList.size()!=0)
{
arranging = true;
delete layoutWidget->layout();
grid->setSpacing(2);
int cellWidth = buttonList.first()->minimumWidth()+2;
int cellHeight = buttonList.first()->minimumHeight()+2;
bool vert = orientation()==Qt::Vertical;
switch(static_cast<QMainWindow*>(parentWidget())->toolBarArea(this))
{
case Qt::LeftToolBarArea:
expandButton->setArrowType(expanded? Qt::LeftArrow : Qt::RightArrow);
break;
case Qt::RightToolBarArea:
expandButton->setArrowType(expanded? Qt::RightArrow : Qt::LeftArrow);
break;
case Qt::BottomToolBarArea:
expandButton->setArrowType(expanded? Qt::DownArrow : Qt::UpArrow);
break;
case Qt::TopToolBarArea:
expandButton->setArrowType(expanded? Qt::UpArrow : Qt::DownArrow);
break;
}
int ButtonsInRow,ButtonsInCol;
if (!expanded)
{
if (vert)
{
ButtonsInRow = 1;
ButtonsInCol = height() / cellHeight;
}
else //horizontal
{
ButtonsInCol = 1;
ButtonsInRow = width() / cellWidth;
}
}
else //ToolBar is expanded
{
if (vert)
{
ButtonsInCol = height() / cellHeight;
ButtonsInRow = (buttonList.size() + 1) / ButtonsInCol;
if ((buttonList.size() + 1) % ButtonsInCol) ++ButtonsInRow;
}
else //horizontal
{
ButtonsInRow = width() / cellWidth;
ButtonsInCol = (buttonList.size() + 1) / ButtonsInRow;
if ((buttonList.size() + 1) % ButtonsInRow) ++ButtonsInCol;
}
}
int Row = 0,Col = 0,i=0;
foreach(PaletteToolbarButton* button,buttonList)
{
grid->addWidget(button,Row,Col);++i;
if (vert)
{
++Row;
if (Row >= ButtonsInCol - 1)
{
if (Col >= ButtonsInRow - 1)
{
break;
}
else
{
++Col;
Row = 0;
}
}
}
else //horizontal
{
++Col;
if (Col >= ButtonsInRow - 1)
{
if (Row >= ButtonsInCol - 1)
{
break;
}
else
{
++Row;
Col = 0;
}
}
}
}//foreach
grid->addWidget(expandButton,Row,Col);
layoutWidget->setLayout(grid);
arranging = false;
}//if (buttonList.size()!=0)
}
#include <QtGui>
#include "PaletteToolbar.h"
PaletteToolbar::PaletteToolbar(const QList<QColor>& colorList, const QString& title, QWidget* parent)
: QToolBar(title,parent), expanded(false), arranging(false)
{
setFloatable(false);
layoutWidget = new QWidget(this);
QAction* actExpand = new QAction(this);
expandButton = new QToolButton(layoutWidget);
expandButton->setDefaultAction(actExpand);
connect(actExpand, SIGNAL(triggered()), this, SLOT(expandButtonTriggered()));
addWidget(layoutWidget);
foreach(QColor color, colorList)
{
PaletteToolbarButton* newButton = new PaletteToolbarButton(color,layoutWidget);
buttonList.append(newButton);
connect(newButton,SIGNAL(clicked(const QColor&)),this,SLOT(setSelColor(const QColor&)));
}
expandButton->setMinimumSize(buttonList.first()->minimumSize());
expandButton->setMaximumSize(buttonList.first()->maximumSize());
if (buttonList.size()) selButton = buttonList.first();
}
void PaletteToolbar::addColor(const QColor&, int before)
{}
void PaletteToolbar::removeColor(const QColor&)
{}
void PaletteToolbar::setExpanded(bool newexp)
{
if (expanded != newexp)
{
expanded = newexp;
arrangeButtons();
emit expands(newexp);
}
}
void PaletteToolbar::setSelColor(const QColor& newcolor)
{
selButton->setSelected(false);
selButton = static_cast<PaletteToolbarButton*> (sender());
selButton->setSelected(true);
emit colorChosen(newcolor);
}
void PaletteToolbar::resizeEvent ( QResizeEvent * event )
{
QToolBar::resizeEvent(event);
if (!arranging)
arrangeButtons();
}
void PaletteToolbar::expandButtonTriggered()
{
if (expanded)
setExpanded(false);
else setExpanded(true);
}
void PaletteToolbar::arrangeButtons()
{
if (buttonList.size()!=0)
{
arranging = true;
delete layoutWidget->layout();
QGridLayout* grid = new QGridLayout;
grid->setSpacing(2);
int cellWidth = buttonList.first()->minimumWidth()+2;
int cellHeight = buttonList.first()->minimumHeight()+2;
bool vert = orientation()==Qt::Vertical;
switch(static_cast<QMainWindow*>(parentWidget())->toolBarArea(this))
{
case Qt::LeftToolBarArea:
expandButton->setArrowType(expanded? Qt::LeftArrow : Qt::RightArrow);
break;
case Qt::RightToolBarArea:
expandButton->setArrowType(expanded? Qt::RightArrow : Qt::LeftArrow);
break;
case Qt::BottomToolBarArea:
expandButton->setArrowType(expanded? Qt::DownArrow : Qt::UpArrow);
break;
case Qt::TopToolBarArea:
expandButton->setArrowType(expanded? Qt::UpArrow : Qt::DownArrow);
break;
}
int ButtonsInRow,ButtonsInCol;
if (!expanded)
{
if (vert)
{
ButtonsInRow = 1;
ButtonsInCol = height() / cellHeight;
}
else //horizontal
{
ButtonsInCol = 1;
ButtonsInRow = width() / cellWidth;
}
}
else //ToolBar is expanded
{
if (vert)
{
ButtonsInCol = height() / cellHeight;
ButtonsInRow = (buttonList.size() + 1) / ButtonsInCol;
if ((buttonList.size() + 1) % ButtonsInCol) ++ButtonsInRow;
}
else //horizontal
{
ButtonsInRow = width() / cellWidth;
ButtonsInCol = (buttonList.size() + 1) / ButtonsInRow;
if ((buttonList.size() + 1) % ButtonsInRow) ++ButtonsInCol;
}
}
int Row = 0,Col = 0,i=0;
foreach(PaletteToolbarButton* button,buttonList)
{
grid->addWidget(button,Row,Col);++i;
if (vert)
{
++Row;
if (Row >= ButtonsInCol - 1)
{
if (Col >= ButtonsInRow - 1)
{
break;
}
else
{
++Col;
Row = 0;
}
}
}
else //horizontal
{
++Col;
if (Col >= ButtonsInRow - 1)
{
if (Row >= ButtonsInCol - 1)
{
break;
}
else
{
++Row;
Col = 0;
}
}
}
}//foreach
grid->addWidget(expandButton,Row,Col);
layoutWidget->setLayout(grid);
arranging = false;
}//if (buttonList.size()!=0)
}
To copy to clipboard, switch view to plain text mode
in the constructor of the class derived from QMainWindow:
QList<QColor> colorlist;
{
colorlist.
append(QColor(name
));
}
palette = new PaletteToolbar(colorlist);
addToolBar(Qt::RightToolBarArea,palette);
QStringList names = QColor::colorNames();
QList<QColor> colorlist;
foreach(QString name, names)
{
colorlist.append(QColor(name));
}
palette = new PaletteToolbar(colorlist);
addToolBar(Qt::RightToolBarArea,palette);
To copy to clipboard, switch view to plain text mode
thanks in advance!
Bookmarks