Qt5reactor not working

Hi there, I did post a bug on the qt5reactor github site but I was wondering if anyone here could help me. I am trying to make a qt5 autobahn-python client. I am following the example at https://github.com/estan/gauges. When I run the code below, the call goes through in the onJoin but when I click the button to trigger message_to the call returns an immediate TransportLost exception. Am I doing something wrong here? My best guess is that my call is ending up on the wrong thread, but I am not sure how to start it on the correct thread.

import sys, json
import qt5reactor
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout, QLineEdit, QPushButton, QListView, QWidget
from PyQt5.QtCore import Qt
from autobahn.twisted.wamp import ApplicationSession
from autobahn.twisted.wamp import ApplicationRunner
from autobahn.wamp import auth
from autobahn.wamp.exception import SessionNotReady
from chatinclude import MessageModel, MessageDelegate

# Subclass QMainWindow to customise your application's main window
from twisted.internet.defer import inlineCallbacks


class MainWindow(QMainWindow, ApplicationSession):

    def __init__(self, *args, **kwargs):
        self.global_authid = "test-chat-client"
        self.global_key = "MYKEY"
        super(MainWindow, self).__init__()
        super(ApplicationSession, self).__init__(*args, **kwargs)
        # Layout the UI
        l = QVBoxLayout()

        self.message_input = QLineEdit("Enter message here")

        # Buttons for from/to messages.
        self.btn1 = QPushButton("<")
        self.btn2 = QPushButton(">")

        self.messages = QListView()
        self.messages.setResizeMode(QListView.Adjust)
        # Use our delegate to draw items in this view.
        self.messages.setItemDelegate(MessageDelegate())

        self.model = MessageModel()
        self.messages.setModel(self.model)

        self.btn1.pressed.connect(self.message_to)
        self.btn2.pressed.connect(self.message_from)

        l.addWidget(self.messages)
        l.addWidget(self.message_input)
        l.addWidget(self.btn1)
        l.addWidget(self.btn2)

        self.w = QWidget()
        self.w.setLayout(l)
        self.setCentralWidget(self.w)

    @inlineCallbacks
    def message_to(self):
        USER_ME=0
        try:
            res2 = yield self.call(u'biz.domain.register_chat')
            print("\nget data result: {}\n".format(res2))
            self.model.add_message(USER_ME, self.message_input.text())
        except Exception as e:
            print("get data call error: {0}".format(e))

    def message_from(self):
        USER_THEM=1
        self.model.add_message(USER_THEM, self.message_input.text())

    def onConnect(self):
        print("CONNECT", self.global_authid)
        self.join(u"unwait", ['wampcra'], self.global_authid)

    def onChallenge(self, challenge):
        print("CHALLENGE",challenge.method)
        if challenge.method == u"wampcra":
            signature = auth.compute_wcs(self.global_key.encode('utf8'),
                                         challenge.extra['challenge'].encode('utf8'))
            return signature.decode('ascii')
        else:
            raise Exception("don't know how to handle authmethod {}".format(challenge.method))
        return None

    @inlineCallbacks
    def onJoin(self, details):
        print("JOIN")
        try:
            res2 = yield self.call(u'biz.domain.register_chat')
            print("\nget data result: {}\n".format(res2))
        except Exception as e:
            print("get data call error: {0}".format(e))

    def onLeave(self, details):
        print("LEAVE")

    def closeEvent(self, event):
        pass


app = QApplication(sys.argv)
qt5reactor.install()
runner = ApplicationRunner(url='ws://IPADDR:9001/ws', realm='myrealm')

window = MainWindow()
window.show()
runner.run(MainWindow)
#app.exec_()

Hi,

I suspect the order of imports and reactor install and Qt app instantiation might screw up things.

I just added and tested a trivial example … this works for me (both examples):

could you check on your side / adapt the example to your needs and report back?

Cheers,
/Tobias

I seem to remember we had created the pyside2reactor because of some issues we had with qt5reactor … but I forgot which issues;) also I’m not sure if these are still there … @meejah ?

I’m a little bit confused. Should I be using pyside2reactor instead of qt5reactor? Both these tests use PySide6 which I do not have installed but could install.

I just looked into PySide6 and realized that there is a Qt6. I had thought Qt5 was the latest. I will try PySide6 and this test.

I was able to get the ex1_qtreactor.py script to work. I was getting ‘Neither QtPy5 or PySide2 found’ the way it is there with PySide6. So I installed PySide2 and that works. However, I don’t know what this is supposed to demontrate; there are no wamp calls in this script. Other than installing qt5reactor it only does Qt5 operations and isn’t an ApplicationSession.

yeah, it’s noted in a comment in the file … you can test it with pyside2/qt5 and pyside6/qt6 - and you need to have those installed.

However, I don’t know what this is supposed to demontrate; there are no wamp calls in this script.

it demonstrates how to run pyside/qt under a twisted reactor loop - which is the critical requirement to combine autobahn and pyside/qt

adding a real application session should be straight forward - sorry, I didn’t bother adding one to the example

Ok I will add one and tell you how it goes. I can get to this point in my current code too so was confused. How do I get this working with pyside6? qt5reactor doesn’t work with pyside6 but I was unable to find any python package called pyside6reactor.