简体   繁体   English

Qt-QPropertyAnimation中有错误吗?

[英]Qt - There is a bug in QPropertyAnimation?

I face a very serious situation. 我面临着非常严重的情况。 By writing this question I hope that really professionals will express their opinion regarding to the problem I am going to describe. 通过写这个问题,我希望真正的专业人士会对我要描述的问题发表意见。 I have reported a bug in https://bugreports.qt.io/ : 我在https://bugreports.qt.io/中报告了一个错误:

I have created QPropertyAnimation for maximumWidth property of QTextEdit and it does not work (it immediately changes state from starting state to the end state), though it works for minimumWidth property. 我已经为QTextEdit的maximumWidth属性创建了QPropertyAnimation,尽管它适用于minimumWidth属性,但它无法正常工作(它将状态从开始状态立即更改为结束状态)。 Please see the attached code. 请参阅随附的代码。

And have attached .h and .cpp files. 并已附加.h和.cpp文件。 See those files here (files are named new.h and new.cpp). 在此处查看这些文件(文件名为new.h和new.cpp)。

And I got the follwing response: 我得到了以下回应:

MaximumWidth is not the property you want to animate. MaximumWidth不是要设置动画的属性。 It holds the maximum width that the widget can have, it's related to layouting and so on. 它保留了窗口小部件可以具有的最大宽度,它与布局等有关。 Changing the maximumWidth (as well as the minimumWidth) does not necessarily trigger a relayout and repaint. 更改maximumWidth(以及minimumWidth)不一定会触发重新布局和重新绘制。 You should animate the size. 您应该设置大小的动画。

Please explain me whether it is a bug or no? 请向我解释说它是错误还是没有? Please tell me how the minimumWith property is being animated but when it concerns to the maximumWidth property, then I should not work and that is OK? 请告诉我minimumWith属性是如何动画的,但是当它涉及到maximumWidth属性时,那我应该不工作,可以吗? I just don't get their point... Please explain. 我只是不明白他们的意思,请解释。

PS I have written this code because I wanted to close by animation the right QTextEdit and be sure that when I resize the main window, where the button and two QTextEdit are, the closed QTextEdit does not being restored. PS我之所以编写此代码,是因为我想通过动画关闭正确的QTextEdit,并确保在调整主窗口(按钮和两个QTextEdit所在的位置)的大小时,不会恢复关闭的QTextEdit。

Did you check the actual value of maximumWidth? 您是否检查了maximumWidth的实际值? You don't seem to set a specific maximumWidth in your code. 您似乎未在代码中设置特定的maximumWidth。

The default value for maximumWidth is 16777215, and you set a duration of 1 msec. maximumWidth的默认值为16777215,并且您设置的持续时间为1毫秒。 for the closing animation. 结束动画。 Fading from 16777215 to 3 in 1 msec. 在1毫秒内从16777215衰减到3。 would look like "instant", I guess. 我想看起来像“即时”。

I don't think it is a bug; 我不认为这是一个错误。 I'd call it "undefined behavior". 我称其为“不确定行为”。 That means that if you try to animate minimumWidth, nobody can tell you for sure what is supposed to happen, and maybe the code has some optimizations or corner cases where sometimes it works, others it doesn't. 这意味着,如果您尝试设置minimumWidth的动画,则没有人可以肯定地告诉您应该发生什么,并且代码可能进行了一些优化或在某些情况下可以工作,但在某些情况下却没有。

Anyway, minimumWidth and maximumWidth aren't supposed to be used to define what the size of a QWidget is, only what it must not exceed; 无论如何,不​​应该使用minimumWidth和maximumWidth来定义QWidget的大小,而不能定义它的大小。 ie they weren't designed to do what you are trying to do, so it can be called a bug. 也就是说,它们并非旨在执行您要尝试执行的操作,因此可以将其称为错误。 If you want to animate, you have to use a deterministic approach, which in this case is using the geometry property. 如果要设置动画,则必须使用确定性方法,在这种情况下,将使用geometry属性。

这不是错误,您从错误报告中得到的响应很好地解释了代码和解决方案的问题。

Dear Sofahamster I have changed my code to the code below and it works fine. 亲爱的Sofahamster:我已将代码更改为以下代码,并且工作正常。 Thanks for your hint! 感谢您的提示!

Header file 头文件

class MyWidget : public QWidget
{

    Q_OBJECT

    QTextEdit       *m_textEditor1;
    QTextEdit       *m_textEditor2;
    QPushButton     *m_pushButton;
    QHBoxLayout     *m_layout;
    QVBoxLayout     *m_buttonLayout;

    int              m_deltaX;
    bool             m_isClosed;


public:

    MyWidget(QWidget * parent = 0);
    ~MyWidget(){}

    void resizeEvent( QResizeEvent * event );

private slots:
    void closeOrOpenTextEdit2(bool isClosing);

};

Source file 源文件

MyWidget::MyWidget(QWidget * parent):QWidget(parent),m_deltaX(0)
{

  m_pushButton = new QPushButton(this);
  m_pushButton->setText(">");
  m_pushButton->setCheckable(true);
  m_pushButton->setFixedSize(16,16);
  connect(m_pushButton, SIGNAL(clicked(bool)), this, SLOT(closeOrOpenTextEdit2(bool)));

  m_textEditor1 = new QTextEdit(this);
  m_textEditor1->setText("AAAAA AAAAAAAAAAA AAAAAAAAAAA  AAAAAAA AAAAAAAAAAA AAAAAAAAAAA  AA");

  m_textEditor2 = new QTextEdit(this);

  m_buttonLayout = new QVBoxLayout();
  m_buttonLayout->addWidget(m_pushButton);
  m_buttonLayout->addItem( new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding) );


  m_layout = new QHBoxLayout;
  m_layout->addWidget(m_textEditor1, 10);
  m_layout->addSpacing(15);
  m_layout->addLayout(m_buttonLayout);
  m_layout->setSpacing(0);
  m_layout->addWidget(m_textEditor2, 4);

  setLayout(m_layout);
  resize(800,500);
}

void MyWidget::closeOrOpenTextEdit2(bool isClosing)
{
    m_isClosed = isClosing;
    QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "maximumWidth");

    if(isClosing) //close the second textEdit
    {
        m_textEditor2->setMaximumWidth(m_textEditor2->width());

        int textEdit2_start = m_textEditor2->maximumWidth();

        m_deltaX = textEdit2_start;
        int textEdit2_end = 3;



        animation1->setDuration(500);
        animation1->setStartValue(textEdit2_start);
        animation1->setEndValue(textEdit2_end);


        m_pushButton->setText("<");

    }
    else //open
    {


        int textEdit2_start = m_textEditor2->maximumWidth();
        int textEdit2_end = m_deltaX;


        animation1->setDuration(500);
        animation1->setStartValue(textEdit2_start);
        animation1->setEndValue(textEdit2_end);


        m_pushButton->setText(">");

    }

    animation1->start();

}


void MyWidget::resizeEvent( QResizeEvent * event )
{
    if(!m_isClosed)
        m_textEditor2->setMaximumWidth( QWIDGETSIZE_MAX );
}

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

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