-
Notifications
You must be signed in to change notification settings - Fork 45
Description
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)