在Qt窗口小部件应用程序中,在重载的`paintEvent`中的`setValue`之后不能更改`QSpinBox`的值吗?

时间:2018-09-02 14:04:07

标签: c++ qt qt5

问题

在Qt窗口小部件应用程序中,在QSpinBox的{​​{1}}超载的情况下,我无法在setValue之后更改paintEvent的值。

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

我的问题是:为什么MainWindow的{​​{1}}中,QSpinBoxsetValue超载后不能更改其值?

重现问题

我可以按照以下步骤重现该问题。

  1. 通过Qt Creator创建QtWidget应用程序
  2. 通过嵌入式Qt Designer创建paintEvent
  3. 将以下代码添加到MainWindow中: QSpinBox

  4. 将以下代码添加到mainwindow.h中: void paintEvent(QPaintEvent *);

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

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

试用

  • 我测试了 void MainWindow::paintEvent(QPaintEvent *) { ui->spinBox->setValue(2); } setValue,它们的行为类似。
  • 尝试QDoubleSpinBox,它不起作用。
  • 当我尝试更改该值时,收到QLineEdit发出信号,但setReadOnly(false)不再起作用。
  • 我阅读了documentation关于valueChanged(int)setValue(int)的内容。我找不到有用的东西。

请帮助我!

环境

  • 操作系统:Windows10
  • Qt编译器:台式机Qt 5.11.1 MinGW 32位

源代码

完整的源代码可以在mainwindow.hmain.cppmainwindow.cppmainwindow.ui中找到。

1 个答案:

答案 0 :(得分:5)

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

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

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

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

最后,如果更改了Spinbox的值,它将间接调用MainWindow的paintEvent方法并将Spinbox设置为先前的值。 paintEvent(...)的任务只是绘画,而不是更新另一个值,如果这样做,则可能会创建一个无限循环。