0

Saving the code below as application.py allows me to run a process that when started shows a simple QDialog with a QLabel:

python application.py

While the process is running and dialog shown I would like to change the default title "somewhere over the rainbow" to something else. How to achieve it?

enter image description here

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
app = QApplication([])

class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setLayout(QVBoxLayout())
        self.label = QLabel('somewhere over the rainbow')
        self.layout().addWidget(self.label)
        self.show()

dialog = Dialog()
app.exec_()

edited:

Below is an example of QLabel's text set to a new string value "01011001001001110100100110":

enter image description here

alphanumeric
  • 17,967
  • 64
  • 244
  • 392
  • Could you explain yourself better, would not it just be `self.label.setText("some text")` or what do you mean by title? – eyllanesc Apr 06 '18 at 04:08
  • Thanks for your comment! The post has been edited. Ideally the solution would allow anther process to emit a signal that could be catch by the application's event listening thread (Qt maybe?) – alphanumeric Apr 06 '18 at 04:23
  • at what time do you want to change the text? the solution would not be self.label.setText("01011001001001110100100110")? – eyllanesc Apr 06 '18 at 04:27
  • I would like to .setText("01011001001001110100100110") from another Python process. So the main `application` (the process that started the QDialog) could be "remotely controlled" from another Python application or a process. – alphanumeric Apr 06 '18 at 04:31
  • 1
    then use `dialog.label.setText("01011001001001110100100110")`, if you do not provide a [mcve] I can not give you another help, I find it strange, you always provide good [mcve] – eyllanesc Apr 06 '18 at 04:33
  • 1
    _I would like to .setText(...) from another Python process._ It's not a good idea that one _process_ calls methods of another _process_ and most OSes prohibits this. For this, [**IPC**](https://en.wikipedia.org/wiki/Inter-process_communication) has been invented. Processes may communicate via files, pipes, shared memory (or memory mapped files), or even over network (which eliminates the constraint that both processes have to run on the same computer). Which of them to use is dependent on required speed, required robustness, etc... not to forget experience to implement them properly. – Scheff's Cat Apr 06 '18 at 06:18
  • May be, this helps: [Python Doc.: 17.2. multiprocessing — Process-based parallelism](https://docs.python.org/3/library/multiprocessing.html). There are dedicated subsections for IPC: [17.2.1.3. Exchanging objects between processes](https://docs.python.org/3/library/multiprocessing.html#exchanging-objects-between-processes) and [17.2.1.4. Synchronization between processes](https://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes). – Scheff's Cat Apr 06 '18 at 06:26

1 Answers1

0

Below is a working solution designed around SocketServer's TPCServer and BaseRequestHandler Classes.

This implementation utilizes QThread Class.

enter image description here

application.py

import SocketServer

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

IP, PORT = '127.0.0.1', 62236

app = QApplication([])


class Emitter(QObject):
    signal = pyqtSignal(str)


class Handler(SocketServer.BaseRequestHandler):
    emitter = Emitter()

    def handle(self):
        self.emitter.signal.emit(self.request.recv(1024))


class Thread(QThread):
    def __init__(self, target, parent=None):
        QThread.__init__(self, parent)
        self.target = target

    def run(self):
        while True:
            self.target()


class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        Handler.emitter.signal.connect(self.onEmit)
        self.server = SocketServer.TCPServer((IP, PORT), Handler)

        thread = Thread(target=self.server.handle_request)
        thread.start()

        self.setLayout(QVBoxLayout())
        self.label = QLabel('somewhere over the rainbow')
        self.layout().addWidget(self.label)
        self.show()

    def closeEvent(self, event):
        self.server.server_close()
        event.accept()

    def onEmit(self, arg):
        self.label.setText(str(arg))


dialog = Dialog()
app.exec_()

client.py

import socket

IP, PORT = '127.0.0.1', 62236

def send(data):
    SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    SOCKET.connect((IP, PORT))
    SOCKET.send(data)
    SOCKET.close()

for i in range(2, 1000):
    send('data %07d'%i)

send(raw_input("input:\t"))

With threading.Thread use SocketServer.TCPServer.serve_forever method instead of SocketServer.TCPServer.handle_request:

    import threading
    thread = threading.Thread(target=self.server.serve_forever)
    thread.start()
alphanumeric
  • 17,967
  • 64
  • 244
  • 392