0
votes

I write a simple socket app with pyqt4 and threading in python3.3, but i have problem with running Qt classes command like show a message in label or anything, only python code works properly.

Not show anything to S_label in my gui,

I use 2 ways to show any message on S_label but neither of ways not work,

  1. self._ui
  2. self.ui

in code :

  1. self.ui.S_label.setText("test !")
  2. self._ui.S_label.setText("test !")
  3. self.ui.S_label.setText("{0}:{1} is connected.".format(addr, remoport))

for both two ways print works well:

  1. print(self._ui)
  2. print(self.ui)

print output :

-<imigui.Ui_MainWindow object at 0x7fe0746cac10>

-<imigui.Ui_MainWindow object at 0x7fe0746d5d90>

What I'm doing wrong?

my code :

from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow

class imiserv(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.Sport_lineEdit.setMaxLength(5)
        self.ui.Sconnect_pushButton.clicked.connect(self.serv)

    def serv(self):
        self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.host= str(self.ui.Sip_lineEdit.text())
        self.port= int(self.ui.Sport_lineEdit.text())
        MY_LOCK = threading.Lock()
        class CountT(threading.Thread, imiserv):
            def __init__(self, ui, ser):
                super().__init__()
                imiserv.__init__(self)
                self._sersock= ser

                self._ui= ui
                print(self._ui)
                print(self.ui)
                self.ui.S_label.setText("test !")
                self._ui.S_label.setText("test !")

            def run(self):
                MY_LOCK.acquire()
                while True:
                    cliconn, (addr, remoport)= self._sersock.accept()
                    self.cstr= cliconn.recv(1024)

                    self.ui.S_label.setText("{0}:{1} is connected.".format(addr, remoport))
                    cliconn.close()

                    print(self.cstr)
                MY_LOCK.release()

        try :
            self.sersock.bind((self.host, self.port))
            self.sersock.listen(5)
            a= CountT(self.ui, self.sersock)
            a.daemon= True # for exit from thread when close gui
            a.start()
        except socket.error as err:
            self.ui.S_label.setText(err)

Edit(new problem) :

I have a new problem with your way:i added a qtextedit to my gui and when i want to settext to it in my code Segmentation fault happened and app crashed ,

error :

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x15c4460), parent's thread is QThread(0xfeb570), current thread is QThread(0x15d3900)
Segmentation fault

My Code:

from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow

class imiserv(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.Sport_lineEdit.setMaxLength(5)
        self.ui.Sconnect_pushButton.clicked.connect(self.serv)

    def serv(self):
        self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.host= str(self.ui.Sip_lineEdit.text())
        self.port= int(self.ui.Sport_lineEdit.text())

        MY_LOCK = threading.Lock()
        class CountT(threading.Thread):
            def __init__(self, label, ser, qtext):
                super().__init__()
                self._sersock= ser

                self._uilabel= label
                self._uiClog= qtext


            def run(self):
                MY_LOCK.acquire()
                while True:
                    cliconn, (addr, remoport)= self._sersock.accept()
                    self.cstr= cliconn.recv(1024)

                    self._uilabel.setText("{0}:{1} is connected.".format(addr, remoport))
                    cliconn.close()

                    print(self.cstr)
                    self._uilabel.setText(self.cstr) # it's ok!
                    self._uiClog.setText(msg) # Segmentation fault

                MY_LOCK.release()


        try :
            self.sersock.bind((self.host, self.port))
            self.sersock.listen(5)
            a= CountT(label= self.ui.S_label, ser= self.sersock, qtext= self.ui.Clog_textEdit)
            a.daemon= True # for exit from thread when close gui
            a.start()
            self.ui.S_label.setText("Connected !")
        except socket.error as err:
            self.ui.S_label.setText(err) # it's ok !
    self.ui.self.ui.Clog_textEdit.setText(err) # it's ok !

Why ?


Edit(new problem2) :

this is my code :

from PyQt4 import QtCore, QtGui from imigui import Ui_MainWindow

class imiserv(QtGui.QMainWindow):

send_msg = pyqtSignal('QString', 'QString')

def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)
    self.ui.Sport_lineEdit.setMaxLength(5)
    self.ui.Sconnect_pushButton.clicked.connect(self.serv)

    self.send_msg.connect(self.write_msg)

def write_msg(self, lbl_msg= None, txt_msg= None):
    if lbl_msg:
        self.ui.C_label.setText(lbl_msg)
    if txt_msg:
        self.ui.Clog_textEdit.setText(txt_msg)

def serv(self):
    MY_LOCK = threading.Lock()
    class CountT(threading.Thread):
        def __init__(self, parent):
            threading.Thread.__init__(self)
            self._parent= parent

        def run(self):
            MY_LOCK.acquire()
            self._parent.send_msg.emit("Waiting connections","")
            while True:
                cliconn, (addr, remoport)= self._parent.clis.accept()
                clirecmsg= str(cliconn.recv(1024)
                self._parent.send_msg.emit("{0}:{1} is connected.".format(addr, remoport), "{0}:{1}".format(addr, remoport)
                cliconn.close()

            MY_LOCK.release()

    try :
        self.clis= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.clis.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        clierhost= str(self.ui.Sip_lineEdit.text())
        clierport= int(self.ui.Sport_lineEdit.text())
        self.clis.bind((clierhost, clierport))
        self.clis.listen(5)
        a= CountT(self)
        a.daemon= True
        a.start()
    except socket.error as err:
        err= str(err)
        print(err)

and this is error that happened decussate, i should press button twice for get event for first time error showed in linux and nothing in windows and for second press event is happened,(this error show only in linux os.)

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.3/threading.py", line 637, in _bootstrap_inner
    self.run()
  File "imiclilap.py", line 34, in run
    cliconn, (addr, remoport)= self._parent.clis.accept()
  File "/usr/lib/python3.3/socket.py", line 135, in accept
    fd, addr = self._accept()
OSError: [Errno 22] Invalid argument

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python3.3/threading.py", line 637, in _bootstrap_inner
    self.run()
  File "imiclilap.py", line 34, in run
    cliconn, (addr, remoport)= self._parent.clis.accept()
  File "/usr/lib/python3.3/socket.py", line 135, in accept
    fd, addr = self._accept()
OSError: [Errno 22] Invalid argument
1

1 Answers

1
votes

The following code works for me (Python 2.6 here). I removed the inheritance of CountT with imiserv and replaced the ui object by the QLabel S_label the imiserv instance instead. A pyqtsignal allows the thread CounT to write text to the QLabel and the QTextEdit:

import socket
import threading

from PyQt4 import QtCore, QtGui
from imigui import Ui_MainWindow

class imiserv(QtGui.QMainWindow):

    send_msg = pyqtSignal('QString', 'QString')

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.Sport_lineEdit.setMaxLength(5)
        self.ui.Sconnect_pushButton.clicked.connect(self.serv)

        self.send_msg.connect(self.my_slot)

    def write_msg(self, lbl_msg, txt_msg):
        self.ui.S_label.setText(lbl_msg)
        self.ui.Clog_textEdit.setText(txt_msg)

    def serv(self):
        self.sersock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sersock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.host= str(self.ui.Sip_lineEdit.text())
        self.port= int(self.ui.Sport_lineEdit.text())
        MY_LOCK = threading.Lock()
        class CountT(threading.Thread):
            def __init__(self, parent):
                threading.Thread.__init__(self)
                self._parent= parent

            def run(self):
                MY_LOCK.acquire()
                self._parent.send_msg.emit("Waiting connections","")
                while True:
                    cliconn, (addr, remoport)= self.__parent.sersock.accept()
                    self.cstr= cliconn.recv(1024)
                    self._parent.send_msg.emit("{0}:{1} is connected.".format(addr, remoport), self.cstr)
                    cliconn.close()

                MY_LOCK.release()

        try :
            self.sersock.bind((self.host, self.port))
            self.sersock.listen(5)
            a= CountT(self)
            a.daemon= True # for exit from thread when close gui
            a.start()
        except socket.error as err:
            self.ui.S_label.setText(err.strerror.decode("utf-8"))
            self.ui.Clog_textEdit.setText(err.strerror.decode("utf-8"))

if __name__ == "__main__":
  import sys
  app = QtGui.QApplication(sys.argv)
  s = imiserv()
  s.show()
  sys.exit(app.exec_())