В приложении Qt Widgets не может изменить значение `QSpinBox` после` setValue` в перегруженном `paintEvent`? - PullRequest
0 голосов
/ 02 сентября 2018

Задача

В приложении Qt Widgets я не могу изменить значение моего QSpinBox после I setValue для него в перегруженном paintEvent из MainWindow.

Благодаря @eyllanesc я подчеркну этот вопрос.

Мой вопрос: почему Я не могу изменить значение моего QSpinBox после I setValue для него в перегруженном paintEvent из MainWindow?

Воспроизвести вопрос

Я могу воспроизвести проблему в следующих шагах.

  1. Создание приложения QtWidget с помощью Qt Creator
  2. Создание QSpinBox с помощью встроенного Qt Designer
  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) больше не работает.
  • Я прочитал документацию о QPaintEvent и QAbstractSpinBox. Я не могу найти ничего полезного.

Помогите мне, пожалуйста!

Среда

  • ОС: Windows10
  • Компилятор Qt: Desktop Qt 5.11.1 MinGW 32bit

Исходный код

Полный исходный код можно найти в mainwindow.h , main.cpp , mainwindow.cpp , mainwindow.ui .

1 Ответ

0 голосов
/ 02 сентября 2018

Почему нельзя изменить значение QSpinBox, если изменение сделано в методе paintEvent?

Поскольку вы создаете бесконечный цикл в асинхронной части приложения.

Когда любое значение графического интерфейса пользователя обновляется, чтобы пользователь мог его увидеть, оно должно быть перекрашено, и для этого разработчик вызывает update(), этот метод внутренне отправляет событие QEvent::Paint, и в случае событий это отправляется всем виджетам от родителя к потомку, в этом случае событие QEvent::Paint сначала поступает в MainWindow, а затем, возможно, достигает спинбокса вашего потомка. Это только передано детям, если родитель использует это. Тогда последовательность выглядит следующим образом:

  1. Пользователь изменил значение QSpinbox
  2. Это называется update()
  3. Событие QEvent::Paint отправляется окну и перераспределяет его дочерним элементам.
  4. Он достигает главного окна, изменяет значение и переходит к шагу 2.

В заключение, если вы измените значение spinbox, он косвенно вызовет метод paintEvent в MainWindow и установит spinbox на предыдущее значение. Задача paintEvent (...) состоит только в том, чтобы рисовать , а не обновлять другое значение, в противном случае это, вероятно, создаст бесконечный цикл.

...