How to share variable between multiprocessing and Pyside application.
I am a newbie.Can anyone help me?Any suggestion will be appreciated.Thanks very much.
This is my demo:
#!/usr/bin/env python
#coding:utf-8
#demo:pyside gui application communicate with multiprocessing.Process()
import sys,time
import multiprocessing as mp
import logging,logging.handlers
from PySide.QtCore import *
from PySide.QtGui import *
class mywindow(QWidget):
def __init__(self,appargs,qlog,qtogui,lock,v1):
super(mywindow, self).__init__()
self.appargs=appargs
self.qlog=qlog
self.qtogui=qtogui
self.lock=lock
self.v1=v1
self.initgui()
self.thtest=sidethread(self.qtogui,self)
self.thtest.start()
self.qlog.put('pyside application started.')
if isinstance(self.appargs['totalprogress'],int):
print(self.appargs['totalprogress'],self.appargs['crtprogress'])
else:
print(self.appargs['totalprogress'].value,self.appargs['crtprogress'].value)
def initgui(self):
self.btntest=QPushButton('logging test')
self.btntest.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
self.pgb=QProgressBar()
self.pgb.setMaximum(100)
self.pgb.setMinimum(0)
self.pgb.setValue(0)
self.teinfo=QTextEdit()
self.teinfo.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
self.teinfo.append('information:')
vbox=QVBoxLayout()
vbox.addWidget(self.btntest)
vbox.addWidget(self.pgb)
vbox.addWidget(self.teinfo)
self.setLayout(vbox)
self.resize(600,400)
#connect object's signal to slot
self.btntest.clicked.connect(self.loggingtest)
def loggingtest(self):
try:
itotal=300
if isinstance(self.appargs['totalprogress'],int):
self.appargs['totalprogress']=itotal
else:
with self.lock:
self.appargs['totalprogress'].value=itotal
#self.pgb.setMaximum(itotal)
for i in range(itotal):
info='message come from pyside application for logging test.[%05d]' %i
self.qlog.put(info)
QApplication.processEvents()
except Exception as ex:
myprint(str(Exception)+'\n'+str(ex))
def closeEvent(self,event):
self.qlog.put(None)
self.qtogui.put(None)
event.accept()
class sidethread(QThread):
def __init__(self, qtogui, parent = None):
QThread.__init__(self, parent)
self.qtogui=qtogui
self.parent=parent
def run(self):
while True:
t1=time.time()
bf=self.qtogui.get()
if bf is None:
break
t2=time.time()
#gui refresh can not too fast,otherwise gui application will crash.
if round((t2-t1),3)<=0.02:
time.sleep(0.02)
self.parent.teinfo.append(str(bf))
myprint('gui v1=%d' % self.parent.v1)
if isinstance(self.parent.appargs['totalprogress'],int):
myprint('gui thread::%d/%d' % (self.parent.appargs['crtprogress'],self.parent.appargs['totalprogress']))
self.parent.pgb.setMaximum(self.parent.appargs['totalprogress'])
self.parent.pgb.setValue(self.parent.appargs['crtprogress'])
else:
myprint('gui thread::%d/%d' % (self.parent.appargs['crtprogress'].value,self.parent.appargs['totalprogress'].value))
self.parent.pgb.setMaximum(self.parent.appargs['totalprogress'].value)
self.parent.pgb.setValue(self.parent.appargs['crtprogress'].value)
QApplication.processEvents()
def logfunc(appargs,qlog,qtogui,lock,v1):
if isinstance(appargs['totalprogress'],int):
print(appargs['totalprogress'],appargs['crtprogress'])
else:
print(appargs['totalprogress'].value,appargs['crtprogress'].value)
#log rotate works
logger = setuplogger(appargs)
while True:
bf=qlog.get()
if bf is None:
break
myprint('subprocess get() OK :: %s' % str(bf))
qtogui.put('subprocess process OK :: %s' % str(bf))
logger.info(bf)
v1+=1
myprint('subprocess v1=%d' % v1)
if isinstance(appargs['totalprogress'],int):
appargs['crtprogress']+=1
myprint('logfunc::%d/%d' % (appargs['crtprogress'],appargs['totalprogress']))
else:
with lock:
appargs['crtprogress'].value+=1
myprint('logfunc::%d/%d' % (appargs['crtprogress'].value,appargs['totalprogress'].value))
myprint('subprocess exit.')
def setuplogger(argsdict):
LOGGINGLEVEL = {
'notset': logging.NOTSET,
'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL,
}
logfn=argsdict['logfilename']
loglevel=LOGGINGLEVEL[argsdict['loglevel']]
# setup logger object
mylogger = logging.getLogger(argsdict['loggername'])
# set log level
mylogger.setLevel(loglevel)
# handler
handler = logging.handlers.RotatingFileHandler(logfn, maxBytes=argsdict['maxlogsize'], backupCount=argsdict['backupcount'])
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s :: %(message)s' )
handler.setFormatter(formatter)
# add handler to logger
mylogger.addHandler(handler)
# return logger object
return mylogger
def myprint(obj, end='\n'):
sys.stdout.write(str(obj) + end)
def startlog(appargs,qlog,qtogui,lock,v1):
plog=mp.Process(target=logfunc,args=(appargs,qlog,qtogui,lock,v1))
plog.start()
return plog
def startgui(appargs,qlog,qtogui,lock,v1):
app = QApplication(sys.argv)
window = mywindow(appargs,qlog,qtogui,lock,v1)
window.show()
app.exec_()
def main():
qlog=mp.Queue()
qtogui=mp.Queue()
lock=mp.Lock()
appargs={ 'loggername': 'app',
'logfilename': 'app.log',
'loglevel': 'debug',
'maxlogsize': 50000, #50kb
'backupcount': 3,
'totalprogress':0,
'crtprogress':0,
#'totalprogress':mp.Value('i'),
#'crtprogress':mp.Value('i'),
}
#appargs=mp.Manager().dict(appargs)
v1=0
if isinstance(appargs['totalprogress'],int):
appargs['totalprogress']=0
appargs['crtprogress']=0
else:
appargs['totalprogress'].value=0
appargs['crtprogress'].value=0
plog=startlog(appargs,qlog,qtogui,lock,v1)
startgui(appargs,qlog,qtogui,lock,v1)
if __name__ == '__main__':
main()