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

Widget "shakes" during resizing. Any solution?



  • In my UI design, I want four QPushButtons stay on the right side of window. So I create a HBoxLayout for the centralWidget, and add a QWidget and a VBoxLayout(which contains the four buttons) to it. The stretch factor for the VBoxLayout is set to 0, so that it will stays stay on the right side with a minimum width.

    However, when I try to resize the window from the left, my QPushButtons kind of "shakes" during resizing, which brings a very bad looking.

    So what might be the reason for this? Is there any solution that such "shaking" can be avoided?
    alt text

    Qt version: 5.15.0, windows 64bit

    A reproducible example:
    mainwindow.ui:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0">
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
          <item>
           <widget class="QWidget" name="widget" native="true"/>
          </item>
          <item>
           <layout class="QVBoxLayout" name="verticalLayout_2">
            <item>
             <widget class="QPushButton" name="pushButton">
              <property name="text">
               <string>PushButton</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
         </layout>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>800</width>
         <height>23</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    Or the auto-generated ui_mainwindow.h:

    /********************************************************************************
    ** Form generated from reading UI file 'mainwindow.ui'
    **
    ** Created by: Qt User Interface Compiler version 5.15.0
    **
    ** WARNING! All changes made in this file will be lost when recompiling UI file!
    ********************************************************************************/
    
    #ifndef UI_MAINWINDOW_H
    #define UI_MAINWINDOW_H
    
    #include <QtCore/QVariant>
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QHBoxLayout>
    #include <QtWidgets/QMainWindow>
    #include <QtWidgets/QMenuBar>
    #include <QtWidgets/QPushButton>
    #include <QtWidgets/QStatusBar>
    #include <QtWidgets/QVBoxLayout>
    #include <QtWidgets/QWidget>
    
    QT_BEGIN_NAMESPACE
    
    class Ui_MainWindow
    {
    public:
        QWidget *centralwidget;
        QHBoxLayout *horizontalLayout_2;
        QHBoxLayout *horizontalLayout;
        QWidget *widget;
        QVBoxLayout *verticalLayout_2;
        QPushButton *pushButton;
        QMenuBar *menubar;
        QStatusBar *statusbar;
    
        void setupUi(QMainWindow *MainWindow)
        {
            if (MainWindow->objectName().isEmpty())
                MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
            MainWindow->resize(800, 600);
            centralwidget = new QWidget(MainWindow);
            centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
            horizontalLayout_2 = new QHBoxLayout(centralwidget);
            horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
            horizontalLayout = new QHBoxLayout();
            horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
            widget = new QWidget(centralwidget);
            widget->setObjectName(QString::fromUtf8("widget"));
    
            horizontalLayout->addWidget(widget);
    
            verticalLayout_2 = new QVBoxLayout();
            verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
            pushButton = new QPushButton(centralwidget);
            pushButton->setObjectName(QString::fromUtf8("pushButton"));
    
            verticalLayout_2->addWidget(pushButton);
    
    
            horizontalLayout->addLayout(verticalLayout_2);
    
            horizontalLayout->setStretch(0, 1);
    
            horizontalLayout_2->addLayout(horizontalLayout);
    
            MainWindow->setCentralWidget(centralwidget);
            menubar = new QMenuBar(MainWindow);
            menubar->setObjectName(QString::fromUtf8("menubar"));
            menubar->setGeometry(QRect(0, 0, 800, 23));
            MainWindow->setMenuBar(menubar);
            statusbar = new QStatusBar(MainWindow);
            statusbar->setObjectName(QString::fromUtf8("statusbar"));
            MainWindow->setStatusBar(statusbar);
    
            retranslateUi(MainWindow);
    
            QMetaObject::connectSlotsByName(MainWindow);
        } // setupUi
    
        void retranslateUi(QMainWindow *MainWindow)
        {
            MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
            pushButton->setText(QCoreApplication::translate("MainWindow", "PushButton", nullptr));
        } // retranslateUi
    
    };
    
    namespace Ui {
        class MainWindow: public Ui_MainWindow {};
    } // namespace Ui
    
    QT_END_NAMESPACE
    
    #endif // UI_MAINWINDOW_H
    

    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp:

    #include "mainwindow.h"
    #include "./ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    main.cpp:

    #include "mainwindow.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    What version of Qt are you using ?
    On what OS ?
    Can you provide a minimal compilable example that shows that issue ?



  • This post is deleted!


  • @SGaist Thanks! Detailed information is already updated in the description.



  • Does anybody take a look at this problem? Thanks a lot.


  • Moderators

    Qt uses double buffering to draw onto a surface that is then drawn in the window. Position of widgets is governed by the layout which does its work in resize event. Resize event is triggering Qt repaint which then triggers native blit. All this can add a 1 or 2 frame latency so when Qt is painting it can have size or layout information from a frame or two before. Not much you can do about it I'm afraid. Aligning widgets to right or bottom just sucks (on Windows at least).



  • @Arsenal591
    I don't really know, but can't you make the pane to the right of the thin line which holds the buttons be a fixed width, and then maybe it would need to move/redraw/"wobble"?



  • I literally just came across something like this in the Qt documentation while searching for something entirely separate. Typing mouse shaking in the documentation search box brings it up. It mentions using global mouse coordinates.

    I don't know for sure if this will address the problem, but it should be worth a look.


Log in to reply