2

I am wondering how one would create a GUI application, and interact with it from the console that started it.

As an example, I would like to create a GUI in PyQt and work with it from the console. This could be for testing settings without restarting the app, but in larger projects also for calling functions etc.

Here is a simple example using PyQt:

import sys from PyQt4 import QtGui def main(): app = QtGui.QApplication(sys.argv) w = QtGui.QWidget() w.show() sys.exit(app.exec_()) if __name__ == '__main__': main() 

when this is run with python -i example.py the console is blocked as long as the main-loop is executed.

How can I call w.resize(100,100) while the GUI is running?

3 Answers 3

0

ops, posted wrong answer before

there is a post in Stack about that

Execute Python code from within PyQt event loop

Sign up to request clarification or add additional context in comments.

1 Comment

As far as I see the QTimer.singleShot method only allows to excecute predefined functions during runtime. This does not allow for interaction from the console as it is still blocked. Or am I misunderstanding it?
0

The following example uses the code module to run a console in the command prompt (be sure to run the script from the command line). Subclassing QThread provides a route by which the console can be run in a separate thread from that of the main GUI and enables some interaction with it. The stub example below should be easy enough to incorporate into a larger packaged PyQt program.

from PyQt5.QtWidgets import * from PyQt5.QtCore import * import threading #used only to id the active thread import code import sys class Worker(QThread): #Subclass QThread and re-define run() signal = pyqtSignal() def __init__(self): super().__init__() def raise_sys_exit(self): #more gracefully exit the console print('(Deactivated Console)') raise SystemExit def setup_console(self,global_dict): console_exit = {'exit': self.raise_sys_exit} self.console = code.InteractiveConsole(locals=dict(global_dict,**console_exit)) def run(self): try: print('worker', threading.get_ident()) self.console.interact() except SystemExit: self.signal.emit() class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args,**kwargs) self.data = [1,2,3,4] #some data we might want to look at layout = QVBoxLayout() self.b = QPushButton("Interact") self.b.clicked.connect(self.b_clicked) layout.addWidget(self.b) w = QWidget() w.setLayout(layout) self.setCentralWidget(w) self.worker = Worker() self.worker.signal.connect(self.finished) def finished(self): self.b.setEnabled(True) def b_clicked(self): print('main',threading.get_ident()) self.worker.setup_console(globals()) #pass the global variables to the worker self.worker.start() self.b.setEnabled(False) #disable the GUI button until console is exited if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() app.exec_() 

Comments

-1

The easiest way is to use IPython:

ipython --gui=qt4 

See ipython --help or the online documentation for more options (e.g. gtk, tk, etc).

2 Comments

Could you provide an example on how this is used? I cannot seem to replicate the example from my post when I run Ipyton with the qt4 gui. I cannot import QtGui, but I cant use the predefined QtGui either.
If you get an import error, make sure that PyQt is in your PYTHONPATH. If you are on ubuntu/debian you can install both pyqt and ipython with apt-get install python-qt4 ipython. Then you can start the shell with the --gui=qt4 and begin testing your qt code. When you type w.show() the window will instantly show up, without blocking (You don't have to run app.exec_() because I guess ipython already does that for you).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.