merging the ZMQ event loop with the QT and Pyforms event loops

In attempting to integrate both zmq and a Pyforms GUI, I am faced with the challenge of each requiring its own event loop. The goal is to create a Pyforms GUI with a text field that can display incoming zmq messages. Below is the simplified code that I am working on:

import pyforms
from   pyforms          import BaseWidget
from   pyforms.controls import ControlTextArea
from   pyforms.controls import ControlButton
import threading
import zmq
from zmq.asyncio import Context
from zmq.eventloop.zmqstream import ZMQStream
from zmq.eventloop import ioloop

class SimpleExample1(BaseWidget):

    def __init__(self):
        super(SimpleExample1,self).__init__('Simple example 1')

        #Definition of the forms fields
        self._controltextarea     = ControlTextArea('textarea to show incoming zmq messages')
        self._button        = ControlButton('Press this button')

        def echo(msg):
            self._controltextarea.__add__(msg) 

        context = Context.instance()
        s = context.socket(zmq.PULL)
        s.connect('tcp://127.0.0.1:5014')
        stream = ZMQStream(s)
        stream.on_recv(echo)

#Execute the application
if __name__ == "__main__":
    
    guiThread = threading.Thread(target=pyforms.start_app( SimpleExample1 ))
    zmqThread = threading.Thread(target=lambda: ioloop.IOLoop.current().start())
    zmqThread.setDaemon(True)
    guiThread.start()
    zmqThread.start()

This is the ZMQ sender.

import zmq
import time

context = zmq.Context()
publisher = context.socket(zmq.PUSH)
publisher.bind('tcp://127.0.0.1:5014')

while True:
    publisher.send_string('something')
    time.sleep(1)

Exploring possible solutions, one involves using threads as in the provided code. However, combining both event loops has proven challenging so far. Another approach could be integrating the zmq function call "echo()" into the Pyforms' event loop based on QT. This method might offer a more elegant solution, but the implementation remains uncertain.

While experimenting with these solutions, resources like pyzmq readthedocs, zeromq org, and pyforms readthedocs have been invaluable. Despite delving into concepts such as futures, promises, coroutines, asyncio, and green in Python, successfully achieving a simple function call for "echo" upon message receipt remains elusive.

If you have any insights or suggestions on how to make this setup work seamlessly, I would greatly appreciate it.

Answer №1

Sorry for the vague response in advance, but I believe it can serve as a good starting point.

It appears that PyForms is ultimately based on Qt, which has the capability to utilize a socket (or file descriptor) as an input source. ZeroMQ, particularly the C version, provides a file descriptor that indicates when a ZMQ message has been received and is ready to be read. This suggests that Qt could potentially utilize this file descriptor to trigger a callback function that reads messages from any ZMQ socket, processing them within Qt's event loop thread (which could offer additional advantages).

Unfortunately, I am unsure if PyZMQ and PyForms expose these functionalities.

Answer №2

Appreciation to Bazza for the valuable input provided. Your solution was instrumental in helping me overcome my issue. Through diligent research on emitting a Qevent, I stumbled upon a helpful example which ultimately led to resolving the problem at hand. The consolidated code snippet now appears as follows:

import pyforms
from   pyforms          import BaseWidget
from   pyforms.controls import ControlTextArea
from   pyforms.controls import ControlButton
import threading
import zmq
from PyQt5 import QtCore

class ZeroMQ_Listener(QtCore.QObject):

    message = QtCore.pyqtSignal(str)

    def __init__(self):

        QtCore.QObject.__init__(self)

        # Socket establishment for server communication
        context = zmq.Context()
        self.socket = context.socket(zmq.PULL)
        self.socket.connect('tcp://127.0.0.1:5014')
        print('connected!')
        self.running = True

    def loop(self):
        while self.running:
            string = self.socket.recv_string()
            self.message.emit(string)


class SimpleExample1(BaseWidget):

    def __init__(self):
        super(SimpleExample1,self).__init__('Simple example 1')

        #Form fields definition
        self._controltextarea     = ControlTextArea('textarea to show incoming zmq messages')
        self._button        = ControlButton('Press this button')

        message = QtCore.pyqtSignal(str)
        self.thread = QtCore.QThread()
        self.zeromq_listener = ZeroMQ_Listener()

        self.zeromq_listener.moveToThread(self.thread)

        self.thread.started.connect(self.zeromq_listener.loop)
        self.zeromq_listener.message.connect(self.signal_received)

        QtCore.QTimer.singleShot(0, self.thread.start)


    def signal_received(self, message):
        self._controltextarea.__add__(message)

#Run the application
if __name__ == "__main__":
    guiThread = threading.Thread(target=pyforms.start_app( SimpleExample1 ))

    guiThread.start()

Deep gratitude and warm regards!!!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The update method of a dictionary will only insert the last value provided

I came across this code snippet (you can find it here) and have been struggling with the issue where the .update method only adds the last value to the dictionary. I tried different solutions found online but still couldn't resolve it. import json ...

Python List Reduction through Performing Bitwise OR Operations

