Gnijuohz
Gnijuohz

Reputation: 3364

Where is my server side GUI?!(using pyqt)should I use thread?

I want to create a simple server/client app using python socket programming and PyQt.The client can send files to the server side.It worked.But I can't see my server side GUI!

After taking the Dikei's advice I changed my server side code by creating a new thread to handle socket part.

Here is my server side code:

#! /usr/bin/python
import sys
import socket
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtNetwork import *

HOST = '127.0.0.1'
PORT = 9996
SIZEOF_UINT32 = 4

class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.worker = Worker()
        self.connect(self.worker, SIGNAL("received"), self.updateUi)
        self.connect(self.worker, SIGNAL("finished()"), self.updateUi)
        self.connect(self.worker, SIGNAL("terminated()"), self.updateUi)
        # Create widgets/layout
        self.browser = QTextBrowser()
        self.selectButton = QPushButton('Close server')
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.selectButton)
        self.setLayout(layout)
        self.setWindowTitle("Server")

    def updateUi(self, text):
        self.browser.append(text)


class Worker(QThread):

    def __init__(self,parent = None):
        super(Worker, self).__init__(parent) 
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def receiveFile(self):
        self.conn, self.addr = self.socket.accept()
        totalData = ''
        while 1:
            data = self.conn.recv(1024)
            if not data: break
            totalData += data
        print totalData
        f = open('/home/jacos/downfrom','w')
        f.write(totalData) 
        f.close()
        self.emit(SIGNAL("received"),"received a file")
        self.conn.close()

    def run(self):
        self.socket.bind((HOST, PORT))
        self.socket.listen(5)
        while 1:
            self.receiveFile() 



app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

here is my client side code:

#! /usr/bin/python
# -*- coding: utf8 -*-
import sys
import socket
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtNetwork import *

HOST = '127.0.0.1'
PORT = 9996
SIZEOF_UINT32 = 4

class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)


        # Create widgets/layout
        self.browser = QTextBrowser()
        self.selectButton = QPushButton('Send a File')
        self.connectButton = QPushButton("Connect")
        self.connectButton.setEnabled(True)
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.selectButton)
        layout.addWidget(self.connectButton)
        self.setLayout(layout)

        # Signals and slots for line edit and connect button
        self.selectButton.clicked.connect(self.sendFile)
        self.connectButton.clicked.connect(self.connectToServer)

        self.setWindowTitle("Client")

    # Update GUI
    def updateUi(self, text):
        self.browser.append(text)



    def sendFile(self):
        filename=QFileDialog.getOpenFileName(self, 'Open File', '.')
        self.socket.sendall(open(filename,'rb').read())
        self.updateUi("Sent a file:" + filename)
        self.socket.close()
        self.connectButton.setEnabled(True)

    def connectToServer(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((HOST, PORT))
        self.connectButton.setEnabled(False)
        self.updateUi("Connected")





app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()

The problems are:

  1. My server side GUI doesn't appear at all!I don't understand why. Should I use thread?
  2. Also, the server only stores the file in a fixed place with a fixed name. Is there any way I can specify the location in the server side and get the original file name from client side?

Edit:Now #1 is solved but the signal emitted by the thread doesn't seem to be caught at all, the browser of the server isn't updated at all.

The #2 is still not solved.

Thanks for any help!

Upvotes: 0

Views: 1450

Answers (1)

Kien Truong
Kien Truong

Reputation: 11381

Your program is stuck in an infinite loop

while 1:
    self.receiveFile()

The form.show() is never reached. You should probably do everything in a different thread and send signal back to main thread which run the GUI.

For the second problem, you can send the filename first before sending the data. When the server receive the filename, the worker thread will emit a signal. This signal will trigger the main thread to pop up a QFileDialog for you to select a folder. After the folder is selected, the main thread will send a signal with the folder path to the worker thread and the worker thread can save the file.

Upvotes: 1

Related Questions