crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Qthread, Qsocket, сигналы-слоты.., Pyqt, Qt.4.8 , win7
Andrewshkovskii
  опции профиля:
сообщение 18.1.2012, 19:44
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Проблема : есть гуи-софтина, в которой есть длительная операция и работа сокетами (tcp).
При длительной операции гуи-поток подвисает, подвисают и сокеты и сервер сбрасывает подключение по этим сокетами( кот.подписли)
Описание объектов :
Менеджер сокетов - содержит в себе список всех сокетов и обрабатывает данные, поступившие от них, а так же всяческие исключительные ситуации, живет в основном потоке
ГУИ - гуёвина где и происходит длительная операция, кот. подвешивает основной поток.
Объект-поток UpQSocketThread - поток с сокетом.
Цель :
Заставить сокет работать в потоке, отличным от гуи, да так, что бы все те слоты объекта-потока, соединенные с содержащимся в нем(объекте-потоке) сокете выполнялись в отдельном потоке.
А слоты, соединенные с сигналами объекта-потока выполнялись в основном потоке.
Вопрос :
Где (в run() или конструкторе объекта-потока) создавать сокет для объекта-потока и соединять сигналы сокета со слотами объекта-потока и каким типом соединения.
И каким типом соединения соединять сигналы объекта-потока с слотами менеджера сокетов.

Вот код, для наглядности. При данном коде происходит следующее :
Часто получаю сообщения типа :
Цитата
QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketError'
(Make sure 'QAbstractSocket::SocketError' is registered using qRegisterMetaType().)

Или же
Цитата
QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketError'
(Make sure 'QAbstractSocket::SocketError' is registered using qRegisterMetaType().)

Или вовсе софтина крашиться.
Что я не понял?как правильно сделать?
class UpQSocket(QTcpSocket):
    def __init__(self):
        QTcpSocket.__init__(self)
        self.wait_len = ''
        self.temp = ''
        self.setSocketOption(QTcpSocket.KeepAliveOption, QVariant(1))

    def connectToHost(self, host, port):
        self.temp = ''
        self.wait_len = ''
        QTcpSocket.connectToHost(self, host, port)


class UpQSocketThread(QThread):
    data_ready = pyqtSignal(unicode)

    error = pyqtSignal(int)
    connected = pyqtSignal()
    disconnected = pyqtSignal()

    def __init__(self, host , port):
        QThread.__init__(self)
        self.start()
        self.host = host
        self.port = port

    def state(self):
        return self.socket.state()

    def resend_error(self, error_code):
        self.error.emit(error_code)

    def resend_connected(self):
        self.connected.emit()

    def resend_disconnected(self):
        self.disconnected.emit()

    def run(self):
        self.socket = UpQSocket()
        self.socket.readyRead.connect(self.on_ready_read)#, Qt.DirectConnection)
        self.socket.error.connect(self.resend_error)#, Qt.DirectConnection)
        self.socket.disconnected.connect(self.resend_disconnected)#, Qt.DirectConnection)
        self.socket.connected.connect(self.connected)#, Qt.DirectConnection)
        self.socket.connectToHost(self.host, self.port )
        self.exec_()

    def send(self, data):
        self.socket.writeData('%s|%s' % (len(data), data))

    def close(self):
        self.socket.close()
        self.terminate()

    def on_ready_read(self):
        if self.socket.bytesAvailable():
            data = str(self.socket.readAll())
            while data:
                #process data...


Сигналы объекта-потока подключаются аналогично(AutoConnection), после создания объекта-потока.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zloiia
  опции профиля:
сообщение 19.1.2012, 6:45
Сообщение #2


Студент
*

Группа: Участник
Сообщений: 25
Регистрация: 5.5.2011
Пользователь №: 2655

Спасибо сказали: 5 раз(а)




Репутация:   0  


А быть может попробовать Qt::QueuedConnection ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 19.1.2012, 8:36
Сообщение #3


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Может. только для кого и где? Основных обхекта - 3 : менеджер сокетов , поток сокета и сам сокет в потоке.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zloiia
  опции профиля:
сообщение 19.1.2012, 11:20
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 25
Регистрация: 5.5.2011
Пользователь №: 2655

Спасибо сказали: 5 раз(а)




Репутация:   0  


Стоп. А может внимательно почитать ошибку? В ней же нерусским языком написано что QAbstractSocket::SocketError типа не зарегестрирован. Я конечно не силен в Питоне, онако есть предположение что стоит попробовать подключить модуль SqlError к скрипту. Но я могу ошибаться. Тут точно проблема не в потоках пока что
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 19.1.2012, 11:26
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Вы о чем вообще ? Какой SqlError? Эта ошибка возникает у меня из-за неверного подключения сигнал-слотов across потоков, точнее почему - не могу сказать , знал бы - пофиксил сам.

Сообщение отредактировал Andrewshkovskii - 19.1.2012, 11:28
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 19.1.2012, 12:05
Сообщение #6


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(zloiia @ 19.1.2012, 12:20) *
Стоп. А может внимательно почитать ошибку? В ней же нерусским языком написано что QAbstractSocket::SocketError типа не зарегестрирован
Всё верно.
Цитата(Andrewshkovskii @ 18.1.2012, 20:44) *
Цитата
QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketError'
(Make sure 'QAbstractSocket::SocketError' is registered using qRegisterMetaType().)
Собственно в самом сообщении об ошибке уже всё сказано. Достаточно открыть документацию на QAbstractSocket::SocketError и прочитать подробности
Цитата(из документации)
void error (QAbstractSocket::SocketError)
This is the default overload of this signal.
This signal is emitted after an error occurred. The socketError parameter describes the type of error that occurred.
QAbstractSocket.SocketError is not a registered metatype, so for queued connections, you will have to register it with Q_DECLARE_METATYPE() and qRegisterMetaType().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 19.1.2012, 12:47
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


В pyqt нет возможности зарегистрировать тип через qRegisterMetaType(). И , кстати, я повторюсь - этот ворнинг возникает из-за неправильного типа подключения сигнал-слотов через треды.
Есть ещё какие-нибудь идеи? Я пока выхода верного не нашел.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 19.1.2012, 20:30
Сообщение #8





Гости








    


Как это нет, qRegisterMetaType() это то, что позволяет Qt правильно передавть типы. Сигнал с незарегестрированным типом не должен эммитироваться. Т.е. практически бесполезно пытаться прогать на qt без этой функции.
Все подвисает по одной просто причине - все запихано в одном треде. Надо из основного потока (он же гуевый) вынести сокетовый тред и в качестве третьего треда - длительная операция.
При этом надо помнить, что слот выполняется в том треде, в котором вызван конструктор объекта, в котором он прописан. Собственно все. Место коннекта не играет роли.
Т.е. вам надо узнать как в pyQt зарегить тип.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 15:06