I am dealing with two lists consisting of zeros and ones. These lists are always the same length, but the values within can vary. Here is an example, showcasing a scenario where I need a solution that can apply to lists of any size with zeros and ones at a ...

Fundamental List manipulation

I ran a simple code snippet in the Python interactive shell >>> arr=[1,2,3] >>> id(arr) 36194248L >>> arr.append(4) >>> arr [1, 2, 3, 4] >>> id(arr) 36194248L >>> >>> id([1,2,3]) 36193288L > ...

Exploring Python's doctest to differentiate between matching single or double quotes in output instead of just single quotes

My go-to tool for formatting code is the Black auto-formatter, and it has ingrained in me the habit of using double quotes. Using double quotes has become second nature to me. By default, many classes' repr output in Python uses single quotes when pr ...

Using Beautiful Soup, extract various elements from a webpage in a repeated sequence

I'm trying to scrape a table that contains a loop, but I'm running into issues with extracting certain elements. <ul> <li class="cell036 tal arrow"><a href=" y/">ALdCTL</a></li> <li class="cell009">5,71</li ...

Python automates the process of loading extensions in firefox using selenium

I'm facing an issue trying to incorporate Firefox addons into headless Firefox using the Selenium browser in Python. from selenium import webdriver import time geckodriver = 'C:\\Gecko\\geckodriver.exe' options = webdri ...

python-rq worker failing to process pending jobs

Encountering a challenge while configuring python-rq - the rqworker is not acknowledging jobs pushed to the queue it's supposed to monitor. All operations are conducted within a virtualenv The code snippet in question is as follows: from redis i ...

The TimeoutException from selenium.common.exceptions has occurred: Notification

https://i.stack.imgur.com/telGx.png Experiencing the following issue with the line pst_hldr. Identified the error: File "/home/PycharmProjects/reditt/redit1.py", line 44, in get_links pst_hldr = wait.until(cond.visibility_of_element_locate ...

Using Python to enable/disable Wi-Fi on macOS operating system

There are times when my internet connection goes down because of my ISP provider, and it only starts working again after I reset the wifi connection. This causes timeout exceptions in my script until I manually switch off and then back on the wifi connec ...

Automating Checkbox Selections with Selenium in Python

I'm having trouble clicking on a checkbox. Here is the HTML Code: <div class="mb-1 p-3 termsCheck"> <input class="form-check-input float-end" type="checkbox" value="" id="flexCheckDefau ...

Is it advisable to implement a combination of repeat, batch, and shuffle operations on tf.data.Dataset before feeding it into the fit

Even after reading the documentation on tf.keras.Model.fit and tf.data.Dataset, I am still unsure about whether I should call repeat and batch on the dataset object when passing it to the fit function. Should I provide the batch_size and epochs arguments t ...

The structure of Django, NPM, and Node packages

When considering the architecture of the project I will be working on, it's important to note the structure of the node_packages: |- Django project |-- app1 |-- app2 |-- node_modules |--- foundation-sites |--- grunt |-- static |--- css |--- images | ...

Automating button clicks with Python and Selenium (Updated for a different problem)

After encountering ad pop-ups on a previous mp3 converter site, I decided to try using an alternative website, h2converter.com/tr/, for my script. However, this time the web driver had trouble finding the button and the program stopped due to a timeout e ...

Creating a dictionary or JSON file to store print output

Incorporating boto3 for AWS, the code snippet below showcases how to utilize it: import boto3 from trp import Document # Document s3BucketName = "bucket" documentName = "doc.png" # Amazon Textract client textract = boto3.client('textract') # ...

Interacting with an iframe element using Selenium in Python

I have a webpage with an iframe embedded, and I'm using Selenium for test automation: <iframe class="wysihtml5-sandbox" security="restricted" allowtransparency="true" frameborder="0" width="0" height="0" marginwidth="0" marginheight="0" style="dis ...

Tips for inputting a phone number into a form using Python

Can someone help with automating the completion of the application form below using Python? enter image description here I am struggling to fill out the phone number field in the form. The last name, first name, and email are randomly populated from the ...

Struggling to pinpoint the exact element in Python/Selenium

As I work on creating a website manipulation script to automate the process of email mailbox creation on our hosted provider, I find myself navigating new territory in Python and web scripting. If something seems off or subpar in my script, it's beca ...

Tips for executing a view function that includes an operation parameter without the need to refresh the page

I am currently working on a website that allows users to post comments and like posts. I have successfully created a view function that enables users to like posts, but I am unsure of how to implement ajax or a similar technique to carry out the request wi ...

Utilizing the py_compile.compile() function from a Python script

Currently, I am delving into the Python documentation. The Python script I have generates code that will be executed at a much later time. In order to ensure the validity of the generated code now, I need to perform a check. According to the documentatio ...

What is the best way to find the maximum value of a string in a group by operation in

Data Presentation: Input: User ID | Channel 123 | online 123 | Null 123 | Grouped by User ID and Maximum Channel: Output: User ID | Channel 123 | online SQL Query for achieving this: SELECT user_id, max(channel) FROM table_name GRO ...