Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QMainWindow auto resize
QtWS25 Last Chance

QMainWindow auto resize

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 2.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tomy
    wrote on 21 Jul 2019, 07:04 last edited by tomy
    #1

    Hi all,

    Please take a look at these files:

    List.h:

    #ifndef LIST_H
    #define LIST_H
    
    #include <QMainWindow>
    #include "task.h"
    #include <QVector>
    
    class QLabel;
    class QPushButton;
    class QHBoxLayout;
    class QVBoxLayout;
    
    class List : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit List(QWidget *parent = nullptr);
        void updateStatus();
        ~List();
    
    public slots:
        void addTask();
        void removeTask(Task*);
        void taskStatusChanged();
    
    private:
        QVector<Task*> mTasks;
        QLabel* statusLabel;
        QPushButton* addTaskButtun;
        QHBoxLayout* hBox;
        QVBoxLayout* vBox;
    };
    
    #endif // LIST_H
    

    List.cpp:

    #include "list.h"
    #include <QPushButton>
    #include <QLabel>
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include <QString>
    #include <QInputDialog>
    #include <QLineEdit>
    
    List::List(QWidget *parent)
        : QMainWindow(parent), mTasks()
    {
        statusLabel = new QLabel(tr("Status: 0 todo / 0 done"));
        addTaskButtun = new QPushButton(tr("Add task"));
    
        hBox = new QHBoxLayout;
        hBox->addWidget(statusLabel);
        hBox->addStretch();
        hBox->addWidget(addTaskButtun);
    
        vBox = new QVBoxLayout;
        vBox->addLayout(hBox);
        vBox->addStretch();
    
        QWidget *widget = new QWidget;
        widget->setLayout(vBox);
        setCentralWidget(widget);
    
        connect(addTaskButtun, &QPushButton::clicked, this, &List::addTask);
        updateStatus();
    }
    
    //************************************************
    
    void List::addTask() {
       bool ok;
       QString name = QInputDialog::getText(this, tr("Add Task"), tr("Task name"),
                                           QLineEdit::Normal, tr("Untitled task"), &ok);
    
       if(ok && !name.isEmpty()) {
           Task* task = new Task(name);
           connect(task, &Task::removed, this, &List::removeTask);
           connect(task, &Task::statusChanged, this, &List::taskStatusChanged);
           mTasks.append(task);
           vBox->addWidget(task);
           updateStatus();
       }
    }
    
    //*********************************************
    
    void List::removeTask(Task* task) {
       mTasks.removeOne(task);
       vBox->removeWidget(task);
       delete task;
       updateStatus();
    }
    
    //**************************************
    
    void List::taskStatusChanged() {
        updateStatus();
    }
    
    //************************************
    
    void List::updateStatus() {
        int completedCount = 0;
    
        for(auto t: mTasks)
            if(t->isCompleted())
                completedCount++;
    
        int todoCount = mTasks.size() - completedCount;
        statusLabel->setText(QString("Statuse: %1 todo / %2 completed")
                                    .arg(todoCount) .arg(completedCount));
    }
    
    //*****************************
    
    List::~List()
    {
        delete vBox;
    }
    
    

    Task.h:

    #ifndef TASK_H
    #define TASK_H
    
    #include <QWidget>
    #include <QString>
    
    class QCheckBox;
    class QPushButton;
    class QHBoxLayout;
    
    class Task : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Task(const QString&, QWidget* parent = nullptr);
    
        void setName(const QString&);
        QString name() const;
        bool isCompleted() const;
    
        ~Task();
    
    public slots:
        void rename();
    
    signals:
       void removed(Task*);
       void statusChanged(Task*);
    
    private slots:
       void checked(bool);
    
    private:
       QCheckBox* checkbox;
       QPushButton* editButton;
       QPushButton* removeButton;
       QHBoxLayout* hBox;
    };
    
    #endif // TASK_H
    
    

    Task.cpp:

    #include "task.h"
    #include "list.h"
    #include <QInputDialog>
    #include <QWidget>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QCheckBox>
    
    Task::Task(const QString& name, QWidget* parent) : QWidget (parent)
    {
        checkbox = new QCheckBox;
        editButton = new QPushButton(tr("Edit"));
        removeButton = new QPushButton(tr("Remove"));
    
        hBox = new QHBoxLayout;
        hBox->addWidget(checkbox);
        hBox->addStretch();
        hBox->addWidget(editButton);
        hBox->addWidget(removeButton);
    
        setLayout(hBox);
    
        setName(name);
    
        connect(editButton, &QPushButton::clicked, this, &Task::rename);
        connect(removeButton, &QPushButton::clicked, [this]()->void {
            emit removed(this);
                });
        connect(checkbox, &QCheckBox::toggled, this, &Task::checked);
    };
    
    //*************************************
    
    void Task::setName(const QString& name) {
        checkbox->setText(name);
    }
    
    //********************************************
    
    QString Task::name() const {
        return checkbox->text();
    }
    
    //*****************************
    
    bool Task::isCompleted() const {
        return checkbox->isChecked();
    }
    
    //****************************************
    
    void Task::rename() {
        bool ok;
        QString value = QInputDialog::getText(this, tr("Edit task"), tr("Task name"),
                                              QLineEdit::Normal, this->name(), &ok);
        if(ok && !value.isEmpty())
            setName(value);
    }
    
    //************************************
    
    void Task::checked(bool checked) {
        QFont font(checkbox->font());
        font.setStrikeOut(checked);
        checkbox->setFont(font);
    
        emit statusChanged(this);
    }
    
    //**************************************************
    
    Task::~Task() {
        delete hBox;
    }
    
    

    When I add tasks "untitled task 1" to "untitled task 3", number 1 below:

    0_1563610239950_3.PNG

    then remove "untitled task 2", the frame/window doesn't shrink and the space for that task is just vacant, number 2. I like it to decrease and fit the remained tasks, like number 3. When a task is added, the window increases in size, so when one is removed, it should decreases in size too.

    I tested the followings one by one in void List::updateStatus() {, but none worked as expected!

    What should be used instead, please?

    this->sizeHint();
    this->update();
    this->resize(sizeHint());
    this->adjustSize();
    
    1 Reply Last reply
    0
    • K Offline
      K Offline
      Kerndog73
      wrote on 21 Jul 2019, 08:21 last edited by Kerndog73
      #2

      When the central widget resizes, call adjustSize on the window to make the window shrink to fit the size of the central widget. So, call adjustSize(); at the end of addTask and removeTask.

      T 1 Reply Last reply 21 Jul 2019, 08:28
      0
      • K Kerndog73
        21 Jul 2019, 08:21

        When the central widget resizes, call adjustSize on the window to make the window shrink to fit the size of the central widget. So, call adjustSize(); at the end of addTask and removeTask.

        T Offline
        T Offline
        tomy
        wrote on 21 Jul 2019, 08:28 last edited by
        #3

        @Kerndog73

        thanks for the answer. I used that:

        void List::removeTask(Task* task) {
           mTasks.removeOne(task);
           vBox->removeWidget(task);
           delete task;
           updateStatus();
           adjustSize();
        }
        

        But no changes in result! :|

        1 Reply Last reply
        0
        • K Offline
          K Offline
          Kerndog73
          wrote on 21 Jul 2019, 08:34 last edited by Kerndog73
          #4

          @tomy The central widget isn't being resized when widgets are removed from the vBox layout. Call setSizeConstraint to ensure that the layout will set the size of the parent widget when child widgets are added and removed. So call vBox->setSizeConstraint(QLayout::SetFixedSize); in the List constructor.

          T 1 Reply Last reply 21 Jul 2019, 08:51
          0
          • K Kerndog73
            21 Jul 2019, 08:34

            @tomy The central widget isn't being resized when widgets are removed from the vBox layout. Call setSizeConstraint to ensure that the layout will set the size of the parent widget when child widgets are added and removed. So call vBox->setSizeConstraint(QLayout::SetFixedSize); in the List constructor.

            T Offline
            T Offline
            tomy
            wrote on 21 Jul 2019, 08:51 last edited by
            #5

            @Kerndog73

            SizeConstraint and the fixedsize, as the names suggest, keep the size fixed, although it doesn't in effect and the window is being larger each time a new task is added. Of course, it doesn't work vice versa, Yet!

            I hoped there's a simple built-in function for that either in central widget or the window itself.

            J.HilkJ 1 Reply Last reply 22 Jul 2019, 05:48
            0
            • T tomy
              21 Jul 2019, 08:51

              @Kerndog73

              SizeConstraint and the fixedsize, as the names suggest, keep the size fixed, although it doesn't in effect and the window is being larger each time a new task is added. Of course, it doesn't work vice versa, Yet!

              I hoped there's a simple built-in function for that either in central widget or the window itself.

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on 22 Jul 2019, 05:48 last edited by
              #6

              @tomy
              don't let the name fool you, according to this thread, it's exactly what you're looking for, and the name- setSizeConstraint(QLayout::SetFixedSize);- is just misleading

              https://stackoverflow.com/questions/14980620/qt-layout-resize-to-minimum-after-widget-size-changes


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              T 1 Reply Last reply 22 Jul 2019, 06:08
              0
              • J.HilkJ J.Hilk
                22 Jul 2019, 05:48

                @tomy
                don't let the name fool you, according to this thread, it's exactly what you're looking for, and the name- setSizeConstraint(QLayout::SetFixedSize);- is just misleading

                https://stackoverflow.com/questions/14980620/qt-layout-resize-to-minimum-after-widget-size-changes

                T Offline
                T Offline
                tomy
                wrote on 22 Jul 2019, 06:08 last edited by
                #7

                @J.Hilk

                setSizeConstraint(QLayout::SetFixedSize);- is just misleading

                Do you mean it works in practice for the problem, even though the name suggests something else?
                But in effect, it doesn't solve the issue.

                0_1563775695542_3.png

                T 1 Reply Last reply 4 Apr 2020, 18:23
                0
                • T tomy
                  22 Jul 2019, 06:08

                  @J.Hilk

                  setSizeConstraint(QLayout::SetFixedSize);- is just misleading

                  Do you mean it works in practice for the problem, even though the name suggests something else?
                  But in effect, it doesn't solve the issue.

                  0_1563775695542_3.png

                  T Offline
                  T Offline
                  tomy
                  wrote on 4 Apr 2020, 18:23 last edited by
                  #8

                  @tomy

                  I didn't find a correct answer for my question here, but I like first to review most of the code. Starting from the header file task.h, on the top, we've got:

                  class Task : public QWidget
                  {
                      Q_OBJECT
                  

                  we here say that we need to inherit QWdiegt because without that, Task is a simple C++ class with no GUI. Right, completely?

                  This way, we both create a GUI widget and inherit worthwhile functions from QWidget. Right, once again?

                  But QWidget is a big and heavy class, the QWidget class is the base class of all user interface objects, while the output window we create using it ultimately is very simple:

                  1.PNG

                  Couldn't we inherit from a lighter class for that purpose?

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on 4 Apr 2020, 18:26 last edited by
                    #9

                    @tomy said in QMainWindow auto resize:

                    while the output window we create using it ultimately is very simple:

                    But it's still a widget what you want to show - so yes you must derive from QWidget and there is also no way around it (and also no need for it).

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    2

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved