在Qt Widgets Application中,在重载的`paintEvent`中`setValue`之后不能改变`QSpinBox`的值?

nam*_*nam 2 c++ qt qt5

问题

在Qt的Widgets应用程序,我不能改变我的价值QSpinBox后,我setValue在重载它paintEvent的MainWindow.

感谢@eyllanesc,我将强调这个问题.

我的问题是:为什么我不能改变我的价值QSpinBox后,我setValue在重载它paintEvent的MainWindow?

重现问题

我可以通过以下步骤重现该问题.

  1. 由Qt Creator创建一个QtWidget应用程序
  2. 创建一个QSpinBox嵌入式Qt设计器
  3. 将以下代码添加到mainwindow.h: void paintEvent(QPaintEvent *);

  4. 将以下代码添加到mainwindow.cpp: void MainWindow::paintEvent(QPaintEvent *) { ui->spinBox->setValue(2); }

  5. 构建并运行应用程序.
  6. 尝试更改spinBox的值,您会发现无法更改该值.

我可以将我的功能setValue移到另一个地方以避免这个问题,但为什么会这样呢?我找不到我犯的错误.

试验

  • 我测试QDoubleSpinBox和QLineEdit,他们的行为类似.
  • 试着setReadOnly(false),它不起作用.
  • 当我尝试更改值时,我得到发射信号valueChanged(int),但setValue(int)不再起作用.
  • 我阅读了关于和的文档.我找不到任何有用的东西.QPaintEventQAbstractSpinBox

请帮帮我!

环境

  • 操作系统:Windows10
  • Qt编译器:桌面Qt 5.11.1 MinGW 32位

源代码

完整的源代码可以在mainwindow.h,main.cpp,mainwindow.cpp,mainwindow.ui中找到.

eyl*_*esc 5

如果在paintEvent方法中进行更改,为什么不能更改QSpinBox的值?

因为您在应用程序的异步部分中创建了一个无限循环.

当任何GUI值更新以便用户可以看到它然后必须重新绘制,并且为此开发人员调用update(),该方法在内部发送事件QEvent::Paint,并且在事件的情况下,这些被发送到从父到子的所有小部件,在这种情况下,QEvent::Paint事件首先到达MainWindow,然后可能到达您孩子的旋转盒.如果父级使用它,它只会传递给子级.然后序列如下:

  1. 用户更改了该值 QSpinbox
  2. 它被称为 update()
  3. 该QEvent::Paint事件被发送到窗口,并其重新分配给孩子们.
  4. 它到达MainWindow,更改值并转到步骤2.

总之,如果你改变了spinbox的值,它将间接调用MainWindow的paintEvent方法并将spinbox设置为前一个值.paintEvent(...)的任务只是绘制,而不是更新另一个值,如果它,它可能会创建一个无限循环.