Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Rendering in Vertical Layout fails to occur



  • So, for this problem, I am trying to create a timeline app for visualization of certain time-sensitive requirements information and have begun experimentation with Qt since I am new to it. The problem I am having is that the rendered object will show up if I render it just basically on the main background, but when I tried to add the TimeLine objects to the vertical layout I have on my UI they refuse to render.

    Here is my main window code for creating the objects:

    void MainWindow::drawTimelines()
    {
        for(int i=0; i <= 3; i++)
        {
            TimeLine *tl = new TimeLine(this, this);
    //        ui->verticalLayout->addWidget(tl, 0, Qt::AlignLeft);
    
            tl->lower();
            QPoint * dest = new QPoint(this->width() - (this->width() / 12), i * this->height() / 4 + this->height() / 4);
            QPoint * src = new QPoint(this->width() / 12, i * this->height() / 4 + this->height() / 4);
    
    //        tl->setGeometry(0, 0, this->width(), 100);
            tl->setGeometry(src->x(), src->y(), this->width(), 100);
            tl->updateGeometry();
    
            QPoint *startPt = new QPoint(src->x(), 50);
            QPoint *endPt = new QPoint(dest->x(), 50);
    //        QPoint *src = new QPoint(this->width() /8, 50);
    //        QPoint *dest = new QPoint(this->width() - (this->width() / 8), 50);
    
            tl->setSrcPt(startPt);
            tl->setDestPt(endPt);
            tl->setNumSegments(3);
    
            timeLineList.push_back(tl);
            timeLineList.at(i)->show();
        }
        update();
    }
    

    Here is the maint function present in the TimeLine object itself:

    void TimeLine::paintEvent(QPaintEvent * event)
    {
        QRectF frame(QPointF(sourcePoint->x(), sourcePoint->y()), geometry().size());
    
        QPainter painter(this);
        painter.setPen(QPen(Qt::FlatCap));
        painter.drawRoundedRect(frame, 10.0, 10.0);
    
        int translateAmount = sourcePoint->y() - window->getPainterY();
        painter.translate(0, translateAmount);
    //    window->setPainterY(translateAmount);
    
        painter.drawLine(sourcePoint->x(), 25, destPoint->x(), 25);
    
        for(int i = 0; i <= numSegments; i++){
            int xPoint = ((destPoint->x() - sourcePoint->x()) * i / numSegments) + sourcePoint->x();
            int yPoint = 25;
            painter.drawLine(xPoint, yPoint + 20, xPoint, yPoint - 20);
        }
    
        QWidget::paintEvent(event);
    }
    

    Here is a screen shot of my .ui file :
    76ba2c50-82dc-49b5-bb3f-fae9b5d88b61-image.png

    And lastly here is a screenshot of what my output looks like when I DON'T put the TimeLine objects in the layout just so you can see what sort of thing I'm going for (normal the TimeLines would be under the text edit due to the layout placement, but you get the idea):
    7bde276b-36e6-4fb9-9989-63467a47469e-image.png

    The TimeLines (and bounded rect boxes) do not render when I have the

    //        ui->verticalLayout->addWidget(tl, 0, Qt::AlignLeft);
    

    uncommented. As you can see from a bunch of the other commented lines, I have tried numerous other things to try and render these TimeLines. I have tried:

    • changing reference points of the geometry to be (0,0) for the new segment of the vertical layout
    • changing the size of the geometry
    • both translating and not translating the painter
    • changing line thickness, type of line, etc.
    • even tried rendering something else simple in the vertical layout

    The part that confuses me is that even the bounded rect made based on the geometry of the TimeLine frame gets cut off even when rendered on the normal screen. I am guessing I am just missing something dumb, but I am at my wit's end. Any suggestions? Thank you so much in advance.


  • Lifetime Qt Champion

    Hi,

    Your vertical layout should be applied to the central widget and then you should put your other widgets in an horizontal layout in that vertical layout to keep your current design.



  • @SGaist will that fix the rendering error? was it just that the vertical layout was not wide enough? Also, thanks for the response.


  • Lifetime Qt Champion

    Layouts do not have physical representation, they are applied to a widget. You should not have them floating around.



  • @SGaist I 100% agree with this and made the change. But even with it, the timelines do not render in the vertical layout. Am I wrong to assume the coordinates of each "box" in the layout reset to have its own (0,0) origin? Do I need to find the coordinates of the "box" before attempting to set the geometry and then paint the TimeLine?


  • Lifetime Qt Champion

    Each widget has it's own "canevas" that does not depend on its position on the screen (or widget hierarchy).
    So if there's an issue with incomplete rendering, you are likely not providing a suitable size hint from your TimeLine widget or not taking the size properly into account when painting.


  • Lifetime Qt Champion

    Hi
    From inside paintEvent
    0,0 is always top left regardless of where widgets is placed on the form.
    (and you dont use translate on the painter)

    You could try

    void TimeLine::paintEvent(QPaintEvent * event)
    {
        QPainter painter(this);
        painter.drawRectangle(0,0, Width()-1, Height()-1);
    }
    

    and see if you can spot if it has the wrong size or what is going on.



  • Someone on StackOverflow gave me the key that I needed. I was not setting a minimumSize for the TimeLines and as a result it was not being given enough space in the verticalLayout. Thanks for all the help!