Emit signal in standard python thread

2024/10/9 16:27:33

I have a threaded application where I do have a network thread. The UI-part passes a callback to this thread. The thread is a normal python thread - it's NO QThread.

Is it possible to emit PyQT Slot within this thread?

Answer

No, it is not possible to emit a PyQt signal from a python thread like this.

However, a possible solution is to use an additional object shared by both threads, making the necessary operations to finally emit a thread-safe PyQt signal.

Here is an implementation of a "SafeConnector" class, making use of a pair of connected sockets and a Queue to exchange data between the two threads, and using a QSocketNotifier to get back in Qt's loop. A QObject is used to make it possible to emit a proper Qt signal:

from PyQt4 import Qt, QtCore, QtGui
import threading
import socket
import Queue
import time# Object of this class has to be shared between
# the two threads (Python and Qt one).
# Qt thread calls 'connect',   
# Python thread calls 'emit'.
# The slot corresponding to the emitted signal
# will be called in Qt's thread.
class SafeConnector:def __init__(self):self._rsock, self._wsock = socket.socketpair()self._queue = Queue.Queue()self._qt_object = QtCore.QObject()self._notifier = QtCore.QSocketNotifier(self._rsock.fileno(),QtCore.QSocketNotifier.Read)self._notifier.activated.connect(self._recv)def connect(self, signal, receiver):QtCore.QObject.connect(self._qt_object, signal, receiver)# should be called by Python threaddef emit(self, signal, args):self._queue.put((signal, args))self._wsock.send('!')# happens in Qt's main threaddef _recv(self):self._rsock.recv(1)signal, args = self._queue.get()self._qt_object.emit(signal, args)class PythonThread(threading.Thread):def __init__(self, connector, *args, **kwargs):threading.Thread.__init__(self, *args, **kwargs)self.connector = connectorself.daemon = Truedef emit_signal(self):self.connector.emit(QtCore.SIGNAL("test"), str(time.time()))def run(self):while True:time.sleep(1)self.emit_signal()if __name__ == '__main__':app = QtGui.QApplication([])mainwin = QtGui.QMainWindow()label = QtGui.QLabel(mainwin)mainwin.setCentralWidget(label)connector = SafeConnector()python_thread = PythonThread(connector)connector.connect(QtCore.SIGNAL("test"), label.setText)python_thread.start()mainwin.show()app.exec_()
https://en.xdnf.cn/q/69998.html

Related Q&A

Sqlalchemy from_statement() cannot locate column

I am following the sqlalchemy tutorial in http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.htmlNevertheless, instead of using a SQLite backend, I am using MySQL. The problem is that when I try to exe…

Python - how to check if weak reference is still available

I am passing some weakrefs from Python into C++ class, but C++ destructors are actively trying to access the ref when the real object is already dead, obviously it crashes...Is there any Python C/API a…

Django using locals() [duplicate]

This question already has answers here:Django template and the locals trick(8 answers)Closed 5 years ago.I am beginner in web development with Django. I have noticed that the locals() function is used …

python ghostscript: RuntimeError: Can not find Ghostscript library (libgs)

When trying to run hello-world exampleimport sys import ghostscriptargs = ["ps2pdf", # actual value doesnt matter"-dNOPAUSE", "-dBATCH", "-dSAFER","-sDEVICE…

what is the default encoding when python Requests post data is string type?

with fhe following codepayload = 工作报告 总体情况:良好 r = requests.post("http://httpbin.org/post", data=payload)what is the default encoding when Requests post data is string type? UTF8…

How to initialize a database connection only once and reuse it in run-time in python?

I am currently working on a huge project, which constantly executes queries. My problem is, that my old code always created a new database connection and cursor, which decreased the speed immensivly. S…

Django - ModelForm: Add a field not belonging to the model

Note: Using django-crispy-forms library for my form. If you have a solution to my problem that involves not using the cripsy_forms library, I accept it all the same. Not trying to be picky just need a …

Row by row processing of a Dask DataFrame

I need to process a large file and to change some values.I would like to do something like that:for index, row in dataFrame.iterrows():foo = doSomeStuffWith(row)lol = doOtherStuffWith(row)dataFrame[col…

Tweepy Why did I receive AttributeError for search [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.This question was caused by a typo or a problem that can no longer be reproduced. While similar q…

Running qsub with anaconda environment

I have a program that usually runs inside a conda environmet in Linux, because I use it to manage my libraries, with this instructions:source activate my_environment python hello_world.pyHow can I run …