从另一个Python进程更新Python GUI

时间:2015-07-29 07:19:46

标签: python-2.7 qt4 pyqt4 qtgui

我已经谷歌搜索了将近两天,以便在Python中找到关于我的问题的答案。我完全迷失了,并且对如何解决我的问题感到困惑。

这就是我想要做的。我有一个Python文件名mymain.py(GUI)及其运行和活动,我想通过在终端中运行此命令来更改和更新我的GUI中的Qlabel文本

  

sudo python myarg.py -i [任何数字]

其中[number]是用户定义的。例如,我在终端中运行了这段代码

  

sudo python myarg.py -i 5

GUI中的Qlabel文本应更改为5.

这是我的代码:

mymain.py

from PyQt4 import QtCore, QtGui
import PyQt4
import sys
import os
from time import sleep

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(QtGui.QMainWindow):
    updatenumber = QtCore.pyqtSignal(int)
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setupUi(self)
        self.num = 0 
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(536, 537)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
        self.gridLayout = QtGui.QGridLayout()
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.lblNumber = QtGui.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily(_fromUtf8("DS-Digital"))
        font.setPointSize(300)
        self.lblNumber.setFont(font)
        self.lblNumber.setObjectName(_fromUtf8("lblNumber"))
        self.lblNumber.setAlignment(QtCore.Qt.AlignCenter)
        self.gridLayout.addWidget(self.lblNumber)
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
        self.lblNumber.setText(QtGui.QApplication.translate("MainWindow", "0", None, QtGui.QApplication.UnicodeUTF8))
        self.thread =  Thread()
        self.thread.update.connect(self.lblNumber.text)

class Thread(QtCore.QThread):
    update = QtCore.pyqtSignal(str)
    def init(self, parent=app):
        QtCore.QThread.init(self,parent)
        self.num = ''
    def run(self):
        self.update.emit(self.num)

if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    ex = Ui_MainWindow()
    ex.show()
    sys.exit(app.exec_())

myarg.py

from mymain import Thread
import sys, getopt
from PyQt4 import QtCore, QtGui
import PyQt4

def main(argv):
   ctr = ''
   try:
      opts, args = getopt.getopt(argv,"hi:",["ifile="])
   except getopt.GetoptError:
      print 'sigarg.py -i <ctr>'
      sys.exit(1)
   for opt, arg in opts:
      if opt == '-h':
         print 'sigarg.py -i <ctr>'
         sys.exit()
      elif opt in ("-i", "--ifile"):
         ctr = arg
   m = Thread()
   m.num = ctr
   m.start()

if __name__ == "__main__":
   main(sys.argv[1:])

我使用的Python版本是2.7,而我的机器是Raspberry Pi。

1 个答案:

答案 0 :(得分:0)

您的用例与单实例应用程序非常相似。在第一次调用命令时,显示主窗口;然后所有后续调用只将其参数发送给正在运行的应用程序。

他们有很多方法可以做到这一点,但最简单的方法之一是使用本地套接字。为了让您了解这是如何工作的,这是一个基于我曾经写过的osd音量控制的演示:

import sys, getopt
from PyQt4 import QtCore, QtGui, QtNetwork

QtGui.QApplication.setApplicationName('foobar')
QtGui.QApplication.setApplicationVersion('0.1')

class Window(QtGui.QLabel):
    def __init__(self, name):
        super(Window, self).__init__()
        self.server = QtNetwork.QLocalServer(self)
        self.server.newConnection.connect(self.handleMessage)
        if not self.server.listen(name):
            raise RuntimeError(self.server.errorString())

    def closeEvent(self, event):
        self.server.close()
        self.server.removeServer(self.server.fullServerName())

    def handleMessage(self, message=None):
        socket = self.server.nextPendingConnection()
        if socket is not None:
            if socket.waitForReadyRead(2000):
                message = socket.readAll().data().decode('utf-8')
                socket.disconnectFromServer()
            socket.deleteLater()
        if message == 'stop':
            self.close()
        else:
            self.setText(message)

def usage():
    print("""
usage: %s [opts] [message]

options:
 -h  display this help and exit
 -V  display version information
 -s  stop the server
""" % QtGui.QApplication.applicationName())

def main():
    keys = 'hVs'
    try:
        options, args = getopt.getopt(sys.argv[1:], keys)
    except getopt.GetoptError as exception:
        print('ERROR: %s' % exception)
        usage()
        return 2
    else:
        options = dict(options)
        if '-h' in options:
            usage()
        elif '-V' in options:
            print('%s-%s' % (
                QtGui.QApplication.applicationName(),
                QtGui.QApplication.applicationVersion(),
                ))
        else:
            if '-s' in options:
                message = 'stop'
            else:
                message = args[0] if args else None
            name = '%s_server' % QtGui.QApplication.applicationName()
            socket = QtNetwork.QLocalSocket()
            socket.connectToServer(name, QtCore.QIODevice.WriteOnly)
            if socket.waitForConnected(500):
                socket.write(message.encode('utf-8'))
                if not socket.waitForBytesWritten(2000):
                    print('ERROR: could not write to socket: %s' %
                          socket.errorString())
                socket.disconnectFromServer()
            elif socket.error() != QtNetwork.QAbstractSocket.HostNotFoundError:
                print('ERROR: could not connect to server: %s' %
                      socket.errorString())
            elif message is not None:
                print('ERROR: server is not running')
            else:
                app = QtGui.QApplication(sys.argv)
                window = Window(name)
                window.setGeometry(50, 50, 200, 30)
                window.show()
                return app.exec_()
    return 0

if __name__ == '__main__':

    sys.exit(main())