Новый ансер для более конкретного рассмотрения повторного входа ...
danatel оставил следующий комментарий к этому сообщению (частично):
Под повторным входом я подразумеваю эту конкретную ситуацию: 1) обработчик paintEvent сохраняет QPainter в переменную класса. 2) обработчик paintEvent вызывает подпрограммы для рисования чего-либо 3) одна из подпрограмм вызывает метод Qt 4) этот метод Qt рекурсивно генерирует другой paintEvent
Ответ на этот вопрос заключается в том, что это, вероятно, должно быть приемлемо, если вы не делаете что-то действительно странное. (И если вы сделаете что-то странное, Qt, вероятно, предупредит вас или прервет.) Я думаю, что все еще может быть некоторая путаница в том, что вы подразумеваете под повторным входом, но генерация paintEvent не остановит поток выполнения текущего действия, чтобы немедленно обработать это событие. Вместо этого (как и все события), он будет поставлен в очередь для последующей обработки. Пока вы не выполняете многопоточность или не вызываете processEvents, порядок выполнения кода, когда вы находитесь в одной из ваших собственных функций, должен быть очень простым.
В качестве примера давайте проследим за вашими шагами и рассмотрим их более подробно.
Foo::paintEvent()
обработчик
создает QPainter и устанавливает
Foo::m_painter_p
на это.
Foo::paintEvent()
звонки
Foo::paintAntarticaFlag()
.
Foo::paintAntarticaFlag()
: а) использует Foo::m_painter_p
, затем б) вызывает что-то, что вызывает Foo::update()
, затем в) использует Foo::m_painter_p
еще немного.
Foo::update()
, который на самом деле является методом Qt, генерирует paintEvent для Foo.
Вышеприведенная последовательность в порядке, так как обновление создает событие , что означает задержку обработки. Если вместо этого вы вызываете Foo :: repaint (), это приведет к немедленной рекурсии в Foo :: paintEvent (), что приведет к прерыванию Qt, потому что вы создаете более 1 рисовальщика для одного и того же объекта или ваша программа прерывает работу потому что это в конечном счете (вы знаете, через несколько сотен миллисекунд) взорвало стек.
Если вы выполняете несколько потоков и просто хотите инициировать перерисовку, вы все равно можете сделать это из другого потока, поскольку он просто поместит paintEvent в очередь для обработки соответствующим потоком в нужное время. Если вы делаете несколько потоков и хотите нарисовать эти флаги одним и тем же художником, не надо. Просто не надо. В этом случае вы можете рассмотреть возможность рисования каждого флага в общем изображении и рисования этого изображения там, где вы сейчас используете QPainter.