在Qt小部件应用程序中,在重载的"paintEvent"中的"setValue"

In Qt Widgets Application, cannot change value of `QSpinBox` after `setValue` in overloaded `paintEvent`?

本文关键字:quot paintEvent setValue 中的 重载 小部 Qt 应用程序      更新时间:2023-10-16

>问题

在Qt小部件应用程序中,在重载paintEventMainWindowsetValueQSpinBox后,我无法更改的值。

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

我的问题是:为什么我在MainWindow的重载paintEventsetValue后无法更改QSpinBox的值?

重现问题

我可以在以下步骤中重现该问题。

  1. 通过Qt Creator创建QtWidget应用程序
  2. 通过嵌入式Qt Designer创建QSpinBox
  3. 将以下代码添加到mainwindow.h void paintEvent(QPaintEvent *);

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

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

我可以将我的函数setValue移动到另一个地方以避免此问题,但为什么会发生这种情况?我找不到我犯了什么错误。

试验

  • 我测试了QDoubleSpinBoxQLineEdit,它们的行为相似。
  • 试图setReadOnly(false),它不起作用。
  • 当我尝试更改该值时,我收到valueChanged(int)发射信号,但setValue(int)不再起作用。
  • 我阅读了有关QPaintEventQAbstractSpinBox的文档.我找不到任何有用的东西。

请帮帮我!

环境

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

源代码

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

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

因为您要在应用程序的异步部分内创建无限循环。

当任何 GUI 值更新以便用户可以看到它时,必须重新绘制它,为此开发人员调用update(),该方法在内部发送事件QEvent::Paint,如果是事件,这些小部件将发送到从父级到子级的所有小部件,在这种情况下,QEvent::Paint事件首先到达 MainWindow,然后可能到达您孩子的微调框。只有当父母使用它时,它才会传递给孩子。那么顺序如下:

  1. 用户更改了QSpinbox的值
  2. 它叫update()
  3. QEvent::Paint事件被发送到窗口,并将其重新分发给子级。
  4. 它到达主窗口,更改值并转到步骤 2。

总之,如果您更改微调框的值,它将间接调用 MainWindow 的 paintEvent 方法并将微调框设置为以前的值。paintEvent(...( 的任务只是绘制,而不是更新另一个值,如果这样做,可能会创建一个无限循环。