@PaffosONE

Как правильно реализовать добавление данных в таблицу PyQt5?

Сейчас я пишу парсер данных с вебсайтов, столкнулся с проблемой зависания GUI.
Прочитал, что нужно выполнять все в отдельном потоке, сначала попробовал стандартную python библиотеку threading, но столкнулся с ошибкой:

QObject::setParent: Cannot set parent, new parent is in a different thread

После, прочитав несколько топиков, пришел к применению QThread, но и тут проблемы, класс worker выдает ошибку, при попытке добавить Item в таблицу.

Сам класс worker:

class worker( QThread ):
    def __init__(self, table, parent=None ):
        super().__init__()
        self.table = table
        self.parent = parent

    def run( self ):
        try:
            block_username = QFrame( self.parent )
            text = "SomeText"
            self.table.setRowCount( self.table.rowCount() + 1 )
            self.table.setCellWidget( 0, 0, block_username ) 
            self.table.setItem( 0, 1 QTableWidgetItem( text ) )
        except Exception as error:
            print( error )

Ошибка:

QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::connect: Cannot queue arguments of type 'QVector<int>'    
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'    
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'    
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'    
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QVector<int>'    
(Make sure 'QVector<int>' is registered using qRegisterMetaType().)

Как можно реализовать добавление данных в таблицу, чтобы при этом GUI не зависал?
  • Вопрос задан
  • 692 просмотра
Пригласить эксперта
Ответы на вопрос 2
Используйте механихзм signal/slot для общения между потоками программы.
Ответ написан
@bbkmzzzz
Qt устроен так, что дергать методы интерфейса можно только из того потока, в котором этот интерфейс работает. Таков путь.

При наследовании от QThread - нужно переопределять метод run, он будет вызван при старте потока, либо его не реализовывать, и тогда срабатывать по сигналам.
Где запуск потока?
self.worker.start()

Есть еще вариант.
Использовать moveToThread, тогда ВСЕ СЛОТЫ класса, наследованного от QObject (нужно пометить декоратором слотов) будут выполняться в отдельном потоке
self.worker = QThread()
self.worker.start()

self.some_class.moveToThread(self.worker)


И еще вариант.
QThreadPool + QRunnable

P.S.
Классы ВСЕГДА называйте с заглавной буквы
Все атрибуты класса инициализируйте в __init__
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы