LINUX.ORG.RU

Ускорить запуск pyqt программки через multiprocessing

 , ,


0

2

Всем привет!

Люди, пожалуйста, помогите разобраться с multiprocessing в pyqt. Хочу изменить картинку на QLabel через дочерний процесс. Такой код:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from multiprocessing import Process, Pool


class Test(QWidget):
    def __init__(self):
        super().__init__()
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.label = QLabel()
        self.layout.addWidget(self.label)

        self.pixmap = QPixmap()


def set_pixmap(classname=None):
    classname.pixmap.load('test.jpg')
    classname.label.setPixmap(classname.pixmap)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    test = Test()
    test.show()

    proc = Process(target=set_pixmap, kwargs={'classname': test})
    proc.start()
    proc.join()

    # pool = Pool()
    # pool.map(set_pixmap, (test,))
    # pool.close()
    # pool.join()

    sys.exit(app.exec_())

В таком виде картинка не появляется. Если через pool запускать, то валятся ошибки:

Process ForkPoolWorker-1:
Traceback (most recent call last):
  File "/usr/lib/python3.5/multiprocessing/process.py", line 254, in _bootstrap
    self.run()
  File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 108, in worker
    task = get()
  File "/usr/lib/python3.5/multiprocessing/queues.py", line 345, in get
    return ForkingPickler.loads(res)
RuntimeError: super-class __init__() of type Test was never called

Читал, что виджеты в pyqt должны быть созданы в главном потоке: у меня так и есть, вроде, у виджета только свойство меняю. Можно ли дочерним процессом установить QPixmap?


Нет, из другого процесса ты не умеешь доступа к объектам первого. Либо используй какое-нибудь IPC, чтобы дать команду основному процессу на манипуляцию с виджетом, либо используй треды.

Вообще, в gtk можно встраивать в окно виджеты из другого процесса, через специальный механизм http://www.pygtk.org/pygtk2tutorial/sec-PlugsAndSockets.html в qt тоже, наверное, что-то такое есть.

pawnhearts ★★★★ ()
Последнее исправление: pawnhearts (всего исправлений: 1)
Ответ на: комментарий от pawnhearts

Спасибо, что ответил. Я правильно понял, что таким образом не получится выиграть на скорости запуска, что всё равно будет картинку менять основной процесс?

rmu ()
Ответ на: комментарий от pawnhearts

в gtk можно встраивать в окно виджеты из другого процесса

Это то, что нужно. Напиши, пожалуйста, если что-то попадётся по теме.

rmu ()
Ответ на: комментарий от rmu

А в чем проблема, основной поток блокируется? Там есть всякие механизмы типа QThread, наверное надо их использовать. Сам я с pyqt никогда не работал.

pawnhearts ★★★★ ()
Ответ на: комментарий от pawnhearts

Пошел QThread пилить. У меня целая куча лейблов, пока все не загрузятся - главное окно не показывается. Хочу, чтобы гл. окно уже было видно при запуске, а чтоб на лейблах картинки потихоньку подгружались. Ради этого всё.

rmu ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.