How to control/drive/interact a PyQt GUI from command line in Python

后端 未结 2 1070
春和景丽
春和景丽 2020-12-07 00:02

I have a GUI application created with PyQt and I would like to be able to control it also from the python terminal through a kind of internal API.

Ideas :

2条回答
  •  北海茫月
    2020-12-07 00:52

    Using the main terminal : impossible since that it is blocked by the QApplication (by app.exec_())

    You can omit app.exec() if you are within a Python terminal and it will not be blocking. As explained here this works because...

    PyQt5 installs an input hook (using PyOS_InputHook) that processes events when an interactive interpreter is waiting for user input. This means that you can, for example, create widgets from the Python shell prompt, interact with them, and still being able to enter other Python commands.

    For example, enter the following in the Python shell to have a working Qt widget and a non-blocking REPL simultaniously.

    $> python
    Python 3.7.6 | packaged by conda-forge | (default, Jan  7 2020, 22:05:27)
    [Clang 9.0.1 ] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from PyQt5.QtWidgets import QApplication, QWidget
    >>> a = QApplication([])
    >>> w = QWidget()
    >>> w.show()
    >>> w.raise_()
    

    IPython has similar functionality. If you start it with ipython --gui=qt, or type %gui qt in the terminal you get the same effect...

    $> ipython
    Python 3.7.6 | packaged by conda-forge | (default, Jan  7 2020, 22:05:27)
    Type 'copyright', 'credits' or 'license' for more information
    IPython 7.11.1 -- An enhanced Interactive Python. Type '?' for help.
    
    In [1]: %gui qt
    
    In [2]: from PyQt5 import QtWidgets
    
    In [3]: win = QtWidgets.QPushButton("click me")
    
    In [4]: win.show()
    
    In [5]: win.raise_()
    

    I recommend to use IPython because it's better suited for interactive work and it will work with PySide (perhaps regular Python and PySide will also work; I didn't check).

    See also my earlier answer here

    Finally, even though this works I don't know how good the performance is. It's a good solution for a hobby project but if you have many users I would consider to implement an 'in-app' terminal or some form of inter-process communication.

提交回复
热议问题