6

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.

3 Answers 3

7

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

2

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.

1
  • Will this still be accurate though? Commented Apr 17, 2018 at 16:43
0

You can use one widget instead of tree and draw the content (step 1, step 2...) in the widget's paintEvent() function. On mouse click (or other) event you can calculate on which of the virtual buttons the event occurred and perform the corresponding action.

Not the answer you're looking for? Browse other questions tagged or ask your own question.