简体   繁体   English

Qt QWidget :: minimumSizeHint延迟

[英]Qt QWidget::minimumSizeHint delay

I want to write dialog with "spoiler". 我想用“扰流板”编写对话框。 When I show/hide some elements, the form must resize to match her content. 当我显示/隐藏某些元素时,表单必须调整大小以匹配她的内容。 But I noticed that minimumSizeHint works with some delay. 但是我注意到minimumSizeHint会有一些延迟。 For example I wrote following dialog code: 例如,我编写了以下对话框代码:

dialog.h dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

class Dialog : public QDialog {
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);

private:
    QPushButton *button1, *button2, *button3;
    void adjust();
};

#endif // DIALOG_H

dialog.cpp dialog.cpp

#include <QVBoxLayout>
#include <QPushButton>
#include <QTimer>

#include "dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent) {
    QVBoxLayout *layout = new QVBoxLayout;
    button1 = new QPushButton("bad method", this);
    button2 = new QPushButton("working method", this);
    button3 = new QPushButton("indent", this);
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(button3);
    setLayout(layout);

    connect(button1, &QPushButton::pressed, [=]() {
        button3->setVisible(!button3->isVisible());

        adjust();
    });

    connect(button2, &QPushButton::pressed, [=]() {
        button3->setVisible(!button3->isVisible());

        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, [=](){ adjust(); });
        timer->setSingleShot(true);
        timer->start(0);
    });
}

void Dialog::adjust() {
    resize(width(), minimumSizeHint().height());
}

When pressed button1, the form isn't match her content tightly, but when pressed button2, the form tightly match her content. 按下button1时,表单与她的内容不完全匹配,但是按下button2时,表单与她的内容紧密匹配。 How to achieve results as pressing button2 without timers and other workarounds? 在没有计时器和其他变通方法的情况下,如何获得按button2的效果? Why button1 isn't work? 为什么button1不起作用?

Consider that the minimum size is not computed until some events are processed in the event loop. 考虑到只有在事件循环中处理了一些事件之后,才计算最小大小。 If you don't want to use a timer, one workaround is to process the event loop for some iterations after the button is hidden or made visible, and then adjust size. 如果您不想使用计时器,一种解决方法是在按钮隐藏或显示后处理事件循环进行某些迭代,然后调整大小。

It's like : 就像是 :

        button3->setVisible(!button3->isVisible());

        for(int i=0;i<10;i++)
           qApp->processEvents();

        adjust();

A better solution is to call QLayout::activate() before resizing: 更好的解决方案是在调整大小之前调用QLayout::activate()

        button3->setVisible(!button3->isVisible());

        layout->activate();

        adjust();

activate() forces your layout to recalculate the size hint. activate()强制您的布局重新计算大小提示。

I tried the QLayout::activate() solution, but it doesn't work for me. 我尝试了QLayout::activate()解决方案,但对我而言不起作用。

QLayout::activate() returns false . QLayout::activate()返回false

This is my code: this is a QMainWindow . 这是我的代码: thisQMainWindow

ui.groupBox->setVisible(!ui.groupBox->isVisible());

qDebug() << this->layout()->activate();

qDebug() << this->minimumSizeHint();

this->resize(this->minimumSizeHint());

any ideas why it's not working? 任何想法为什么它不起作用?

My current workaround is: 我当前的解决方法是:

QTimer::singleShot(10, this, SLOT(on_resizeMin()));

but i noticed 10ms may not be enough on a slow system. 但我注意到10ms在慢速系统上可能还不够。 Nasty workaround. 讨厌的解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM