def __init__(self, timeOfDay): QtGui.QMainWindow.__init__(self) DebugObject.__init__(self, "TimeOfDayEditor") self.setupUi(self) self.sliders = [ self.slider00, self.slider03, self.slider06, self.slider09, self.slider12, self.slider15, self.slider18, self.slider21, ] for slider in self.sliders: slider.valueChanged.connect(self.sliderChanged) self.btnReset.clicked.connect(self.resetProperty) self.btnSmooth.clicked.connect(self.smoothProperty) self.btnSave.clicked.connect(self.save) self.btnGenerateClasses.clicked.connect(self.generateClasses) self.currentProperty = None self.widget = CurveWidget(self.curveBG) self.propertyList.selectionModel().selectionChanged.connect( self.selectedProperty) self.timeOfDay = timeOfDay self.fillList() self.savePath = None self.autoClassPath = None self.shaderIncludePath = None self.haveUnsavedChanges = False self.applicationMovedSlider = False
def finishingLayout(self): self.left_layout = QVBoxLayout() self.right_layout = QHBoxLayout() self.notice_window = NoticeWidget(self) self.curve_window = CurveWidget(self) self.left_layout.addWidget(self.curve_window) self.left_layout.addWidget(self.notice_window) self.curve_window.hide() self.widget_container.setLayout(self.left_layout) self.explain_window = Explain(self) self.configuration_window = Configuration(self) self.lcd_window = LCDGroup(self) self.right_layout.addWidget(self.explain_window) self.right_layout.addWidget(self.configuration_window) self.right_layout.addWidget(self.lcd_window) self.configuration_window.hide() self.lcd_window.hide() self.frame_container.setLayout(self.right_layout)
def setupUi(self): """ Setups the UI Components """ Ui_MainWindow.setupUi(self, self) self.settings_tree.setColumnWidth(0, 160) self.settings_tree.expandAll() self.edit_widget = CurveWidget(self) self.edit_widget.set_change_handler(self._on_curve_edited) self.prefab_edit_widget.addWidget(self.edit_widget) connect(self.time_slider, QtCore.SIGNAL("valueChanged(int)"), self._on_time_changed) connect(self.settings_tree, QtCore.SIGNAL("itemSelectionChanged()"), self._on_setting_selected)
class TimeOfDayWindow(QtGui.QMainWindow, TimeOfDayWindowUI, DebugObject): def __init__(self, timeOfDay): QtGui.QMainWindow.__init__(self) DebugObject.__init__(self, "TimeOfDayEditor") self.setupUi(self) self.sliders = [ self.slider00, self.slider03, self.slider06, self.slider09, self.slider12, self.slider15, self.slider18, self.slider21, ] for slider in self.sliders: slider.valueChanged.connect(self.sliderChanged) self.btnReset.clicked.connect(self.resetProperty) self.btnSmooth.clicked.connect(self.smoothProperty) self.btnSave.clicked.connect(self.save) self.btnGenerateClasses.clicked.connect(self.generateClasses) self.currentProperty = None self.widget = CurveWidget(self.curveBG) self.propertyList.selectionModel().selectionChanged.connect( self.selectedProperty) self.timeOfDay = timeOfDay self.fillList() self.savePath = None self.autoClassPath = None self.shaderIncludePath = None self.haveUnsavedChanges = False self.applicationMovedSlider = False def setSavePath(self, pth): self.savePath = pth def setAutoClassPath(self, pth): self.autoClassPath = pth def setShaderIncludePath(self, pth): self.shaderIncludePath = pth def generateClasses(self): if self.autoClassPath is None: self.error("No auto class path specified! Use setAutoClassPath") return if self.shaderIncludePath is None: self.error( "No shader include path specified! Use shaderIncludePath") return copyFiles = ["DayProperty.py", "TimeOfDay.py"] replaces = [("from DebugObject import DebugObject", "from ..DebugObject import DebugObject")] for f in copyFiles: with open(f, "r") as handle: content = handle.read() for find, replace in replaces: content = content.replace(find, replace) dest = join(self.autoClassPath, f) with open(dest, "w") as writeHandle: writeHandle.write(content) self.debug("Generated class files! Now generating shader files ..") self.timeOfDay.saveGlslInclude( join(self.shaderIncludePath, "TimeOfDay.include")) self.debug("Done!") def closeEvent(self, event): if not self.haveUnsavedChanges: event.accept() return quit_msg = "You still have unsaved changes. Are you sure you want to exit?" reply = QtGui.QMessageBox.question(self, 'Confirm', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: event.accept() else: event.ignore() def save(self): if self.savePath is None: self.error("Save path not set! Use setSavePath") return self.debug("Saving to", self.savePath) self.timeOfDay.save(self.savePath) self.haveUnsavedChanges = False def selectedProperty(self): selected = self.propertyList.selectedItems()[0] propertyId = str(selected.toolTip()) if len(propertyId) < 1: # nothing selected, or a header return prop = self.timeOfDay.getProperty(propertyId) self.loadProperty(prop) def fillList(self): self.propertyList.clear() first = None currentCat = None boldFont = self.font() boldFont.setBold(True) for propid in self.timeOfDay.getPropertyKeys(): prop = self.timeOfDay.getProperty(propid) if "." in propid: # I like cats cat = propid.split(".")[0] if cat != currentCat: # Get a new cat! currentCat = cat header = QtGui.QListWidgetItem() header.setText(self.timeOfDay.categories[cat]) header.setToolTip("") header.setFont(boldFont) self.propertyList.addItem(header) padding = "" if currentCat is None else " " item = QtGui.QListWidgetItem() item.setText(padding + prop.name) item.setToolTip(propid) self.propertyList.addItem(item) if first is None: first = item self.propertyList.setCurrentItem(first) def smoothProperty(self): if self.currentProperty is None: return # save old values oldValues = self.currentProperty.values oldValues = [oldValues[0]] + oldValues + [oldValues[1]] smoothFactor = 0.05 for i in xrange(8): val = oldValues[i + 1] valBefore = oldValues[i] valAfter = oldValues[i + 2] avgBeforeAfter = (valBefore + valAfter) / 2.0 newVal = avgBeforeAfter * smoothFactor + val * (1.0 - smoothFactor) self.currentProperty.setValue(i, newVal) asUniform = self.currentProperty.propType.asUniform(newVal) * 999.0 self.sliders[i].setValue(asUniform) self.haveUnsavedChanges = True def resetProperty(self): if self.currentProperty is not None: reply = QtGui.QMessageBox.question( self, 'Confirm', "Are you sure you want to reset the curve? You can't revert this!", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: defVal = self.currentProperty.propType.asUniform( self.currentProperty.defaultValue) * 999.0 for slider in self.sliders: slider.setValue(defVal) self.haveUnsavedChanges = True def sliderChanged(self): """ Gets called when the user moved a slider """ if self.currentProperty is None: return if not self.applicationMovedSlider: self.haveUnsavedChanges = True for index, slider in enumerate(self.sliders): rawVal = slider.value() / 999.0 adjVal = self.currentProperty.propType.fromUniform(rawVal) self.currentProperty.setValue(index, adjVal) self.currentProperty.recompute() self.curveBG.update() def loadProperty(self, prop): """ Gets called when another property got selected """ self.applicationMovedSlider = True self.labelDescription.setText("<strong>" + prop.name + "</strong><br>Description: " + prop.description) self.currentProperty = None self.lblMaxVal.setText(str(prop.propType.maxVal)) self.lblMinVal.setText(str(prop.propType.minVal)) self.lblMidVal.setText( str((prop.propType.maxVal + prop.propType.minVal) / 2)) for index, value in enumerate(prop.values): slider = self.sliders[index] val = prop.values[index] valScaled = prop.propType.asUniform(val) slider.setValue(valScaled * 999.0) self.currentProperty = prop self.widget.setProperty(self.currentProperty) self.sliderChanged() self.applicationMovedSlider = False
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.setFixedSize(960, 640) #不会出现对toolbar的隐藏 self.toolBar.toggleViewAction().setVisible(False) self.finishingLayout() self.setupValue() self.setupSignal() self.setupAction(config=False, start=False, reset=False, result=False, printer=False, back=False) self.setShow(1) self.setShow(3) def setupValue(self): self.__action = { "config": False, "start": False, "reset": False, "result": False, "print": False, "back": False, "exit": True } self.color_sheet = [ '#0000ff', '#ff0000', '#ffff00', '#00ff40', '#00ffff', '#0080c0', '#8080c0', '#ff00ff', '#800000', '#ff8000', '#008040', '#800080', 'black' ] self.lcd_group = [ self.lcd_window.press_lcd1, self.lcd_window.press_lcd2, self.lcd_window.press_lcd3, self.lcd_window.press_lcd4, self.lcd_window.press_lcd5, self.lcd_window.press_lcd6, self.lcd_window.digital_lcd1, self.lcd_window.digital_lcd2, self.lcd_window.digital_lcd3, self.lcd_window.digital_lcd4, self.lcd_window.speed_lcd, self.lcd_window.acceleration_lcd, self.lcd_window.shift_lcd ] self.chk_group = [ self.lcd_window.press_chk1, self.lcd_window.press_chk2, self.lcd_window.press_chk3, self.lcd_window.press_chk4, self.lcd_window.press_chk5, self.lcd_window.press_chk6, self.lcd_window.digital_chk1, self.lcd_window.digital_chk2, self.lcd_window.digital_chk3, self.lcd_window.digital_chk4, self.lcd_window.speed_chk, self.lcd_window.acceleration_chk, self.lcd_window.shift_chk ] self.tcp_link = TcpLink() #比例转换系数1,5,10 self.scaleRegion = (40, 10, 5, 2, 1) self.scaleFactor = [10, 10, 10, 10, 10, 10] self.lines_data = [None] * 14 self.report = {} self.report['PRESS'] = {} self.report['DIGITAL'] = {} self.ST_flag = False self.init_press = 0 def setupSignal(self): self.connect(self.action_exit, SIGNAL("triggered()"), self.actionExit) self.connect(self.action_config, SIGNAL("triggered()"), self.actionConfig) self.connect(self.action_start, SIGNAL("triggered()"), self.actionStart) self.connect(self.action_reset, SIGNAL("triggered()"), self.actionReset) self.connect(self.action_result, SIGNAL("triggered()"), self.actionResult) self.connect(self.action_print, SIGNAL("triggered()"), self.actionPrint) self.connect(self.action_back, SIGNAL("triggered()"), self.actionBack) self.connect(self.action_read_report, SIGNAL("triggered()"), self.actionReadReport) self.connect(self.notice_window.default_part.connect_button, SIGNAL("clicked()"), self.connectButtonClicked) self.connect(self.notice_window.default_part.read_file_button, SIGNAL("clicked()"), self.readFileButtonClicked) self.notice_window.current_press.ready_button.clicked.connect( self.readyButtonClicked) self.lcd_window.st_transfer.clicked.connect(self.setShiftTimeChange) #不能在外界直接操作GUI只能采用信号槽方式 self.tcp_link.signal_tips.connect(self.notice_window.setLblNotice) self.tcp_link.signal_noticeText.connect( self.notice_window.setNoticeText) self.tcp_link.signal_progressBar.connect(self.notice_window.setValue) self.tcp_link.signal_lcd.connect(self.setPress6LCDValue) self.tcp_link.signal_trigger.connect(self.actionStart) self.tcp_link.signal_result.connect(self.connectResult) self.tcp_link.signal_timeout.connect(self.dataTimeout) #右侧LCD 显示 self.curve_window.lcd_signal.connect(self.lcdDisplay) for i in self.chk_group: i.toggled.connect(self.lcdCheck) #数据收集阶段定时器,根据具体情况删减 self.draw_timer = QTimer(self) self.connect(self.draw_timer, SIGNAL("timeout()"), self.waitDraw) def finishingLayout(self): self.left_layout = QVBoxLayout() self.right_layout = QHBoxLayout() self.notice_window = NoticeWidget(self) self.curve_window = CurveWidget(self) self.left_layout.addWidget(self.curve_window) self.left_layout.addWidget(self.notice_window) self.curve_window.hide() self.widget_container.setLayout(self.left_layout) self.explain_window = Explain(self) self.configuration_window = Configuration(self) self.lcd_window = LCDGroup(self) self.right_layout.addWidget(self.explain_window) self.right_layout.addWidget(self.configuration_window) self.right_layout.addWidget(self.lcd_window) self.configuration_window.hide() self.lcd_window.hide() self.frame_container.setLayout(self.right_layout) def setShow(self, flag): """flag must a int""" if flag == 1: self.curve_window.hide() self.notice_window.show() self.notice_window.update() elif flag == 2: #print self.notice_window.geometry() self.notice_window.hide() self.curve_window.show() self.curve_window.update() #print self.curve_window.geometry() #print self.widget_container.geometry() elif flag == 3: self.explain_window.show() self.explain_window.update() self.configuration_window.hide() self.lcd_window.hide() elif flag == 4: self.explain_window.hide() self.configuration_window.show() self.configuration_window.update() self.lcd_window.hide() elif flag == 5: self.explain_window.hide() self.configuration_window.hide() self.lcd_window.show() self.lcd_window.update() def setupAction(self, **kwargs): """ kwargs = {"config":False,"start":False,"reset":False,"result":False,"print":False,"back":False, "exit":False} """ for i in kwargs.keys(): self.__action[i] = kwargs[i] self.action_config.setEnabled(self.__action["config"]) self.action_start.setEnabled(self.__action["start"]) self.action_reset.setEnabled(self.__action["reset"]) self.action_result.setEnabled(self.__action["result"]) self.action_print.setEnabled(self.__action["printer"]) self.action_back.setEnabled(self.__action["back"]) self.action_exit.setEnabled(self.__action["exit"]) def actionOrder(self, order): if order == 'init': self.setupAction(config=False, start=False, reset=False, result=False, printer=False, back=False) self.setShow(1) self.setShow(3) self.notice_window.setShow(1) self.notice_window.reset() self.notice_window.setLblNotice(u"点击[检测连接(Ctrl+Alt+L)]与下位机建立通信连接\ \n点击[读取文档(Ctrl+Alt+R)]读取已保存的数据文档") self.action_back.setText(u"首页/断开") elif order == 'config': self.setupAction(config=True, back=True) self.notice_window.setShow(2) self.setShow(1) self.setShow(4) self.notice_window.reset() self.notice_window.setLblNotice(u"点击[参数设置(F1)]对要进行测量的项目进行相关参数的设置\n" u"点击[断开连接(F7)]断开与下位机的通信") self.action_back.setText(u"断开连接") elif order == 'ready': self.setupAction(config=False, reset=True) self.setShow(1) self.setShow(4) self.notice_window.setShow(3) self.notice_window.setLblNotice(u"点击[准备测试(Ctrl+Alt+R)]进入测量\n" u"点击[复位(F3)]对配置信息进行重新配置") elif order == 'reset': self.setupAction(config=True, start=False, reset=False, result=False, printer=False) self.notice_window.setShow(2) self.setShow(1) self.setShow(4) self.notice_window.setLblNotice(u"点击[参数设置(F1)]对要进行测量的项目进行相关参数的设置\ \n点击[断开连接(F7)]断开与下位机的通信") self.notice_window.setNoticeText(u"对下次测试进行重新配置") elif order == 'trigger': self.notice_window.setShow(2) self.notice_window.setLblNotice(u'此时请勿进行其他操作,若要停止测试请点击[复位(F3)]') self.notice_window.setNoticeText(u'等待触发......') elif order == 'start': self.setupAction(start=True) self.notice_window.setShow(2) self.notice_window.setLblNotice( u'点击[开始(F2)]进行测量,若要重新测试请点击[复位(F3)]') self.notice_window.setNoticeText(u'手动触发方式') elif order == 'draw': self.setupAction(result=True, printer=True) elif order == 'tips': pass elif order == 'read': self.setShow(2) self.setShow(5) self.setupAction(back=True, result=True) self.action_back.setText(u"返回首页") def actionConfig(self): """根据配置对话框的内容获取相关参数""" config_dialog = ConfigDialog(self.tcp_link.getLineState) config_dialog.show() config_dialog.exec_() if config_dialog.getPassFlag(): self.group_digital = [(i[0].text(), i[1].isChecked()) for i in config_dialog.group_digital] self.group_press = [(i[0].text(), i[1].isChecked(), i[2].currentIndex()) for i in config_dialog.group_press] self.group_speed_trigger = [ config_dialog.speed_chk.isChecked(), config_dialog.trigger_combo.currentIndex() ] #测试项目,项目名称,测试人员,测试日期 self.groupNPTInfo = [ config_dialog.testProject.currentIndex(), config_dialog.projectName_edit.text(), config_dialog.person_edit.text(), config_dialog.time_edit.text() ] #测试时长 self.measure_time = config_dialog.measureTime #测试距离 self.measure_distance = config_dialog.measureDistance #set默认通道 self.default_press = config_dialog.default_press.currentIndex() #设置默认膛压通道 self.notice_window.setDefault(self.default_press) self.default_digital = config_dialog.default_digital.currentIndex() self.tcp_link.setPressChannel(self.default_press) self.tcp_link.setDigitalChannel(self.default_digital) self.tcp_link.setThresholdPress(config_dialog.threshold_press) self.tcp_link.setCalibration(config_dialog.calibration) self.tcp_link.setSpeedFactor(self.groupNPTInfo[0]) #需要绘制的坐标系 self.exist_axis = [] #需要调整宽度的坐标系 axis_num = [] for i, j in enumerate(self.group_press): if j[1]: self.exist_axis.append(i) axis_num.append((i, j[2])) self.scaleFactor[i] = self.scaleRegion[j[2]] #if j[0]: #self.report['PRESS'][i] = j[0] #else: #self.report['PRESS'][i] = u'通道%d' %(i + 1) else: self.scaleFactor[i] = 0 #self.report['PRESS'][i] = None for i, j in enumerate(self.group_digital): if j[1]: self.exist_axis.append(i + 6) #if j[0]: #self.report['DIGITAL'][i] = j[0] #else: #self.report['DIGITAL'][i] = '通道%d' %(i + 1) #else: #self.report['DIGITAL'][i] = None if self.group_speed_trigger[0]: self.exist_axis.extend([10, 11, 12]) if self.groupNPTInfo[0] == 0: axis_num.append((12, 1)) else: axis_num.append((12, 4)) self.tcp_link.setFactor(self.scaleFactor[:]) #print self.scaleFactor self.curve_window.produceAxis(self.exist_axis[:]) for i in (axis_num): self.curve_window.setTicker(i[0], i[1]) #开始根据配置获取需求值并显示当前压力 self.tcp_link.setTestFlag(False) self.tcp_link.setCurrentFlag(True) #报告关键值 #序列号 self.report['SERIAL'] = self.groupNPTInfo[1] _test_type = [u'鱼雷', u'诱饵'] self.report['TYPE'] = _test_type[self.groupNPTInfo[0]] _trigger = [u'自动触发', u'手动触发', u'外触发'] self.report['TRIGGER'] = _trigger[ self.group_speed_trigger[1]] #触发方式 self.report['PERSON'] = self.groupNPTInfo[2] #测试人员 self.report['DATE'] = self.groupNPTInfo[3] #测试日期 self.tcp_link.setCurrentFlag(True) self.actionOrder('ready') #print self.measure_distance self.configuration_window.readConfig() def actionStart(self): #print 'start' self.lcd_window.check([i[1] for i in self.group_press], [i[1] for i in self.group_digital], self.group_speed_trigger[0]) #print self.group_speed_trigger[0] self.tcp_link.setTriggerFlag(False) self.tcp_link.setClearFlag(False) self.setupAction(start=False) self.notice_window.reset() self.setShow(1) self.notice_window.setLblNotice(u'正在接收数据中,若想停止测量可直接点击[复位(F3)]终止本次测量') self.notice_window.setShow(2) self.notice_window.setNoticeText(u'系统正在测量,请等待......') self.notice_window.setValue(1) self.draw_count = 0 self.draw_timer.start(100) self.draw_timer.setInterval(100) def waitDraw(self): self.draw_count += 0.1 value = 100 / (self.measure_time) * self.draw_count self.notice_window.setValue(value) if self.draw_count >= self.measure_time: self.draw() def draw(self): #关闭时间 self.tcp_link.setClearFlag(True) self.draw_timer.stop() self.notice_window.setNoticeText(u'数据接收完毕,处理中......') data = self.tcp_link.getData() #若无数据直接返回 if not data: self.actionReset() return #print len(data), 'total data' speed_data = data[15::16] self.handle = HandleData(speed_data, self.measure_distance) length = len(speed_data) #开始运动点num num = self.handle.getStartTime() shift = self.handle.shift() if self.groupNPTInfo[0] == 0: speed_out = self.handle.getOutTime(shift) else: speed_out = self.handle.getStopTime(shift, self.measure_distance) #所截取数据的长度 right_limit = speed_out + 100 if right_limit > length: right_limit = speed_out + 1 if self.group_speed_trigger[0]: x_data = [(i - num) * 5E-4 for i in range(length)] else: x_data = [i * 5E-4 for i in range(length)] self.lines_data[0] = x_data[:right_limit] #print self.exist_axis for i in range(10): y_data = data[i::16] self.lines_data[i + 1] = y_data[:right_limit] if i < 6: if i in self.exist_axis: #不同测试类型取值不同 if self.groupNPTInfo[0] == 0: _value = y_data[int(self.measure_time * 2000)] #_value = max(y_data) self.report['PRESS'][i + 1] = '%0.2f' % _value if i == self.default_press: self.report['PRESS'][ i + 1] = '%0.2f' % (_value - self.init_press) self.handle.setChamberPressure( self.lines_data[i + 1], self.init_press) else: # _value = y_data[speed_out] _value = y_data[int(self.measure_time * 2000)] self.report['PRESS'][i + 1] = '%0.2f' % _value self.curve_window.drawLine2D(self.exist_axis.index(i), self.lines_data[0], self.lines_data[i + 1], self.color_sheet[i]) else: self.report['PRESS'][i + 1] = '--' else: if i in self.exist_axis: begin = self.handle.bleedTime(y_data) #dead = length - begin #self.report['DIGITAL'][i - 5] = ('%0.2f' %(begin*5E-4), '%0.2f' %(dead*5E-4)) self.report['DIGITAL'][i - 5] = '%0.1f' % (begin * 5E-4) self.curve_window.drawLine2D(self.exist_axis.index(i), self.lines_data[0], self.lines_data[i + 1], self.color_sheet[i]) else: self.report['DIGITAL'][i - 5] = ('--') self.lines_data[11] = speed_data[:right_limit] #加速度 acceleration = self.handle.acceleration() self.lines_data[12] = acceleration[:right_limit] self.lines_data[13] = shift[:right_limit] if 10 in self.exist_axis: self.report['SPEED'] = '%0.1f' % speed_data[speed_out] self.curve_window.drawLine2D(self.exist_axis.index(10), self.lines_data[0], self.lines_data[11], self.color_sheet[10]) self.report['ACCELERATION'] = '%0.1f' % acceleration[speed_out] self.curve_window.drawLine2D(self.exist_axis.index(11), self.lines_data[0], self.lines_data[12], self.color_sheet[11]) self.curve_window.drawLine2D(self.exist_axis.index(12), self.lines_data[0], self.lines_data[13], self.color_sheet[12]) else: self.report['SPEED'] = '--' self.report['ACCELERATION'] = '--' #图像填充全屏 self.curve_window.setXFull(self.lines_data[0][0], self.lines_data[0][-1]) #延迟时间 self.report['DELAY'] = '%0.1f' % (num * 5E-4) #发射时间 self.report['SHOOT'] = '%0.1f' % (speed_out * 5E-4) #flag = self.report['DIGITAL'].get(self.default_digital + 1, ('--', '--')) if self.group_digital[self.default_digital][1]: begin, dead = self.handle.getStartClock( data[6 + self.default_digital::16]) #print begin, dead #泄放阀开启时间 self.report['OPEN'] = '%0.1f' % (begin * 5E-4) #泄放阀开启时机 self.report['BLEED'] = '%0.1f' % shift[dead] else: self.report['OPEN'] = '--' self.report['BLEED'] = '--' now_time = datetime.datetime.now() file_path = now_time.strftime("%Y%m%d%H%M%S") if self.groupNPTInfo[0] == 0: filename = u'鱼雷' + self.groupNPTInfo[1] + file_path else: filename = u'诱饵' + self.groupNPTInfo[1] + file_path #self.tempHTML(self.group_press, self.group_digital, './template/'+'image.png') self.tempPicture("./template/" + "image.png") self.saveReport('./report/' + filename + '.pdf') self.saveFile('./DigitalSheet/' + filename + '.csv') self.curve_window.updateDraw() self.curve_window._init_View() self.notice_window.setValue(100) self.setShow(2) self.setShow(5) self.actionOrder('draw') def tempPicture(self, filename): directory = os.path.dirname(filename) if not os.path.isdir(directory): os.makedirs(directory) self.curve_window.canvas.print_figure(filename, dpi=300) def saveReport(self, filename): directory = os.path.dirname(filename) if not os.path.isdir(directory): os.makedirs(directory) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(QPrinter.Landscape) printer.setPageSize(QPrinter.A4) printer.setOutputFileName(filename) if filename: self.print_(printer) def print_(self, printer): painter = QPainter(printer) pageRect = printer.pageRect() w = pageRect.width() * 0.85 h = pageRect.height() painter.drawPixmap(0, 0, w, h, './template/image.png') sansFont = QFont("Helvetica", 10) painter.setFont(sansFont) fm = QFontMetrics(sansFont) height = fm.height() + 10 vmargin = 40 x0 = w + 1 y = 25 width = fm.width(u"测试编号") + 25 x1 = x0 + width painter.drawText(x0, y, u"报告编号") painter.drawText(x1, y, self.report['SERIAL']) y += height painter.drawText(x0, y, u"测试类型") painter.drawText(x1, y, self.report['TYPE']) y += height painter.drawText(x0, y, u"触发方式") painter.drawText(x1, y, self.report['TRIGGER']) y += height painter.drawText(x0, y, u"测试人员") painter.drawText(x1, y, self.report['PERSON']) y += height painter.drawText(x0, y, u"测试日期") painter.drawText(x1, y, self.report['DATE']) y += vmargin width = fm.width(u"通道1") + 50 x1 = x0 + width space = 0 painter.drawText(x0 + 20, y, u"压力通道(Mpa)") for i, j in enumerate(self.group_press): if j[1]: y += height if j[0]: painter.drawText(x0, y, j[0]) else: painter.drawText(x0, y, '通道%d'.decode("utf-8") % (i + 1)) painter.drawText(x1, y, self.report['PRESS'][i + 1]) else: space += height y += (vmargin + space) width = fm.width(u"通道计量1") + 15 x1 = x0 + width #x2 = x1 + width painter.drawText(x0 + 20, y, u"数字量计时通道(s)") y += height painter.drawText(x0, y, u"通道") painter.drawText(x1, y, u"开启时间") #painter.drawText(x2, y, u"关闭") space = 0 for i, j in enumerate(self.group_digital): if j[1]: y += height if j[0]: painter.drawText(x0, y, j[0]) else: painter.drawText(x0, y, '通道%d'.decode("utf-8") % (i + 1)) painter.drawText(x1, y, self.report['DIGITAL'][i + 1][0]) #painter.drawText(x2, y, self.report['DIGITAL'][i + 1][1]) else: space += height y += (vmargin + space) width = fm.width(u"出管速度(m/s)") + 25 x1 = x0 + width painter.drawText(x0, y, u"加速度(g)") painter.drawText(x1, y, self.report['ACCELERATION']) y += height painter.drawText(x0, y, u"出管速度(m/s)") painter.drawText(x1, y, self.report['SPEED']) y += height painter.drawText(x0, y, u"延迟时间(s)") painter.drawText(x1, y, self.report['DELAY']) y += height painter.drawText(x0, y, u"发射时间(s)") painter.drawText(x1, y, self.report['SHOOT']) y += height painter.drawText(x0, y, u"发射深度(s)") painter.drawText(x1, y, self.report['DEEP']) width = fm.width(u"泄放装置泄放时间(s)") + 5 y += height painter.drawText(x0, y, u"泄放阀开启时机(m)") x1 = x0 + width painter.drawText(x1, y, self.report['BLEED']) y += height painter.drawText(x0, y, u"泄放阀开启时间(s)") x1 = x0 + width + 1 painter.drawText(x1, y, self.report['OPEN']) def saveFile(self, filename): directorys = os.path.dirname(filename) if not os.path.isdir(directorys): os.makedirs(directorys) if not os.path.isfile(filename): try: file = open(filename, 'w') except Exception, e: file.close() return press = '&'.join([self.report['PRESS'][i] for i in range(1, 7)]) digital = '&'.join( [self.report['DIGITAL'][i] for i in range(1, 5)]) bleed_value = '&'.join([self.report['OPEN'], self.report['BLEED']]) #20131216对保存的数据进行修改 datapool = [ 'startest', self.report['SERIAL'], self.report['TYPE'], self.report['TRIGGER'], self.report['PERSON'], self.report['DATE'], press, digital, self.report['ACCELERATION'], self.report['SPEED'], self.report['DELAY'], self.report['SHOOT'], bleed_value, self.report['DEEP'] ] saveString = self.setText(','.join(datapool)) #print saveString file.write(saveString) file.write('\n') datapool = [] datapool.append('0') for i in range(6): datapool.append('%d' % self.group_press[i][2]) for i in range(4): datapool.append('0') datapool.append('0') datapool.append('0') if self.groupNPTInfo[0] == 0: datapool.append('1') else: datapool.append('4') saveString = ','.join(['%s' % i for i in datapool]) file.write(saveString) file.write('\n') datapool = [] datapool.append(True) datapool.extend([chk[1] for chk in self.group_press]) datapool.extend([chk[1] for chk in self.group_digital]) datapool.extend([self.group_speed_trigger[0] for i in range(3)]) saveString = ','.join(['%s' % i for i in datapool]) file.write(saveString) file.write('\n') datapool = [] for i, j in enumerate(self.lines_data[0]): for k in range(14): datapool.append(self.lines_data[k][i]) saveString = ','.join(['%s' % v for v in datapool]) file.write(saveString) file.write('\n') datapool = [] file.close()
class TimeOfDayWindow(QtGui.QMainWindow, TimeOfDayWindowUI, DebugObject): def __init__(self, timeOfDay): QtGui.QMainWindow.__init__(self) DebugObject.__init__(self, "TimeOfDayEditor") self.setupUi(self) self.sliders = [ self.slider00, self.slider03, self.slider06, self.slider09, self.slider12, self.slider15, self.slider18, self.slider21, ] for slider in self.sliders: slider.valueChanged.connect(self.sliderChanged) self.btnReset.clicked.connect(self.resetProperty) self.btnSmooth.clicked.connect(self.smoothProperty) self.btnSave.clicked.connect(self.save) self.btnGenerateClasses.clicked.connect(self.generateClasses) self.currentProperty = None self.widget = CurveWidget(self.curveBG) self.propertyList.selectionModel().selectionChanged.connect( self.selectedProperty) self.timeOfDay = timeOfDay self.fillList() self.savePath = None self.autoClassPath = None self.shaderIncludePath = None self.haveUnsavedChanges = False self.applicationMovedSlider = False def setSavePath(self, pth): self.savePath = pth def setAutoClassPath(self, pth): self.autoClassPath = pth def setShaderIncludePath(self, pth): self.shaderIncludePath = pth def generateClasses(self): if self.autoClassPath is None: self.error("No auto class path specified! Use setAutoClassPath") return if self.shaderIncludePath is None: self.error("No shader include path specified! Use shaderIncludePath") return copyFiles = ["DayProperty.py", "TimeOfDay.py"] replaces = [ ("from DebugObject import DebugObject", "from ..DebugObject import DebugObject") ] for f in copyFiles: with open(f, "r") as handle: content = handle.read() for find, replace in replaces: content = content.replace(find, replace) dest = join(self.autoClassPath, f) with open(dest, "w") as writeHandle: writeHandle.write(content) self.debug("Generated class files! Now generating shader files ..") self.timeOfDay.saveGlslInclude(join(self.shaderIncludePath, "TimeOfDay.include")) self.debug("Done!") def closeEvent(self, event): if not self.haveUnsavedChanges: event.accept() return quit_msg = "You still have unsaved changes. Are you sure you want to exit?" reply = QtGui.QMessageBox.question(self, 'Confirm', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: event.accept() else: event.ignore() def save(self): if self.savePath is None: self.error("Save path not set! Use setSavePath") return self.debug("Saving to", self.savePath) self.timeOfDay.save(self.savePath) self.haveUnsavedChanges = False def selectedProperty(self): selected = self.propertyList.selectedItems()[0] propertyId = str(selected.toolTip()) if len(propertyId) < 1: # nothing selected, or a header return prop = self.timeOfDay.getProperty(propertyId) self.loadProperty(prop) def fillList(self): self.propertyList.clear() first = None currentCat = None boldFont = self.font() boldFont.setBold(True) for propid in self.timeOfDay.getPropertyKeys(): prop = self.timeOfDay.getProperty(propid) if "." in propid: # I like cats cat = propid.split(".")[0] if cat != currentCat: # Get a new cat! currentCat = cat header = QtGui.QListWidgetItem() header.setText(self.timeOfDay.categories[cat]) header.setToolTip("") header.setFont(boldFont) self.propertyList.addItem(header) padding = "" if currentCat is None else " " item = QtGui.QListWidgetItem() item.setText(padding + prop.name) item.setToolTip(propid) self.propertyList.addItem(item) if first is None: first = item self.propertyList.setCurrentItem(first) def smoothProperty(self): if self.currentProperty is None: return # save old values oldValues = self.currentProperty.values oldValues = [oldValues[0]] + oldValues + [oldValues[1]] smoothFactor = 0.05 for i in xrange(8): val = oldValues[i + 1] valBefore = oldValues[i] valAfter = oldValues[i + 2] avgBeforeAfter = (valBefore + valAfter) / 2.0 newVal = avgBeforeAfter * smoothFactor + val * (1.0 - smoothFactor) self.currentProperty.setValue(i, newVal) asUniform = self.currentProperty.propType.asUniform(newVal) * 999.0 self.sliders[i].setValue(asUniform) self.haveUnsavedChanges = True def resetProperty(self): if self.currentProperty is not None: reply = QtGui.QMessageBox.question(self, 'Confirm', "Are you sure you want to reset the curve? You can't revert this!", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: defVal = self.currentProperty.propType.asUniform( self.currentProperty.defaultValue) * 999.0 for slider in self.sliders: slider.setValue(defVal) self.haveUnsavedChanges = True def sliderChanged(self): """ Gets called when the user moved a slider """ if self.currentProperty is None: return if not self.applicationMovedSlider: self.haveUnsavedChanges = True for index, slider in enumerate(self.sliders): rawVal = slider.value() / 999.0 adjVal = self.currentProperty.propType.fromUniform(rawVal) self.currentProperty.setValue(index, adjVal) self.currentProperty.recompute() self.curveBG.update() def loadProperty(self, prop): """ Gets called when another property got selected """ self.applicationMovedSlider = True self.labelDescription.setText( "<strong>" + prop.name + "</strong><br>Description: " + prop.description) self.currentProperty = None self.lblMaxVal.setText(str(prop.propType.maxVal)) self.lblMinVal.setText(str(prop.propType.minVal)) self.lblMidVal.setText( str((prop.propType.maxVal + prop.propType.minVal) / 2)) for index, value in enumerate(prop.values): slider = self.sliders[index] val = prop.values[index] valScaled = prop.propType.asUniform(val) slider.setValue(valScaled * 999.0) self.currentProperty = prop self.widget.setProperty(self.currentProperty) self.sliderChanged() self.applicationMovedSlider = False
class DayTimeEditor(QtGui.QMainWindow, Ui_MainWindow): """ This is the main editor class which handles the user interface """ def __init__(self): # Init mounts self._mount_mgr = MountManager(None) self._mount_mgr.mount() QtGui.QMainWindow.__init__(self) self.setupUi() self._tree_widgets = [] self._cmd_queue = set() # Construct a new virtual interface since we don't run in the pipeline self._interface = VirtualPluginInterface() self._interface.set_base_dir("../../") self._interface.load_plugin_config() self._interface.load_plugins() # Construct a new daytime manager with that interface self._daytime = DayTimeInterface(self._interface) self._daytime.set_base_dir("../../") self._daytime.load() self._update_settings_list() self._selected_setting_handle = None self._selected_setting = None self._selected_plugin = None self._current_time = 0.5 self._on_time_changed(self.time_slider.value()) self.set_settings_visible(False) self._bg_thread = Thread(target=self.updateThread) self._bg_thread.start() def set_settings_visible(self, visibility): if not visibility: self.frame_current_setting.hide() self.lbl_select_setting.show() else: self.frame_current_setting.show() self.lbl_select_setting.hide() def closeEvent(self, event): event.accept() import os os._exit(1) def updateThread(self): """ Seperate update thread """ while True: if self._cmd_queue: cmd = self._cmd_queue.pop() if cmd == "settime": # TODO: Send time change over network local_time = self._current_time UDPListenerService.do_ping(UDPListenerService.DAYTIME_PORT, "settime " + str(local_time)) elif cmd == "write_settings": # Write settings self._daytime.write_configuration() UDPListenerService.do_ping(UDPListenerService.DAYTIME_PORT, "loadconf") else: print("Unkown cmd:", cmd) time.sleep(0.2) def setupUi(self): """ Setups the UI Components """ Ui_MainWindow.setupUi(self, self) self.settings_tree.setColumnWidth(0, 160) self.settings_tree.expandAll() self.edit_widget = CurveWidget(self) self.edit_widget.set_change_handler(self._on_curve_edited) self.prefab_edit_widget.addWidget(self.edit_widget) connect(self.time_slider, QtCore.SIGNAL("valueChanged(int)"), self._on_time_changed) connect(self.settings_tree, QtCore.SIGNAL("itemSelectionChanged()"), self._on_setting_selected) def _update_tree_widgets(self): """ Updates the tree widgets """ for setting_handle, widget in self._tree_widgets: value = setting_handle.get_value(self._current_time) formatted = setting_handle.format(value) widget.setText(1, formatted) if setting_handle.type == "COLOR": widget.setBackground(1, QtGui.QBrush(QtGui.QColor(*value))) def _on_curve_edited(self): """ Called when the curve got edited in the curve widget """ self._cmd_queue.add("write_settings") self._update_tree_widgets() def _on_setting_selected(self): """ Called when a setting got selected in the settings tree """ selected = self.settings_tree.selectedItems() if len(selected) != 1: self._selected_setting = None self._selected_plugin = None self._selected_setting_handle = None self.edit_widget.set_curves([]) self.set_settings_visible(False) else: selected = selected[0] self._selected_plugin = selected._plugin_id self._selected_setting = selected._setting_id self._selected_setting_handle = selected._setting_handle self.lbl_current_setting.setText(self._selected_setting_handle.label) self.lbl_setting_desc.setText(self._selected_setting_handle.description) self.edit_widget.set_curves(self._selected_setting_handle.curves) self.edit_widget.set_unit_processor(self._selected_setting_handle.format_nonlinear) self.set_settings_visible(True) self._update_tree_widgets() def _on_time_changed(self, val): """ Handler when the time slider got moved """ hour = val / (60 * 60 * 60) minute = (val / (60 * 60)) % 60 ftime = float(val) / (24 * 60 * 60 * 60) self.time_label.setText(str(hour).zfill(2) + ":" + str(minute).zfill(2)) self.edit_widget.set_current_time(ftime) self._current_time = ftime self._update_tree_widgets() self._cmd_queue.add("settime") def _update_settings_list(self): """ Updates the list of visible settings """ self.settings_tree.clear() self._tree_widgets = [] for plugin in self._interface.get_plugin_instances(): if not self._interface.is_plugin_enabled(plugin.get_id()): continue daytime_settings = plugin.get_config().get_daytime_settings() if not daytime_settings: # Skip plugins with empty settings continue plugin_head = QtGui.QTreeWidgetItem(self.settings_tree) plugin_head.setText(0, plugin.get_name()) plugin_head.setFlags(QtCore.Qt.ItemIsEnabled) # Display all settings for setting, setting_handle in iteritems(daytime_settings): setting_item = QtGui.QTreeWidgetItem(plugin_head) setting_item.setText(0, setting_handle.label) setting_item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) setting_item._setting_id = setting setting_item._setting_handle = setting_handle setting_item._plugin_id = plugin.get_id() setting_item.setToolTip(0, setting_handle.description) setting_item.setToolTip(1, setting_handle.description) self._tree_widgets.append((setting_handle, setting_item)) self.settings_tree.expandAll()