моята програма има главен прозорец и в този прозорец изпълнява нишка, за да прочете мощността от фотодетектор, след което изпраща сигнал, който се улавя от слот в главния прозорец, който актуализира графичния интерфейс на главния прозорец.
След това имам друга джаджа (да я наречем програмна джаджа), която изскача от главния прозорец, което е основно обикновен текст, в който потребителят може да вмъква команди, така че програмата да ги изпълни. Сега идва въпросът:
Когато просто отворя приспособлението за програмиране с „покажи“, главният прозорец продължава да актуализира фотодетектора. Въпреки това, когато започна да изпълнявам последователност от приспособлението за програмиране, главният прозорец замръзва и показанията на фотодетектора спират с него, докато изпълнява командите (предполагам, че продължава да чете, защото е в друга нишка, но спира да актуализира графичния интерфейс на основния прозорец).
Въпросът ми е: джаджата за програмиране вече е по подразбиране в друга нишка, тъй като главният прозорец продължава да работи, когато се отвори. И така, защо той (главният прозорец) замръзва, когато програмният модул е в цикъл?
Ето кода на темата:
class PDThread(QtCore.QThread):
valueupdate = QtCore.pyqtSignal(float)
state = 1
def __init__(self, state, port):
QtCore.QThread.__init__(self)
self.photodetector = PM100D()
self.port = port
def run(self):
while True:
try:
self.photodetector.connect(self.port)
break
except:
self.dialog = dialog_classes.DialogPort()
self.dialog.set_instrument('PM100D')
self.dialog.exec_()
ret = self.dialog.pm100d.itemText(self.dialog.pm100d.currentIndex())
if ret == QtGui.QDialog.Accepted:
self.port = str(ret)
else:
self.photodetector.__del__()
self.quit()
return
window.PDState = 1
window.startpd.setText('Stop PD')
while self.state == 1:
time.sleep(0.1)
value = self.photodetector.get_pow()
self.valueupdate.emit(value)
Ето функцията, която създава нишката и слота в главния прозорец:
def ActionConnect_PM100D(self):
if self.PDState == 0:
self.PD = PDThread(self.PDState, self.PDport)
self.PD.valueupdate.connect(self.PDHandler)
self.threads = []
self.threads.append(self.PD)
self.PD.start()
else:
self.PDState = 0
self.PD.state = 0
self.startpd.setText('Start PD')
def PDHandler(self, value):
ref = float(self.refpd.value())
self.outputpd.setText(str(value-ref))
Тук също в главния прозорец, функцията, която създава джаджата:
def ActionSetup(self):
self.program = dialog_classes.Programming(self.newport, self.output, self.outputpd)
self.program.show()
И накрая, кодът на джаджата:
class Programming(QtGui.QDialog, Ui_Programming_Dialog, gui.MyApp):
def __init__(self, ESP300, output, outputpd):
QtGui.QDialog.__init__(self)
self.setupUi(self)
self.setWindowTitle('Programming Setup')
self.openbuttom.clicked.connect(self.Open)
self.save.clicked.connect(self.Save)
self.execute.clicked.connect(self.Execute)
self.newport = ESP300
self.output = output
self.outputpd = outputpd
def Open(self):
self.fileName = QtGui.QFileDialog.getOpenFileName(self, 'OpenFile', '', '*.txt')
try:
text = open(self.fileName).read()
except:
None
else:
self.program.setPlainText(text)
def Save(self):
self.fileName = QtGui.QFileDialog.getSaveFileName(self, 'Save File', '', '*.txt')
try:
open(self.fileName, 'w').write(str(self.program.toPlainText()))
except:
None
def Execute(self):
text = str(self.program.toPlainText())
lines = text.split('\n')
for line in lines:
arg = []
List = line.split(',')
for word in List:
arg.append(word.strip())
if arg[0].lower() == 'move':
if arg[1].lower() == 'x':
self.newport.move_x(float(arg[2]))
elif arg[1].lower() == 'y':
self.newport.move_y(float(arg[2]))
elif arg[1].lower() == 'z':
self.newport.move_z(float(arg[2]))
elif arg[0].lower() == 'wait':
self.newport.wait()
elif arg[0].lower() == 'home':
self.newport.home()
while True:
try:
self.GetPosition()
except:
time.sleep(0.5)
else:
if self.newport.x == 0 and self.newport.y == 0 and self.newport.z == 0:
break
elif arg[0].lower() == 'power on':
self.newport.power_on(arg[1])
elif arg[0].lower() == 'power off':
self.newport.power_off(arg[1])
elif arg[0].lower() == 'pos':
self.newport.pos_x(arg[1])
self.newport.pos_y(arg[2])
self.newport.pos_z(arg[3])
while True:
try:
self.GetPosition()
except:
time.sleep(0.5)
else:
time.sleep(1)
break
elif arg[0].lower() == 'get pos':
self.GetPosition()
elif arg[0].lower() == 'get error':
self.GetError()
elif arg[0].lower() == 'get pow':
print(self.outputpd.toPlainText())
time.sleep(2)
def closeIt(self):
self.close()
Благодарим за подкрепата.
QWidget
, не може да бъде в нито една нишка, различна от основната нишка. Вашият код не е многонишков, той просто блокира потребителския интерфейс, когато сте в цикъл. UI кодът работи чрез изпълнение на цикъл на събития, който изпраща събития, когато сте заседнали в някакви слотове или манипулатори на събития, цикълът на събития не се изпълнява. Обърнете потока на контрол: вместо да чакате нещата в цикъл, използвайте таймер, който извиква кода ви от време на време, за да чете нещата или да реагира на нови данни, когато станат достъпни, ако използвате напр. aQSerialPort
. - person Kuba hasn't forgotten Monica   schedule 20.09.2016