I am trying to create a simple rest endpoint, that when hit, it changes the status of a tray icon that is installed by the program itself.
I believe that I need Flask and the QApplication to run in different threads and I tried to do this.
However I am not familiar with python and most probably I am doing something wrong below:
import sys
import asyncio
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import (
QSystemTrayIcon,
QApplication,
QWidget
)
from flask import Flask
async def gui():
app = QApplication(sys.argv)
w = QWidget()
trayIcon = QSystemTrayIcon(QIcon("disconnected.png"), w)
trayIcon.show()
print("running gui")
return app.exec()
async def rest():
app1 = Flask(__name__)
@app1.route("/status/connected")
def setStatusConnected():
return "I will signal gui to change icon to connected"
@app1.route("/status/disconnected")
def setStatusDisconnected():
return "I will signal gui to change icon to disconnected"
print("creating rest endpoint")
return app1.run()
async def main():
return await asyncio.gather(gui(), rest() )
if __name__ == "__main__":
asyncio.run(main())
When I run the code above I see only "running gui" and I can see the tray icon being installed to the status bar. I do not see "creating rest endpoint"
If I comment-out the "return app.exec()". I see the "creating rest endpoint" and I can access the endpoints, but I don't see the the tray icon.
Whay is am I missing?
extra info: this is my Pipfile
(Using pipenv
)
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
pyqt6 = "*"
flask = {extras = ["async"], version = "*"}
[dev-packages]
[requires]
python_version = "3.10"
ayncio
is useful when programs usesawait
inside its code - insideapp.run()
and insideapp.exec()
- but as I knowQt
andFlask
don't do this. (but maybeFlask
has version which usesasyncio
)You may need to use threading to run programs in separated threads (or one program run in separated thread and other run in current thread).
Version 1: both programs in separated threads
Version 2: one programs in separated thread and other in current thread
Full working code
EDIT:
I not sure if these threads may use Qt signals to communicates. They may need to use queue to comunicate, and
Qt
may needQTimer
to check periodically if there is new information inqueue
.Other idea:
Flask
should haveurl
which returns current status (information if it is connected or disconnected) andQt
could useQTime
with probablyQtNetwork.QNetworkRequest(QtCore.QUrl(url))
to check this status. This way you can always use other GUI framework to check status. Or you can check status in text console (ie. usingcurl
,wget
)If you plan to use
Flask
only to change status inQt
then maybe you should useQtNetwork
to run server directly inQt
without usingFlask
.