Skip to content

Qt support #95

@Bleyddyn

Description

@Bleyddyn

TLDR: I would like to launch a Qt GUI from inside tinyfugue so it has access to the tf module. Kind-of a backdoor into creating a GUI Mud client based on tinyfugue. Any help would be appreciated.

I can run the script below from the command line and it works, with a simple Qt GUI running on a background thread. I set the PYTHONPATH so it can access the fake tf module that's in tf-lib

$ PYTHONPATH=./tf-lib python3 test_qt.py
tf.out  | Main: <class 'str'> 
tf.out  | Leaving main
tf.out  | Starting exec
tf.out  | Quitting
tf.out  | Exited exec

Unfortunately, when I run it from inside tinyfuge it doesn't work. There are no error messages so I don't have anything to go on. That second call to main calls join on the thread, which does launch the GUI, unfortunately it also locks up tinyfuge until the GUI exits.

/python_load test_qt
/python_call test_qt.main
/python_call test_qt.check_thread
/python_call test_qt.main

Output of the above sequence:

Main: <class 'str'>
Leaving main
Background thread is alive: True
% PYTHON_CALL: No world
Starting exec
Quitting
Exited exec

import sys
import threading
import time

import tf

running = True
background_thread = None

def make_window(app):
# You can't import any widget before creating the application object on it's background thread
# So these are hidden inside a function
    from PyQt5.QtWidgets import QWidget, QLabel, QMainWindow, QVBoxLayout, QPushButton


    class TestApp(QMainWindow):
        def __init__(self, _app):
            QMainWindow.__init__(self)

            self.app = _app

            _widget = QWidget()
            _widget.setGeometry(50,50,320,200)
            _layout = QVBoxLayout(_widget)
            textLabel = QLabel(_widget)
            textLabel.setText(f"Hello World! {tf.world()}")
            _layout.addWidget(textLabel)
            self.setCentralWidget(_widget)
            self.setWindowTitle("PyQt5 Example")

            quitButton = QPushButton("Quit");
            _layout.addWidget( quitButton )
            quitButton.clicked.connect(self.quit)

        def closeEvent(self, event):
            tf.out( "Closing" )
            global running
            running = False
            self.app.quit()
            if hasattr( self, "loop" ):
                self.loop.quit()

        def quit(self):
            tf.out( "Quitting" )
            global running
            running = False
            self.app.quit()
            if hasattr( self, "loop" ):
                self.loop.quit()
            
    return TestApp(app)

def check_thread(args):
    if background_thread is None:
        tf.out( "No background thread" )
    else:
        tf.out( f"Background thread is alive: {background_thread.is_alive()}" )

def background():
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    foo = make_window(app)
    foo.show()
    tf.out( "Starting exec" )
    app.exec()
    tf.out( "Exited exec" )

def main(args):
    global background_thread
    if background_thread is not None:
        background_thread.join()
        return

    tf.out( f"Main: {type(args)} {args}" )
    background_thread = threading.Thread(target=background)
    background_thread.start()
    tf.out( "Leaving main" )

if __name__ == '__main__':
    main("")

    while running:
        time.sleep(0.1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions