Reputation: 3364
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:
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
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