Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design buttons with custom shapes in QT

Tags:

button

qt

qt4

I am trying to desing in Qt a sequence of custom buttons with arrow shape but I could not find the way. I need something like the buttons that you can see in the next picture in order to manage the workflow of my program and guide the user through it. workflow guide buttons The texts of the images should be "Step 1", "Step 2" and "Step 3". Sorry for the mistake. Any help or suggestion is welcome. Thanks for your help.

like image 413
Luis López Avatar asked Apr 22 '15 11:04

Luis López


2 Answers

header file:

public:

void paintEvent(QPaintEvent* event); //--> drawing triangles
void createPushButtons(); 
const static int firstButtonX = 0; //--> topleft corner x value of first button 
const static int firstButtonY = 0; //--> topleft corner y value of first button 
const static int buttonWidth = 50;
const static int buttonHeight = 30;
const static int triangleWidth = 30;
QList<QColor> colors; //--> button colors

cpp file:

I populate colors list with button colors.

colors.append(Qt::red);
colors.append(Qt::blue);
colors.append(Qt::yellow);

and call createPushButtons(); function to create pushButtons.

void MainWindow::createPushButtons()
{
    QWidget * wdg = new QWidget(this);//--> widget contains pushButtons
    wdg->setObjectName("buttonWidget");//--> I set object name in order to catch widget and pushButtons in PaintEvent()
    setCentralWidget(wdg);//--> I add widget to app main layout

    for(int i=0; i<colors.size(); i++)//--> Button count and color count must be same.
    {
        QPushButton *btn = new QPushButton(QString::number(i)+". button",wdg);//--> create pushButtons in parent wdg
        btn->setGeometry(firstButtonX + (buttonWidth+triangleWidth)*i, firstButtonY, buttonWidth, buttonHeight);//--> I set geometry for pushButtons 

        btn->setStyleSheet(QString("background-color: %1;border-style: outset;border-width: 0px;").arg(colors.at(i).name()));//--> I change background color and clear border
    }
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QWidget *wdg = findChild<QWidget *>("buttonWidget");//--> I catch my widget
    QList<QPushButton *> buttons = wdg->findChildren < QPushButton *>();//--> I find pushButtons

    for(int i=0;i < buttons.size(); i++)
    {
        int x = buttons.at(i)->pos().x();//--> measurements for triangle
        int y = buttons.at(i)->pos().y();
        int w = buttons.at(i)->width();
        int h = buttons.at(i)->height();

        QRect r(x+w,y,triangleWidth,h);//--> I create rectangular area between pushButtons

        QPainter painter(this);
        qreal point3X = x+w + triangleWidth;//--> triangle corners
        qreal point3Y = y + h/2 ;
        qreal point1X = x+w;
        qreal point1Y = y;
        qreal point2X = x+w;
        qreal point2Y = y+h;

        QPainterPath path;
        path.moveTo (point1X, point1Y);
        path.lineTo (point2X, point2Y);
        path.lineTo (point3X, point3Y);

        painter.setPen (Qt :: NoPen);
        if(i != buttons.size()-1)//--> I paint rectangular and triangle
        {
            painter.fillRect(r, QBrush (colors.at(i+1)));
        }
        painter.fillPath (path, QBrush (colors.at(i)));
    }
}

result is

you can look result

like image 85
utarid Avatar answered Oct 10 '22 17:10

utarid


If you do not want to do all the painting yourself you can use three normal QPushButtons with setIcon() to contain your custom graphic cut in three parts as while setting the flat property to true.

It is probably required to group them in a parent widget to control their position and sizes, depending on your layout.

like image 35
Bowdzone Avatar answered Oct 10 '22 17:10

Bowdzone