Page 1 of 2 12 LastLast
Results 1 to 20 of 21

Thread: How to shrink a QMainWindow when its central widget is shrinked

  1. #1
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default How to shrink a QMainWindow when its central widget is shrinked

    Hi all,

    Please take a look at these files:

    List.h:

    Qt Code:
    1. #ifndef LIST_H
    2. #define LIST_H
    3.  
    4. #include <QMainWindow>
    5. #include "task.h"
    6. #include <QVector>
    7.  
    8. class QLabel;
    9.  
    10. class List : public QMainWindow
    11. {
    12. Q_OBJECT
    13.  
    14. public:
    15. explicit List(QWidget *parent = nullptr);
    16. void updateStatus();
    17. ~List();
    18.  
    19. public slots:
    20. void addTask();
    21. void removeTask(Task*);
    22. void taskStatusChanged();
    23.  
    24. private:
    25. QVector<Task*> mTasks;
    26. QLabel* statusLabel;
    27. QPushButton* addTaskButtun;
    28. QHBoxLayout* hBox;
    29. QVBoxLayout* vBox;
    30. };
    31.  
    32. #endif // LIST_H
    To copy to clipboard, switch view to plain text mode 

    List.cpp:

    Qt Code:
    1. #include "list.h"
    2. #include <QPushButton>
    3. #include <QLabel>
    4. #include <QHBoxLayout>
    5. #include <QVBoxLayout>
    6. #include <QString>
    7. #include <QInputDialog>
    8. #include <QLineEdit>
    9.  
    10. List::List(QWidget *parent)
    11. : QMainWindow(parent), mTasks()
    12. {
    13. statusLabel = new QLabel(tr("Status: 0 todo / 0 done"));
    14. addTaskButtun = new QPushButton(tr("Add task"));
    15.  
    16. hBox = new QHBoxLayout;
    17. hBox->addWidget(statusLabel);
    18. hBox->addStretch();
    19. hBox->addWidget(addTaskButtun);
    20.  
    21. vBox = new QVBoxLayout;
    22. vBox->addLayout(hBox);
    23. vBox->addStretch();
    24.  
    25. QWidget *widget = new QWidget;
    26. widget->setLayout(vBox);
    27. setCentralWidget(widget);
    28.  
    29. connect(addTaskButtun, &QPushButton::clicked, this, &List::addTask);
    30. updateStatus();
    31. }
    32.  
    33. //************************************************
    34.  
    35. void List::addTask() {
    36. bool ok;
    37. QString name = QInputDialog::getText(this, tr("Add Task"), tr("Task name"),
    38. QLineEdit::Normal, tr("Untitled task"), &ok);
    39.  
    40. if(ok && !name.isEmpty()) {
    41. Task* task = new Task(name);
    42. connect(task, &Task::removed, this, &List::removeTask);
    43. connect(task, &Task::statusChanged, this, &List::taskStatusChanged);
    44. mTasks.append(task);
    45. vBox->addWidget(task);
    46. updateStatus();
    47. }
    48. }
    49.  
    50. //*********************************************
    51.  
    52. void List::removeTask(Task* task) {
    53. mTasks.removeOne(task);
    54. vBox->removeWidget(task);
    55. delete task;
    56. updateStatus();
    57. }
    58.  
    59. //**************************************
    60.  
    61. void List::taskStatusChanged() {
    62. updateStatus();
    63. }
    64.  
    65. //************************************
    66.  
    67. void List::updateStatus() {
    68. int completedCount = 0;
    69.  
    70. for(auto t: mTasks)
    71. if(t->isCompleted())
    72. completedCount++;
    73.  
    74. int todoCount = mTasks.size() - completedCount;
    75. statusLabel->setText(QString("Statuse: %1 todo / %2 completed")
    76. .arg(todoCount) .arg(completedCount));
    77. }
    78.  
    79. //*****************************
    80.  
    81. List::~List()
    82. {
    83. delete vBox;
    84. }
    To copy to clipboard, switch view to plain text mode 

    Task.h:

    Qt Code:
    1. #ifndef TASK_H
    2. #define TASK_H
    3.  
    4. #include <QWidget>
    5. #include <QString>
    6.  
    7. class QCheckBox;
    8.  
    9. class Task : public QWidget
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. explicit Task(const QString&, QWidget* parent = nullptr);
    15.  
    16. void setName(const QString&);
    17. QString name() const;
    18. bool isCompleted() const;
    19.  
    20. ~Task();
    21.  
    22. public slots:
    23. void rename();
    24.  
    25. signals:
    26. void removed(Task*);
    27. void statusChanged(Task*);
    28.  
    29. private slots:
    30. void checked(bool);
    31.  
    32. private:
    33. QCheckBox* checkbox;
    34. QPushButton* editButton;
    35. QPushButton* removeButton;
    36. QHBoxLayout* hBox;
    37. };
    38.  
    39. #endif // TASK_H
    To copy to clipboard, switch view to plain text mode 


    Task.cpp:

    Qt Code:
    1. #include "task.h"
    2. #include "list.h"
    3. #include <QInputDialog>
    4. #include <QWidget>
    5. #include <QHBoxLayout>
    6. #include <QPushButton>
    7. #include <QCheckBox>
    8.  
    9. Task::Task(const QString& name, QWidget* parent) : QWidget (parent)
    10. {
    11. checkbox = new QCheckBox;
    12. editButton = new QPushButton(tr("Edit"));
    13. removeButton = new QPushButton(tr("Remove"));
    14.  
    15. hBox = new QHBoxLayout;
    16. hBox->addWidget(checkbox);
    17. hBox->addStretch();
    18. hBox->addWidget(editButton);
    19. hBox->addWidget(removeButton);
    20.  
    21. setLayout(hBox);
    22.  
    23. setName(name);
    24.  
    25. connect(editButton, &QPushButton::clicked, this, &Task::rename);
    26. connect(removeButton, &QPushButton::clicked, [this]()->void {
    27. emit removed(this);
    28. });
    29. connect(checkbox, &QCheckBox::toggled, this, &Task::checked);
    30. };
    31.  
    32. //*************************************
    33.  
    34. void Task::setName(const QString& name) {
    35. checkbox->setText(name);
    36. }
    37.  
    38. //********************************************
    39.  
    40. QString Task::name() const {
    41. return checkbox->text();
    42. }
    43.  
    44. //*****************************
    45.  
    46. bool Task::isCompleted() const {
    47. return checkbox->isChecked();
    48. }
    49.  
    50. //****************************************
    51.  
    52. void Task::rename() {
    53. bool ok;
    54. QString value = QInputDialog::getText(this, tr("Edit task"), tr("Task name"),
    55. QLineEdit::Normal, this->name(), &ok);
    56. if(ok && !value.isEmpty())
    57. setName(value);
    58. }
    59.  
    60. //************************************
    61.  
    62. void Task::checked(bool checked) {
    63. QFont font(checkbox->font());
    64. font.setStrikeOut(checked);
    65. checkbox->setFont(font);
    66.  
    67. emit statusChanged(this);
    68. }
    69.  
    70. //**************************************************
    71.  
    72. Task::~Task() {
    73. delete hBox;
    74. }
    To copy to clipboard, switch view to plain text mode 

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

    3.jpg

    then remove "untitled task 2", the frame/window doesn't shrink and the space for that task is just vacant, image number 2. I like it to decrease and fit the remained tasks, like image number 3. When a task is added, the window increases in size, so when one is removed, it should decrease 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?

    Qt Code:
    1. this->sizeHint();
    2. this->update();
    3. this->resize(sizeHint());
    4. this->adjustSize();
    To copy to clipboard, switch view to plain text mode 
    Last edited by franky; 21st July 2019 at 18:25.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    I think it is because in the List constructor, you add stretch to the vbox layout. The Task widgets you add go below that, so when you remove one, the stretch just expands to fill the empty space in between the hbox and the first remaining task.

    Try not using the stretch at all. If that doesn't work, try using QBoxLayout::insertWidget() instead of addWidget() (which appends the new widget to the end of the layout, thus "trapping" the stretch between it and the start of the layout). In this case, your code would look something like this (assuming you still add the stretch during construction):

    Qt Code:
    1. vbox->insertWidget( vbox->count() - 1, task );
    To copy to clipboard, switch view to plain text mode 

    I don't know if this will solve the non-shrink problem, but at least you won't have a gap when you remove a task because the stretch will always be at the end of the layout.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. The following user says thank you to d_stranz for this useful post:

    franky (22nd July 2019)

  4. #3
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Neither worked unfortunately!

    Without vBox->addStretch();, shrink won't be applied but merely we have a sparsely populated area, after removing some tasks:

    3.png

    And when I keep vBox->addStretch();, and use vBox->insertWidget(vBox->count() - 1, task); instead of vBox->addWidget(task);, we will have this, once again:

    3.png

  5. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Yes, your second screen shot is what I expected to see.

    What you will probably have to do is implement a resize() on your List window when you remove a Task. In that slot, get the size of the List window -before- removing the Task, get the size of the Task itself, remove it, then resize the List height to be the original height minus the Task height.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  6. The following user says thank you to d_stranz for this useful post:

    franky (22nd July 2019)

  7. #5
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Good, thanks. There's always a way in programming!

    I added the slot in List, but I think inside it, vBox should be resized, not? (And not the central widget of QMainWindow)

  8. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    The QMainWindow is in charge of resizing its contents. I am pretty sure it asks the layout for the central widget for its size hint and adds the frame, menu bars, toolbars, status bars sizes as appropriate. So if the vbox layout never shrinks, it will return a size hint that includes the empty space.

    But try it out to resize the vbox. If it works, it works. Riht now, I don't see any method in the QVBoxLayout class (or its base classes) that allows you to directly set the size.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. The following user says thank you to d_stranz for this useful post:

    franky (23rd July 2019)

  10. #7
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Thanks.

    I was actually much dealt with height() and width() in the List.cpp file, but these two both belong to the central widget and hence, I couldn't make the job done using them.
    How to access the height/width of the base class (QMainWindow) which is indeed in charge of the overall size, please, so that we can modify it when a remove is accomplished?

  11. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Your List class is derived from QMainWindow, isn't it? If your slots to add / remove new Task widgets are in the List class, then you can just call "height()" in those slots and you will get the height of the List widget. You then just call resize() after you compute the new height.

    You don't want to change the height using the pointer to the central widget because QMainWindow (List) and the layout won't let it happen.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  12. #9
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Your List class is derived from QMainWindow, isn't it? If your slots to add / remove new Task widgets are in the List class, then you can just call "height()" in those slots and you will get the height of the List widget. You then just call resize() after you compute the new height.
    I added resize(height() - 100, width()) to removeTask, (-100, just to test):

    Qt Code:
    1. void List::removeTask(Task* task) {
    2. mTasks.removeOne(task);
    3. vBox->removeWidget(task);
    4. delete task;
    5. updateStatus();
    6.  
    7. resize(height() - 100, width());
    8. }
    To copy to clipboard, switch view to plain text mode 

    When I hover the mouse on height(), this message is shown:
    inline int QWidget::height() const , so that QWidget in our example is List, right?

    So in that slot, when we use resize via a smaller height, the widget List must resize normally, and since this slot is called each time we remove a Task, therefore List is expected to shrink that way.

    But it doesn't work as expected!

  13. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    But it doesn't work as expected!
    Well, what does happen? Anything? Nothing?

    You should probably call "task->deleteLater()" instead of "delete task". You are in the middle of a slot, and control needs to return to the event loop so that Qt can clean up properly and take whatever other action is needed to redraw the UI. deleteLater() will delete the widget when the event loop runs.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  14. The following user says thank you to d_stranz for this useful post:

    franky (25th July 2019)

  15. #11
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Very good, thanks for the precious info. I use the function this way:

    Qt Code:
    1. void List::removeTask(Task* task) {
    2. mTasks.removeOne(task);
    3. vBox->removeWidget(task);
    4. task->deleteLater();
    5. updateStatus();
    6.  
    7. resize(height() - 100, width());
    8. }
    To copy to clipboard, switch view to plain text mode 

    After entering 5 tasks:

    3.PNG

    And then deleting the first four ones, I got this! It's actually the way I meant I doesn't work.

    4.PNG

  16. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Your last screen shot looks like you still have the spacer item as the first thing in the vbox. If the spacer item was at the end, task 5 would be pushed to the top of the layout. Instead, it looks like the spacer item is first and is pushing everything down.

    Please show your code for adding a new task to the list.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  17. #13
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Your last screen shot looks like you still have the spacer item as the first thing in the vbox.
    Yes. We firstly have a button and label of the list on the top, and to hold it on top we need the spacer which comes after these. Afterwards, in the addTask slot, we have this code, as before:

    Qt Code:
    1. void List::addTask() {
    2. bool ok;
    3. QString name = QInputDialog::getText(this, tr("Add Task"), tr("Task name"),
    4. QLineEdit::Normal, tr("Untitled task"), &ok);
    5.  
    6. if(ok && !name.isEmpty()) {
    7. Task* task = new Task(name);
    8. connect(task, &Task::removed, this, &List::removeTask);
    9. connect(task, &Task::statusChanged, this, &List::taskStatusChanged);
    10. mTasks.append(task);
    11. vBox->addWidget(task);
    12. updateStatus();
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 

  18. #14
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    We firstly have a button and label of the list on the top, and to hold it on top we need the spacer which comes after these.
    Well, that's the problem. Your code calls addWidget() instead of insertWidget() (see my post from earlier in this thread), which means that the spacer stays at the top of the vbox and pushes both up and down. The button and label get pushed up and the tasks get pushed down. When you add new tasks, this results in the window expanding. When you remove a task, the spacer just expands to add more space between the top and the remaining tasks and the window doesn't shrink.

    When you add a task, you need to insert it -above- the spacer so that the spacer is always the last thing in the vbox. When you remove a task, you need to resize the window so the spacer will shrink.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  19. #15
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Yes, thank you. These are right in theory, but when tested in practice, the result is quite different!

    I did these:
    Firstly removed vBox->addStretch(); in List's constructor. Then changed void List::addTask() to this:


    Qt Code:
    1. void List::addTask() {
    2. bool ok;
    3. QString name = QInputDialog::getText(this, tr("Add Task"), tr("Task name"),
    4. QLineEdit::Normal, tr("Untitled task"), &ok);
    5.  
    6. if(ok && !name.isEmpty()) {
    7. Task* task = new Task(name);
    8. connect(task, &Task::removed, this, &List::removeTask);
    9. connect(task, &Task::statusChanged, this, &List::taskStatusChanged);
    10. mTasks.append(task);
    11. vBox->insertWidget(vBox->count()-1, task);
    12. vBox->addStretch();
    13. updateStatus();
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 

    And here's also:

    Qt Code:
    1. void List::removeTask(Task* task) {
    2. mTasks.removeOne(task);
    3. vBox->removeWidget(task);
    4. task->deleteLater();
    5. updateStatus();
    6.  
    7. resize(height() - 100, width());
    8. }
    To copy to clipboard, switch view to plain text mode 

    The result is:

    3.PNG

    Why don't you test the project once?

  20. #16
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Why don't you test the project once?
    Because I have my own code to write...

    In your addTask() slot, lines 11 and 12, you are adding a new stretch item every time you add a new task, but in the removeTask() slot, you are only removing the task widget. So you end up with a vbox that contains one stretch item for every task you add, and they never go away. So when you call insertWidget(), you are probably putting the new task in between two stretch items and then sticking a new stretch item onto the end of that.

    Going back to your original post in this thread, you are building the central widget by:

    1 - creating a generic QWidget to act as the central widget.
    2 - adding a vbox as its layout.
    3 - inserting an hbox layout with your buttons, etc. as the first item in the vbox
    4 - adding a stretch to the end of the vbox to push the hbox to the top of the vertical layout

    OK so far. Your desired behavior is for the main window to grow as you add Task items (widgets) to it and to shrink as they are removed.

    To add a new task, you want to insert it between the stretch item (which is always at the bottom of the vbox) and whatever is above it (the hbox, more tasks, whatever).

    After the initial construction of the vbox, the item count is 2 (the hbox and the stretch). So you want to call insertWidget() with the argument count - 1. You do not add new stretch and you do not change the position of the stretch that you added at the start. It always stays at the bottom of the vbox and everything else goes above it and below the hbox.

    To add more tasks to the list, you do exactly the same - insertWidget with count - 1 as the position argument.

    To remove a task, your existing code should be OK. Find the task widget in the vbox, take it, then resize the vbox to remove the space taken up by the widget you just removed. The stretch still stays at the bottom and the hbox at the top, unchanged.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  21. #17
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    Only these parts are changed compared to the first code:

    Qt Code:
    1. List::List(QWidget *parent)
    2. : QMainWindow(parent), mTasks()
    3. {
    4. statusLabel = new QLabel(tr("Status: 0 todo / 0 done"));
    5. addTaskButtun = new QPushButton(tr("Add task"));
    6. cWidget = new QWidget;
    7.  
    8. hBox = new QHBoxLayout;
    9. hBox->addWidget(statusLabel);
    10. hBox->addStretch();
    11. hBox->addWidget(addTaskButtun);
    12.  
    13. vBox = new QVBoxLayout;
    14. vBox->addLayout(hBox);
    15. vBox->addStretch();
    16.  
    17. cWidget->setLayout(vBox);
    18. setCentralWidget(cWidget);
    19.  
    20. connect(addTaskButtun, &QPushButton::clicked, this, &List::addTask);
    21. updateStatus();
    22. }
    23.  
    24. //************************************************
    25.  
    26. void List::addTask() {
    27. bool ok;
    28. QString name = QInputDialog::getText(this, tr("Add Task"), tr("Task name"),
    29. QLineEdit::Normal, tr("Untitled task"), &ok);
    30.  
    31. if(ok && !name.isEmpty()) {
    32. Task* task = new Task(name);
    33. connect(task, &Task::removed, this, &List::removeTask);
    34. connect(task, &Task::statusChanged, this, &List::taskStatusChanged);
    35. mTasks.append(task);
    36. vBox->insertWidget(vBox->count()-1, task);
    37. updateStatus();
    38. }
    39. }
    40.  
    41. //*********************************************
    42.  
    43. void List::removeTask(Task* task) {
    44. mTasks.removeOne(task);
    45. vBox->removeWidget(task);
    46. task->deleteLater();
    47. updateStatus();
    48. resize(height() - task->height(), task->width()); // Here we resize the window, List
    49. }
    To copy to clipboard, switch view to plain text mode 


    The outcome is not very bad but still far from a decent app!

    3.PNG

    4.PNG

  22. #18
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    OK, here's one last thing to try. The stretch at the bottom really seems to be messing things up when trying to dynamically resize the main window.

    In removeTask(), try this:

    - remove the task.
    - remove the stretch
    - resize the height
    - add the stretch back in

    If this still doesn't work, then I will implement some code and solve it. It can't be this hard.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  23. #19
    Join Date
    Jan 2016
    Posts
    76
    Thanks
    28
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    A question, in vBox->insertWidget(vBox->count()-1, task);
    Isn't "count" one beyond the last element? And "count-1" the last indeed element? Also, isn't "stretch" counted as an element in the layout?

    Anyway, I used this for the function:

    Qt Code:
    1. void List::removeTask(Task* task) {
    2. mTasks.removeOne(task);
    3. vBox->removeWidget(task);
    4. task->deleteLater();
    5. delete vBox->takeAt(vBox->count()-1);
    6. resize(height() - task->height(), task->width()); // Here we resize the window, List
    7. vBox->addStretch();
    8. updateStatus();
    9. }
    To copy to clipboard, switch view to plain text mode 

    And after adding a number of task and removing them continually reaching the fist task, the following result emerged:

    1.PNG

  24. #20
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to shrink a QMainWindow when its central widget is shrinked

    The "index" argument in insertWidget() is the place where the new widget will be placed. So if the vbox has two items in it (the hbox and the stretch), count = 2, count - 1 = 1, so the widget will be inserted at index 1, which is between the hbox and the stretch. The stretch becomes index 3. The hbox stays at index 0.

    So in order for insertWidget( vbox->count() - 1 ) to work correctly, there has to be a minimum of two items in the vbox, so you have to build it with the hbox and the stretch in place before you start adding tasks. If you don't have the stretch, then the first task will be added at 0, on top of the hbox. Subsequent tasks will be added on top of the hbox as well.

    If I can find time, I will work on this sometime before the end of the week.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  25. The following user says thank you to d_stranz for this useful post:

    franky (31st July 2019)

Similar Threads

  1. Replies: 1
    Last Post: 10th August 2014, 22:06
  2. Replies: 0
    Last Post: 28th March 2013, 01:22
  3. Widget auto shrink
    By been_1990 in forum Qt Programming
    Replies: 9
    Last Post: 24th January 2013, 02:43
  4. Replies: 8
    Last Post: 28th June 2011, 15:57
  5. Central Widget of QMainWindow
    By sumsin in forum Qt Programming
    Replies: 3
    Last Post: 13th March 2006, 19:32

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.