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

Problems with setting geometry to a widget and alignement



  • Hi,

    I use QWT library (multiaxes branch). It has QwtPlotWiget() widget. QwtPlotWidget() has QwtCanvas() where all the graphics is done.
    I need create two QwtPlotWidget() one above another and the should have the same X position of canvas (x corner position and length of each canvas should be equal).
    To achieve that I'm trying to set spacing QBoxLayout::insertSpacing(int index, int size) to lower QHBoxLayout wich has lower QwtPlotWidget(). The size of spacing is equal to difference between X-position of upper and lower canvas.
    Here is the code:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QLayout>
    #include <qwt_plot.h>
    #include <qwt_scale_widget.h>
    #include <qwt_scale_div.h>
    #include <qwt_scale_draw.h>
    #include <qwt_scale_map.h>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        upperPlot = new QwtPlot(this);
        lowerPlot = new QwtPlot(this);
        upperPlot->setAxesCount(QwtAxis::yLeft, 2);
    
        upperPlot->axisWidget(QwtAxisId(QwtAxis::yLeft, 0))->setTitle("title_1");
        upperPlot->axisWidget(QwtAxisId(QwtAxis::yLeft, 1))->setTitle("title_2");
    
        upperPlot->setMinimumSize(10,10);
        lowerPlot->setMinimumSize(10,10);
    
        QWidget* mainWidget = new QWidget;
        QVBoxLayout* mainLayout = new QVBoxLayout(mainWidget);
    
        QWidget* lowerWidget = new QWidget;
        lowerLayout = new QHBoxLayout(lowerWidget);
        lowerLayout->setContentsMargins(0, 0, 0, 0);
        lowerLayout->addWidget(lowerPlot);
    
        mainLayout->addWidget(upperPlot);
        mainLayout->addWidget(lowerWidget);
    
        setCentralWidget(mainWidget);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::showEvent(QShowEvent *event){
        upperPlot->updateGeometry();
        lowerPlot->updateGeometry();
        upperPlot->canvas()->updateGeometry();
        lowerPlot->canvas()->updateGeometry();
    
        int dx = upperPlot->canvas()->geometry().x() - lowerPlot->canvas()->geometry().x();
        lowerLayout->insertSpacing(0, dx);
    }
    
    

    But I get some misfits in the result. Does anybody has idea why it doesn't work?
    1.png


  • Lifetime Qt Champion

    Hi,

    Why not use a QGridLayout ?



  • There is something wrong with geometry, like it gives me wrong size.
    I copied the picture of mainwindow to a Paint (on Windows) and I figured out that in general size of mainwindow in Qt is the same as in Paint (+-3 pixels).
    But when I get geometry->x() to a canvas Qt tells me that its value is equal to 174 pixels but in Paint I can see that it is about 210 pixels (see picture attached).
    1.png



  • @SGaist upper plot already has its own layout where are few X/Y axes and canvas widgets. I can add this plot only with those widgets in a cell. I think I can't divide any of plot to a canvas widget, X-axis widget, Y-axis etc and put them separetely in different cells
    Or I misunderstood your Idea?



  • @SGaist the whole day I spent for that problem and finally I've found the reason why it gives me the wrong geometry :)
    This is because I use showEevent() method which gives me geometry BEFORE layout is applied.
    I just renamed showEvent() to a mouseDoubleClickEvent(QMouseEvent *event) and I doubleclick on window when it appears and everything works fine (see picture).
    Is there a QMainWindow() method wich starts working after layouts are applied and where I could put my code with geometry settings?
    2.png


  • Lifetime Qt Champion

    You should rather build a custom widget dedicated to your plots layout and do things directly there.



  • In myWidget I reimplemented QWidget::resizeEvent(QResizeEvent *event) and put there a signal.
    Then In other class I connected this signal with slot void WiggleObjectCreator::onCanvasSizeChanged(QResizeEvent* event).
    This slot changes the geometry of myWidget but I need to do it without sending signals.
    I tried something like:

    void WiggleObjectCreator::onCanvasSizeChanged(QResizeEvent* event){
        myWidget->blockSignals(true);
    
    	myWidget->setFixedWidth(myWidget->width() + 10);
    
        myWidget->blockSignals(false);
    }
    

    but seems to me that signals still invoke this slot recursively.
    How to change geometry of widget in such type of slot and avoid recursion?


  • Lifetime Qt Champion

    @Please_Help_me_D
    Hi
    Events are not signals so they are not blocked with blockSignals
    Since its not WiggleObjectCreator but myWidget you alter size on, it must affect the size of
    WiggleObjectCreator in a way still for this to become recursive.



  • @mrjj could you recommend me a way to vertically align canvas of these two qwPlot widgets when number of axes at left and at right is changeable?
    I was thinking about putting these two qwtPlot in two horizontal layouts and then add them to vertical layout and call insertSapcing(...) in each horizontal layout (where those qwtPlot are) every time the parent widget is resized


Log in to reply