0

Python ソケット プログラミングと PyQt を使用して、単純なサーバー/クライアント アプリを作成したいと考えています。クライアントはサーバー側にファイルを送信できます。うまくいきましたが、サーバー側の GUI が表示されません。

Dikei のアドバイスを受けた後、ソケット部分を処理する新しいスレッドを作成して、サーバー側のコードを変更しました。

ここに私のサーバー側のコードがあります:

#! /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_()

ここに私のクライアント側のコードがあります:

#! /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_()

問題は次のとおりです。

  1. サーバー側の GUI がまったく表示されない!理由がわかりません。スレッドを使用する必要がありますか?
  2. また、サーバーは固定された名前で固定された場所にファイルを保存するだけです。サーバー側で場所を指定し、クライアント側から元のファイル名を取得する方法はありますか?

編集:#1は解決されましたが、スレッドによって発行された信号はまったくキャッチされていないようで、サーバーのブラウザはまったく更新されていません。

#2はまだ解決されていません。

助けてくれてありがとう!

4

1 に答える 1

1

あなたのプログラムは無限ループに陥っています

while 1:
    self.receiveFile()

form.show()に到達することはありません。おそらく、すべてを別のスレッドで実行し、信号を GUI を実行するメイン スレッドに送り返す必要があります。

2 番目の問題については、データを送信する前にファイル名を最初に送信できます。サーバーがファイル名を受け取ると、ワーカー スレッドがシグナルを発します。この信号は、メイン スレッドをトリガーして、フォルダーを選択するための QFileDialog をポップアップします。フォルダーが選択されると、メイン スレッドはフォルダー パスを含むシグナルをワーカー スレッドに送信し、ワーカー スレッドはファイルを保存できます。

于 2012-04-04T09:49:17.430 に答える