Запуск QPainter на QPrinter в фоновом потоке приводит к зависанию всего приложения.Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Запуск QPainter на QPrinter в фоновом потоке приводит к зависанию всего приложения.

Сообщение Anonymous »

В моем приложении Qt у меня есть относительно большой QGraphicsScene, и его рендеринг в QPrinter занимает пару секунд, и приложение перестает отвечать на запросы. Поэтому я решил визуализировать сцену в фоновом потоке. Однако вызов QPainter::begin() на QPrinter, который указывает на виртуальный принтер (т. е. принтеры, записывающие в PDF-файл) в фоновый поток приводит к зависанию всего приложения и PDF-файлу не создается.
Я считаю, что QPainter::begin() для виртуальных принтеров требует открытия диалогового окна файла для получения PDF-файла имя файла. Поскольку этот вызов происходит в фоновом потоке, он не может открыть диалоговое окно файла, что приводит к взаимоблокировке всего приложения.
Вот минимальный и полный пример, иллюстрирующий проблему:
import sys
from PyQt6.QtCore import QObject, Qt, QThread
from PyQt6.QtGui import QPainter
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QGraphicsScene, QVBoxLayout
from PyQt6.QtPrintSupport import QPrinter

class RenderThread(QThread):
scene: QGraphicsScene
printer: QPrinter

def __init__(self, scene: QGraphicsScene, printer: QPrinter, parent: QObject) -> None:
super().__init__(parent)
self.scene = scene
self.printer = printer

def run(self) -> None:
painter = QPainter(self.printer)
self.scene.render(painter)

class Window(QWidget):
scene: QGraphicsScene
printer: QPrinter
renderer: RenderThread

def __init__(self) -> None:
super().__init__()
self.scene = QGraphicsScene()
self.scene.addEllipse(5, 5, 50, 50)
self.printer = QPrinter(QPrinter.PrinterMode.HighResolution)
self.renderer = RenderThread(self.scene, self.printer, self)
layout = QVBoxLayout(self)
button = QPushButton("Print")
layout.addWidget(button, 0, Qt.AlignmentFlag.AlignCenter)
button.clicked.connect(self.renderer.start)

if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())


Подробнее здесь: https://stackoverflow.com/questions/790 ... ntire-appl
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • LD_PRELOAD на Android приводит к зависанию приложения
    Anonymous » » в форуме Android
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Использование Ironpython из C# async-await приводит к зависанию приложения
    Anonymous » » в форуме C#
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous
  • Отключение. Повторное подключение сокета winsock2 приводит к зависанию приложения?
    Anonymous » » в форуме C++
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Отключение. Повторное подключение сокета winsock2 приводит к зависанию приложения?
    Anonymous » » в форуме C++
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Инициализация кадра данных Polars с 15 миллионами записей приводит к зависанию машины.
    Anonymous » » в форуме Python
    0 Ответы
    36 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»