class CustomMainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.isShiftPressed = False self.model = Model() self.generator = Generator() self.ui.showArea.setReadOnly(True) self.ui.sendButton.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q)) self.connect(self.ui.sendButton, QtCore.SIGNAL('clicked()'), self.onSendButtonClicked) self.connect(self.model, QtCore.SIGNAL('messageAdded(QString)'), self.onMessageAdded) def onSendButtonClicked(self): question = self.ui.inputArea.toPlainText() if question: message = Message(question, u"Станислав") self.ui.inputArea.clear() self.model.addMessage(message) answer = self.generator.getAnswer(question) self.model.addMessage(Message(answer, u"Катерина")) def onMessageAdded(self, message): self.ui.showArea.append(message + "\n")
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setWindowTitle("Demo8_4, 自定义界面组件") self.ui.slider.setRange(0, 100) self.ui.LabInfo.setMaximumHeight(20) self.ui.battery.powerLevelChanged.connect(self.do_battery_changed) self.ui.slider.setValue(60) ## ==============自定义功能函数======================== ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ def on_slider_valueChanged(self, value): self.ui.battery.setPowerLevel(value) ## =============自定义槽函数=============================== def do_battery_changed(self, power): powStr = "当前电量:%d %%" % power self.ui.LabInfo.setText(powStr)
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.__buildModelView() ## ==============自定义功能函数============ def __buildModelView(self): ##构造Model/View 系统 self.model = QFileSystemModel(self) self.model.setRootPath(QDir.currentPath()) self.ui.treeView.setModel(self.model) #设置数据模型 self.ui.listView.setModel(self.model) self.ui.tableView.setModel(self.model) self.ui.treeView.clicked.connect(self.ui.listView.setRootIndex) self.ui.treeView.clicked.connect(self.ui.tableView.setRootIndex) ## ==========由connectSlotsByName() 自动连接的槽函数================== def on_treeView_clicked(self, index): ##treeView单击 self.ui.chkBox_IsDir.setChecked(self.model.isDir(index)) #是否是目录 self.ui.LabPath.setText(self.model.filePath(index)) #目录名 self.ui.LabType.setText(self.model.type(index)) #节点类型 self.ui.LabFileName.setText(self.model.fileName(index)) #文件名 fileSize = self.model.size(index) / 1024 if (fileSize < 1024): self.ui.LabFileSize.setText("%d KB" % fileSize) else: self.ui.LabFileSize.setText("%.2f MB" % (fileSize / 1024.0))
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.splitter) pass ## ================自定义功能函数============================ def __setActionsForButton(self): ##为界面上的ToolButton按钮设置Actions pass def __createSelectionPopMenu(self): ##创建ToolButton的下拉菜单 pass ## =========connectSlotsByName() 自动连接的槽函数=========== @pyqtSlot() ##初始化列表 def on_actList_Ini_triggered(self): pass @pyqtSlot() ##插入一项 def on_actList_Insert_triggered(self): pass @pyqtSlot() ##添加一项 def on_actList_Append_triggered(self): pass @pyqtSlot() ##删除当前项 def on_actList_Delete_triggered(self): pass @pyqtSlot() ##清空列表 def on_actList_Clear_triggered(self): pass @pyqtSlot() def on_actSel_ALL_triggered(self): ##全选 pass @pyqtSlot() def on_actSel_None_triggered(self): ##全不选 pass @pyqtSlot() def on_actSel_Invs_triggered(self): ##反选 pass @pyqtSlot(bool) def on_chkBoxList_Editable_clicked(self, checked): ##改变可编辑状态 pass def on_listWidget_currentItemChanged(self, current, previous): ##当前项切换变化 pass def on_listWidget_customContextMenuRequested(self, pos): ##右键快捷菜单 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui=Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.tableView) pass ## ==============自定义功能函数============ def __getFieldNames(self): ##获取所有字段名称 pass def __openTable(self): ##打开数据表 pass ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() def on_actOpenDB_triggered(self): pass @pyqtSlot() ##保存修改 def on_actSubmit_triggered(self): pass @pyqtSlot() ##取消修改 def on_actRevert_triggered(self): pass @pyqtSlot() ##添加记录 def on_actRecAppend_triggered(self): pass @pyqtSlot() ##插入记录 def on_actRecInsert_triggered(self): pass @pyqtSlot() ##删除记录 def on_actRecDelete_triggered(self): pass @pyqtSlot() ##显示字段列表 def on_actFields_triggered(self): pass ## =============自定义槽函数=============================== def do_currentChanged(self,current,previous): ##更新actPost和actCancel 的状态 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.textEdit) pass ## ============自定义功能函数================================ def __buildUI(self): ##窗体上动态添加组件 pass ## ===========由connectSlotsByName() 自动连接的槽函数===================== @pyqtSlot(bool) ##设置粗体 def on_actFont_Bold_triggered(self, checked): pass @pyqtSlot(bool) ##设置斜体 def on_actFont_Italic_triggered(self, checked): pass @pyqtSlot(bool) ##设置下划线 def on_actFont_UnderLine_triggered(self, checked): pass def on_textEdit_copyAvailable(self, avi): ##文本框内容可copy pass def on_textEdit_selectionChanged(self): ##文本选择内容发生变化 pass def on_textEdit_customContextMenuRequested(self, pos): ##标准右键菜单 pass @pyqtSlot(bool) ##设置工具栏按钮样式 def on_actSys_ToggleText_triggered(self, checked): pass def on_actFile_New_triggered(self): ##新建文件,不实现具体功能 pass def on_actFile_Open_triggered(self): ##打开文件,不实现具体功能 pass def on_actFile_Save_triggered(self): ##保存文件,不实现具体功能 pass ## =============自定义槽函数=============================== @pyqtSlot(int) ##设置字体大小,关联 __spinFontSize def do_fontSize_Changed(self, fontSize): pass @pyqtSlot(str) ##选择字体名称,关联__comboFontName def do_fontName_Changed(self, fontName): pass
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.__ui = Ui_MainWindow() self.__ui.setupUi(self) self.__ui.pushButton.clicked.connect(self.click_agregar) def click_agregar(self): self.__ui.pushButton.setText("Guardado")
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 pass ## ==============自定义功能函数======================== def __getSampleTypeStr(self, sampleType): ##采样数据点类型的字符串表示 pass def __getByteOrderStr(self, endian): ##字节序的字符串表示 pass ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot(int) ##选择音频输入设备 def on_comboDevices_currentIndexChanged(self, index): pass @pyqtSlot() ##使用内建IODevice def on_radioSaveMode_Inner_clicked(self): pass @pyqtSlot() ##使用QFile对象(test.raw) def on_radioSaveMode_QFile_clicked(self): pass @pyqtSlot(int) ##调节录音音量 def on_sliderVolumn_valueChanged(self, value): pass @pyqtSlot() ##测试音频输入设备是否支持选择的设置 def on_actDeviceTest_triggered(self): pass @pyqtSlot() ##开始音频输入 def on_actStart_triggered(self): pass @pyqtSlot() ##停止音频输入 def on_actStop_triggered(self): pass ## =============自定义槽函数=============================== ##1. 使用QIODevice* start()返回的内置的IODevice, pull mode,利用readyRead()信号读出数据 def do_IO_readyRead(self): ##内建IODevice,读取缓冲区数据 pass def do_stateChanged(self, state): ##设备状态变化 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # 调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() # 创建UI对象 self.ui.setupUi(self) # 构造UI界面 # 初始化各参数 self.ui.lineEdit.setText('使用说明: 按顺序选择统计量') self.ui.spinBox.setValue(3) # 设置默认保留三位小数 self.ui.checkBox.setChecked(True) self.line_list = [self.ui.lineEdit_1, self.ui.lineEdit_2, self.ui.lineEdit_3, self.ui.lineEdit_4, self.ui.lineEdit_5, self.ui.lineEdit_6, self.ui.lineEdit_7, self.ui.lineEdit_8, self.ui.lineEdit_9, self.ui.lineEdit_10, self.ui.lineEdit_11, self.ui.lineEdit_12, self.ui.lineEdit_13, self.ui.lineEdit_14, self.ui.lineEdit_15] self.values = ['1', '', '', '3', '4', '', '2', '5', '6', '7', '8', '', '', '', ''] for widget, value in zip(self.line_list, self.values): widget.setText(value) # ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() def on_action_triggered(self): # 导入数据按钮 download_path = QFileDialog.getOpenFileName(None, "浏览", None, "Text Files (*.xlsx);;Text Files (*.xls)") try: self.df = pd.read_excel(download_path[0]) self.ui.lineEdit.setText("恭喜,数据读取成功!") except: self.ui.lineEdit.setText("数据读取失败,请重新导入数据!") if self.ui.checkBox.isChecked(): # 判断date是否勾选,如果勾选,删除第一列日期数据 self.df = self.df.drop(self.df.columns[0], axis=1) @pyqtSlot() def on_action_2_triggered(self): # 开始运行按钮 parameter = [] for widget in self.line_list: parameter.append(widget.text()) opt = deal_int(parameter) stat = description(opt, self.ui.spinBox.value()) stat.run(self.df) self.ui.lineEdit.setText(f'结果已保存在{os.getcwd()}\\output.xlsx!') @pyqtSlot() def on_action_3_triggered(self): # 清空按钮 for widget in self.line_list: widget.setText('') self.ui.lineEdit.setText('已清空全部顺序量!') @pyqtSlot() def on_action_4_triggered(self): # 初始化按钮 for widget, value in zip(self.line_list, self.values): widget.setText(value) self.ui.lineEdit.setText('使用说明: 按顺序选择统计量')
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.tableView) pass ## ==============自定义功能函数============ def __getFieldNames(self): ##获取所有字段名称 pass def __openTable(self): #查询数据 pass def __updateRecord(self, recNo): ##更新一条记录 pass ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() ##打开数据库 def on_actOpenDB_triggered(self): pass @pyqtSlot() ##插入记录 def on_actRecInsert_triggered(self): pass @pyqtSlot() ##删除记录 def on_actRecDelete_triggered(self): pass @pyqtSlot() ##编辑记录 def on_actRecEdit_triggered(self): pass ## @pyqtSlot() ##双击编辑记录 def on_tableView_doubleClicked(self, index): pass @pyqtSlot() ##遍历记录,涨工资 def on_actScan_triggered(self): pass @pyqtSlot() ##SQL语句测试 def on_actTestSQL_triggered(self): pass ## =============自定义槽函数=============================== def do_currentRowChanged(self, current, previous): ##行切换时触发 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui=Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.splitter) pass ## ==============自定义功能函数============ def __getFieldNames(self): ##获取所有字段名称 pass def __openTable(self): ##查询数据 pass def __refreshTableView(self): ##刷新tableView显示 pass ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() ##“打开数据库”按钮 def on_actOpenDB_triggered(self): pass @pyqtSlot() ##首记录 def on_actRecFirst_triggered(self): pass @pyqtSlot() ##前一记录 def on_actRecPrevious_triggered(self): pass @pyqtSlot() ##后一条记录 def on_actRecNext_triggered(self): pass @pyqtSlot() ##最后一条记录 def on_actRecLast_triggered(self): pass ## =============自定义槽函数=============================== def do_currentRowChanged(self, current, previous): ##记录移动时触发 pass
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() #Se llama a la ventana self.administrador = ListaParticula() self.ui = Ui_MainWindow() self.ui.setupUi(self) #Conexión del Slot self.ui.agregarFinal_pushButton.clicked.connect(self.click_agregar) self.ui.agregarInicio_pushButton.clicked.connect( self.click_agregarInicio) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) @Slot() def click_mostrar(self): #self.administrador.mostrar() self.ui.salida.clear() self.ui.salida.insertPlainText(str(self.administrador)) @Slot() #Definición de Slot def click_agregar(self): ID = self.ui.ID_lineEdit.text() origenX = self.ui.origenX_spinBox.value() origenY = self.ui.origenY_spinBox.value() destinoX = self.ui.destinoX_spinBox.value() destinoY = self.ui.destinoY_spinBox.value() velocidad = self.ui.velocidad_spinBox.value() red = self.ui.red_spinBox.value() green = self.ui.green_spinBox.value() blue = self.ui.blue_spinBox.value() particula = Particula(ID, origenX, origenY, destinoX, destinoY, velocidad, red, green, blue) self.administrador.agregar_final(particula) @Slot() #Definición de Slot def click_agregarInicio(self): ID = self.ui.ID_lineEdit.text() origenX = self.ui.origenX_spinBox.value() origenY = self.ui.origenY_spinBox.value() destinoX = self.ui.destinoX_spinBox.value() destinoY = self.ui.destinoY_spinBox.value() velocidad = self.ui.velocidad_spinBox.value() red = self.ui.red_spinBox.value() green = self.ui.green_spinBox.value() blue = self.ui.blue_spinBox.value() particula = Particula(ID, origenX, origenY, destinoX, destinoY, velocidad, red, green, blue) self.administrador.agregar_inicio(particula)
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setWindowTitle( "Demo12_3, QScatterSeries、QSplineSeries、自定义QChartView") pass ## ==============自定义功能函数======================== def __buildStatusBar(self): pass def __createChart(self): ##创建图表 pass def __prepareData(self): ##为序列设置数据 pass ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() ##放大 def on_actZoomIn_triggered(self): pass @pyqtSlot() ##缩小 def on_actZoomOut_triggered(self): pass @pyqtSlot() ##复位原始大小 def on_actZoomReset_triggered(self): pass ## =============自定义槽函数=============================== def do_LegendMarkerClicked(self): ##点击图例小方块 pass def do_chartView_mouseMove(self, point): ##鼠标移动 pass def do_series_hovered(self, point, state): ##序列的hovered信号 pass def do_series_clicked(self, point): ##序列的click信号 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 pass ## ==============自定义功能函数======================== def __iniCamera(self): ##创建 QCamera对象 pass def __iniImageCapture(self): ##创建 QCameraImageCapture对象 pass ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot(bool) ##设置保存方式 def on_chkBoxSaveToFile_clicked(self, checked): pass @pyqtSlot() ##拍照 def on_actCapture_triggered(self): pass @pyqtSlot() ##打开摄像头 def on_actStartCamera_triggered(self): pass @pyqtSlot() ##关闭摄像头 def on_actStopCamera_triggered(self): pass ## =============自定义槽函数=============================== def do_cameraStateChanged(self, state): ##摄像头状态变化 pass def do_imageReady(self, ready): ##是否可以拍照了 pass def do_imageCaptured(self, imageID, preview): ##图片被抓取到内存 pass def do_imageSaved(self, imageID, fileName): ##图片被保存 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.textEdit) ## ==============自定义功能函数======================== def __openByIODevice(self, fileName): ##用QFile打开文件 pass def __saveByIODevice(self, fileName): ##用QFile保存文件 pass def __openByStream(self, fileName): ##用QTextStream打开文件 pass def __saveByStream(self, fileName): ##用 QTextStream 保存文件 pass ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() ##用QFile 打开文件 def on_actQFile_Open_triggered(self): pass @pyqtSlot() ##用QFile 另存文件 def on_actQFile_Save_triggered(self): pass @pyqtSlot() ##用QTextStream 打开文件 def on_actStream_Open_triggered(self): pass @pyqtSlot() ##用QTextStream 另存文件 def on_actStream_Save_triggered(self): pass @pyqtSlot() ##用 python 的file()打开文件 def on_actPY_Open_triggered(self): pass @pyqtSlot() ##用 python的file() 保存文件 def on_actPY_Save_triggered(self): pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 pass ## ==============自定义功能函数============ def __buildModelView(self): ##构造Model/View 系统 pass ## ==========由connectSlotsByName() 自动连接的槽函数================== def on_treeView_clicked(self, index): ##treeView单击 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.tabWidget) pass ## ==============自定义功能函数============ ## =============event事件处理函数============ def paintEvent(self, event): pass super().paintEvent(event) ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() ## "嵌入式Widget" def on_actWidgetInsite_triggered(self): pass @pyqtSlot() ##独立Widget窗口 def on_actWidget_triggered(self): pass @pyqtSlot() ##"嵌入式MainWindow" def on_actWindowInsite_triggered(self): pass @pyqtSlot() ##"独立MainWindow窗口" def on_actWindow_triggered(self): pass def on_tabWidget_currentChanged(self, index): ##tabWidget当前页面变化 pass def on_tabWidget_tabCloseRequested(self, index): ##分页关闭时关闭窗体 pass ## =============自定义槽函数=============================== @pyqtSlot(str) def do_docFileChanged(self, shotFilename): ##显示文件名 pass
class QmyMainWindow(QMainWindow): cellIndexChanged = pyqtSignal(int, int) def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.tableView) pass def __del__(self): pass ## ==============自定义功能函数============ ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() ##设置行数列数对话框 def on_actTab_SetSize_triggered(self): pass @pyqtSlot() ##设置表头标题 def on_actTab_SetHeader_triggered(self): pass @pyqtSlot() ##"定位单元格" def on_actTab_Locate_triggered(self): pass ## =============自定义槽函数=============================== def do_currentChanged(self, current, previous): pass def do_setActLocateEnable(self, enable): pass def do_setACellText(self, row, column, text): pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 pass ## ==============自定义功能函数============ def __setRecordParams(self): ##设置音频输入参数 pass ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() ##"录音输出文件"按钮 def on_btnGetFile_clicked(self): pass @pyqtSlot() ##开始录音 def on_actRecord_triggered(self): pass @pyqtSlot() ##暂停 def on_actPause_triggered(self): pass @pyqtSlot() ##停止 def on_actStop_triggered(self): pass ## =============自定义槽函数=============================== def do_stateChanged(self, state): ##状态变化 pass def do_durationChanged(self, duration): ##持续时间长度变化 pass def do_processBuffer(self, buffer): ##解析缓冲区数据 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setWindowTitle("Demo8_4, 自定义界面组件") pass ## ==============自定义功能函数======================== ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ def on_slider_valueChanged(self, value): pass ## =============自定义槽函数=============================== def do_battery_changed(self, power): pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建Ui对象 self.ui.setupUi(self) #构造UI ##==========自定义功能函数========== def run_proxy(self): Verification().run_proxy() def run_spider(self): Spiders_Jap.Get_Jap().run_japsite() Spiders_Eur.Get_Eur().run_eursite() Spiders_Chi.Get_Chi().run_chisite() ##==========事件处理函数=========== def on_refresh_Button_clicked(self): self.run_proxy() def on_Init_Button_clicked(self): self.run_spider()
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建Ui对象 self.ui.setupUi(self) #构造UI self.LabPath = QLabel(self) self.ui.statusBar.addWidget(self.LabPath) self.__buildModelView() ##==========自定义功能函数========== def __buildModelView(self): self.model = QFileSystemModel(self) #定义数据模型 self.model.setRootPath(QDir.currentPath()) #获取当前路径,并设置为model的根目录 self.ui.treeView.setModel(self.model) #将self.model设置为自己的数据模型 self.ui.listView.setModel(self.model) self.ui.tableView.setModel(self.model) #将treeView的cilcked信号与listView与tableView的槽函数setRootIndex相关联 self.ui.treeView.clicked.connect(self.ui.listView.setRootIndex) self.ui.treeView.clicked.connect(self.ui.tableView.setRootIndex) ##==========事件处理函数=========== ##==========由connectSlotsByName()自动关联的槽函数==== def on_treeView_clicked(self, index): #index是模型索引 print(index) self.ui.checkBox.setChecked(self.model.isDir(index)) self.LabPath.setText(self.model.filePath(index)) self.ui.LabType.setText(self.model.type(index)) self.ui.LabFileName.setText(self.model.fileName(index)) fileSize = self.model.size(index) / 1024 # print(fileSize) if fileSize < 1024: self.ui.LabFileSize.setText("%d KB" % fileSize) else: self.ui.LabFileSize.setText(".2f MB" % (fileSize / 1024.0))
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # 调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() # 创建UI对象 self.ui.setupUi(self) # 构造UI界面 # ========菜单栏open的激活函数================================ @pyqtSlot() def on_actFile_Open_triggered(self): print("user clicked “open” ") curPath = QDir.currentPath() # 获取系统当前目录 title = "Open a file" # 对话框标题 filt = "edf file(*.edf);;All file(*.*)" # 文件过滤器eg.程序文件(*.h *.cpp *.py);;文本文件(*.txt);;所有文件(*.*) fileName, flt = QFileDialog.getOpenFileName(self, title, curPath, filt) if (fileName == ""): # 如果没有选择任何文件 return else: print(fileName) if "edf" in flt: self.ui.statusBar.showMessage(fileName) EEGLAB = QEEGLAB(self) EEGLAB.setAttribute(Qt.WA_DeleteOnClose) EEGLAB.setWindowFlag(Qt.Window, True) EEGLAB.show()
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.ui.toolBox.setCurrentIndex(0) self.fileWatcher = QFileSystemWatcher() self.fileWatcher.directoryChanged.connect(self.do_directoryChanged) self.fileWatcher.fileChanged.connect(self.do_fileChanged) ## ==============自定义功能函数======================== def __showBtnInfo(self, btn): ##显示按钮的text()和toolTip() self.ui.textEdit.appendPlainText("====" + btn.text()) self.ui.textEdit.appendPlainText(btn.toolTip() + "\n") ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() ##"选择文件"按钮 def on_btnOpenFile_clicked(self): curDir = QDir.currentPath() #获取当前路径 aFile, filt = QFileDialog.getOpenFileName(self, "打开文件", curDir, "所有文件(*.*)") self.ui.editFile.setText(aFile) @pyqtSlot() ##"选择目录"按钮 def on_btnOpenDir_clicked(self): curDir = QDir.currentPath() aDir = QFileDialog.getExistingDirectory(self, "选择一个目录", curDir, QFileDialog.ShowDirsOnly) self.ui.editDir.setText(aDir) @pyqtSlot() ##"清空"按钮 def on_btnClear_clicked(self): self.ui.textEdit.clear() ## =========QFile类 的静态函数=========== @pyqtSlot() ##类函数copy() def on_btnFile_copy_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text().strip() #源文件 if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return fileInfo = QFileInfo(sous) newFile = fileInfo.path() + "/" + fileInfo.baseName( ) + "--副本." + fileInfo.suffix() if QFile.copy(sous, newFile): self.ui.textEdit.appendPlainText("源文件:" + sous) self.ui.textEdit.appendPlainText("复制为文件:" + newFile + "\n") else: self.ui.textEdit.appendPlainText("复制文件失败") @pyqtSlot() ##类函数exists() def on_btnFile_exists_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text().strip() #源文件 if QFile.exists(sous): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") @pyqtSlot() ##类函数remove() def on_btnFile_remove_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text().strip() #源文件 if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return ret = QMessageBox.question(self, "确认删除", "确定要删除这个文件吗\n\n" + sous) if (ret != QMessageBox.Yes): return if QFile.remove(sous): self.ui.textEdit.appendPlainText("成功删除文件:" + sous + "\n") else: self.ui.textEdit.appendPlainText("删除文件失败:" + sous + "\n") @pyqtSlot() ##类函数rename() def on_btnFile_rename_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text().strip() #源文件 if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return fileInfo = QFileInfo(sous) newFile = fileInfo.path() + "/" + fileInfo.baseName( ) + ".XZY" #更改文件后缀为".XYZ" if QFile.rename(sous, newFile): self.ui.textEdit.appendPlainText("源文件:" + sous) self.ui.textEdit.appendPlainText("重命名为:" + newFile + "\n") else: self.ui.textEdit.appendPlainText("重命名文件失败\n") ## =========QFileInfo类=========== @pyqtSlot() ##absoluteFilePath() def on_btnInfo_absFilePath_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.absoluteFilePath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##absolutePath() def on_btnInfo_absPath_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.absolutePath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##fileName() def on_btnInfo_fileName_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.fileName() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##filePath() def on_btnInfo_filePath_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.filePath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##size() def on_btnInfo_size_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) btCount = fileInfo.size() #字节数 text = "%d Bytes" % btCount self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##path() def on_btnInfo_path_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.path() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##baseName() def on_btnInfo_baseName_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.baseName() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##completeBaseName() def on_btnInfo_baseName2_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.completeBaseName() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##suffix() def on_btnInfo_suffix_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.suffix() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##completeSuffix() def on_btnInfo_suffix2_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) text = fileInfo.completeSuffix() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##isDir() def on_btnInfo_isDir_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editDir.text()) if fileInfo.isDir(): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") @pyqtSlot() ##isFile() def on_btnInfo_isFile_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) if fileInfo.isFile(): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") @pyqtSlot() ##isExecutable() def on_btnInfo_isExec_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) if fileInfo.isExecutable(): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") @pyqtSlot() ##birthTime() ,替代了过时的created()函数 def on_btnInfo_birthTime_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) dt = fileInfo.birthTime() # QDateTime text = dt.toString("yyyy-MM-dd hh:mm:ss") self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##lastModified() def on_btnInfo_lastModified_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) dt = fileInfo.lastModified() # QDateTime text = dt.toString("yyyy-MM-dd hh:mm:ss") self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##lastRead() def on_btnInfo_lastRead_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) dt = fileInfo.lastRead() # QDateTime text = dt.toString("yyyy-MM-dd hh:mm:ss") self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##类函数exists() def on_btnInfo_exists_clicked(self): self.__showBtnInfo(self.sender()) if QFileInfo.exists(self.ui.editFile.text()): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") @pyqtSlot() ##接口函数exists() def on_btnInfo_exists2_clicked(self): self.__showBtnInfo(self.sender()) fileInfo = QFileInfo(self.ui.editFile.text()) if fileInfo.exists(): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") ## ==================QDir类======================== @pyqtSlot() ##tempPath() def on_btnDir_tempPath_clicked(self): self.__showBtnInfo(self.sender()) text = QDir.tempPath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##rootPath() def on_btnDir_rootPath_clicked(self): self.__showBtnInfo(self.sender()) text = QDir.rootPath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##homePath() def on_btnDir_homePath_clicked(self): self.__showBtnInfo(self.sender()) text = QDir.homePath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##drives() def on_btnDir_drives_clicked(self): self.__showBtnInfo(self.sender()) strList = QDir.drives() #QFileInfoList for line in strList: #line 是QFileInfo类型 self.ui.textEdit.appendPlainText(line.path()) self.ui.textEdit.appendPlainText("") @pyqtSlot() ##currentPath() def on_btnDir_curPath_clicked(self): self.__showBtnInfo(self.sender()) text = QDir.currentPath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##setCurrent() def on_btnDir_setCurPath_clicked(self): self.__showBtnInfo(self.sender()) curDir = QDir.currentPath() text = QFileDialog.getExistingDirectory(self, "选择一个目录", curDir, QFileDialog.ShowDirsOnly) QDir.setCurrent(text) self.ui.textEdit.appendPlainText("选择了一个目录作为当前目录:\n" + text + "\n") @pyqtSlot() ##mkdir() def on_btnDir_mkdir_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text().strip() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return subDir = "subdir1" dirObj = QDir(sous) if dirObj.mkdir(subDir): self.ui.textEdit.appendPlainText("新建一个子目录: " + subDir + "\n") else: self.ui.textEdit.appendPlainText("创建目录失败\n") @pyqtSlot() ##rmdir() def on_btnDir_rmdir_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text().strip() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return dirObj = QDir(sous) if dirObj.rmdir(sous): self.ui.textEdit.appendPlainText("成功删除所选目录\n" + sous + "\n") else: self.ui.textEdit.appendPlainText("删除目录失败,目录下必须为空\n") @pyqtSlot() ##remove() def on_btnDir_remove_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text().strip() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return parDir = self.ui.editDir.text().strip() if parDir == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return dirObj = QDir(parDir) if dirObj.remove(sous): self.ui.textEdit.appendPlainText("成功删除文件:\n" + sous + "\n") else: self.ui.textEdit.appendPlainText("删除文件失败\n") @pyqtSlot() ##rename() def on_btnDir_rename_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return parDir = self.ui.editDir.text().strip() if parDir == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return dirObj = QDir(parDir) fileInfo = QFileInfo(sous) newFile = fileInfo.path() + "/" + fileInfo.baseName() + ".XYZ" if dirObj.rename(sous, newFile): self.ui.textEdit.appendPlainText("源文件:" + sous) self.ui.textEdit.appendPlainText("重命名为:" + newFile + "\n") else: self.ui.textEdit.appendPlainText("重命名文件失败\n") @pyqtSlot() ##setPath(),改换QDir所指的目录 def on_btnDir_setPath_clicked(self): self.__showBtnInfo(self.sender()) curDir = QDir.currentPath() lastDir = QDir(curDir) self.ui.textEdit.appendPlainText("选择目录之前,QDir所指目录是:" + lastDir.absolutePath()) aDir = QFileDialog.getExistingDirectory(self, "选择一个目录", curDir, QFileDialog.ShowDirsOnly) if aDir == "": return lastDir.setPath(aDir) self.ui.textEdit.appendPlainText("\n选择目录之后,QDir所指目录是:" + lastDir.absolutePath() + "\n") @pyqtSlot() ##removeRecursively() def on_btnDir_removeALL_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text().strip() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return dirObj = QDir(sous) ret = QMessageBox.question(self, "确认删除", "确认删除目录下的所有文件及目录吗?\n" + sous) if ret != QMessageBox.Yes: return if dirObj.removeRecursively(): self.ui.textEdit.appendPlainText("删除目录及文件成功\n") else: self.ui.textEdit.appendPlainText("删除目录及文件失败\n") @pyqtSlot() ##absoluteFilePath() def on_btnDir_absFilePath_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return parDir = QDir.currentPath() dirObj = QDir(parDir) text = dirObj.absoluteFilePath(sous) self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##absolutePath() def on_btnDir_absPath_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return dirObj = QDir(sous) text = dirObj.absolutePath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##canonicalPath() def on_btnDir_canonPath_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个目录") return dirObj = QDir(sous) text = dirObj.canonicalPath() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##filePath() def on_btnDir_filePath_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editFile.text() if sous == "": self.ui.textEdit.appendPlainText("请先选择一个文件") return parDir = QDir.currentPath() dirObj = QDir(parDir) text = dirObj.filePath(sous) self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##exists() def on_btnDir_exists_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text() ## if sous=="": ## self.ui.textEdit.appendPlainText("请先选择一个目录") ## return dirObj = QDir(sous) #若sous为空,则使用其当前目录 self.ui.textEdit.appendPlainText(dirObj.absolutePath() + "\n") if dirObj.exists(): self.ui.textEdit.appendPlainText("True \n") else: self.ui.textEdit.appendPlainText("False \n") @pyqtSlot() ##dirName() def on_btnDir_dirName_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text() ## if sous=="": ## self.ui.textEdit.appendPlainText("请先选择一个目录") ## return dirObj = QDir(sous) #若sous为空,则使用其当前目录 text = dirObj.dirName() self.ui.textEdit.appendPlainText(text + "\n") @pyqtSlot() ##entryList()dirs def on_btnDir_listDir_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text() dirObj = QDir(sous) #若sous为空,则使用其当前目录 strList = dirObj.entryList(QDir.Dirs | QDir.NoDotAndDotDot) self.ui.textEdit.appendPlainText("所选目录下的所有目录:") for line in strList: self.ui.textEdit.appendPlainText(line) self.ui.textEdit.appendPlainText("\n") @pyqtSlot() ##entryList()files def on_btnDir_listFile_clicked(self): self.__showBtnInfo(self.sender()) sous = self.ui.editDir.text() dirObj = QDir(sous) #若sous为空,则使用其当前目录 strList = dirObj.entryList(QDir.Files) self.ui.textEdit.appendPlainText("所选目录下的所有文件:") for line in strList: self.ui.textEdit.appendPlainText(line) self.ui.textEdit.appendPlainText("\n") ## ==========QFileSystemWatcher类=================== @pyqtSlot() ##addPath()添加监听目录 def on_btnWatch_addDir_clicked(self): self.__showBtnInfo(self.sender()) curDir = QDir.currentPath() aDir = QFileDialog.getExistingDirectory(self, "选择一个需要监听的目录", curDir, QFileDialog.ShowDirsOnly) self.fileWatcher.addPath(aDir) #添加监听目录 self.ui.textEdit.appendPlainText("添加的监听目录:") self.ui.textEdit.appendPlainText(aDir + "\n") @pyqtSlot() ##addPaths()添加监听文件 def on_btnWatch_addFiles_clicked(self): self.__showBtnInfo(self.sender()) curDir = QDir.currentPath() fileList, flt = QFileDialog.getOpenFileNames(self, "选择需要监听的文件", curDir, "所有文件 (*.*)") self.fileWatcher.addPaths(fileList) #添加监听文件列表 self.ui.textEdit.appendPlainText("添加的监听文件:") for lineStr in fileList: self.ui.textEdit.appendPlainText(lineStr) self.ui.textEdit.appendPlainText("") @pyqtSlot() ##removePaths()移除所有监听的文件和目录 def on_btnWatch_remove_clicked(self): self.__showBtnInfo(self.sender()) self.ui.textEdit.appendPlainText("移除所有监听的目录和文件\n") dirList = self.fileWatcher.directories() self.fileWatcher.removePaths(dirList) fileList = self.fileWatcher.files() self.fileWatcher.removePaths(fileList) @pyqtSlot() ##显示监听目录,directories() def on_btnWatch_dirs_clicked(self): self.__showBtnInfo(self.sender()) strList = self.fileWatcher.directories() self.ui.textEdit.appendPlainText("正在监听的目录:") for line in strList: self.ui.textEdit.appendPlainText(line) self.ui.textEdit.appendPlainText("\n") @pyqtSlot() ##显示监听文件,files() def on_btnWatch_files_clicked(self): self.__showBtnInfo(self.sender()) strList = self.fileWatcher.files() self.ui.textEdit.appendPlainText("正在监听的文件:") for line in strList: self.ui.textEdit.appendPlainText(line) self.ui.textEdit.appendPlainText("\n") ## =============自定义槽函数=============================== def do_directoryChanged(self, path): ##目录发生变化 self.ui.textEdit.appendPlainText(path) self.ui.textEdit.appendPlainText("目录发生了变化\n") def do_fileChanged(self, path): ##文件发生变化 self.ui.textEdit.appendPlainText(path) self.ui.textEdit.appendPlainText("文件发生了变化\n")
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 pass ## ==============自定义功能函数============ ## ===============event 处理函数========== def closeEvent(self, event): ##窗体关闭时 ## 窗口关闭时不能自动停止播放,需手动停止 pass ## ==========由connectSlotsByName() 自动连接的槽函数================== # 播放列表管理 @pyqtSlot() ##添加文件 def on_btnAdd_clicked(self): pass @pyqtSlot() ##移除一个文件 def on_btnRemove_clicked(self): pass @pyqtSlot() ##清空播放列表 def on_btnClear_clicked(self): pass ## @pyqtSlot() ##双击时切换播放文件 def on_listWidget_doubleClicked(self, index): pass ## 播放控制 @pyqtSlot() ##播放 def on_btnPlay_clicked(self): pass @pyqtSlot() ##暂停 def on_btnPause_clicked(self): pass @pyqtSlot() ##停止 def on_btnStop_clicked(self): pass @pyqtSlot() ##上一曲目 def on_btnPrevious_clicked(self): pass @pyqtSlot() ##下一曲目 def on_btnNext_clicked(self): pass @pyqtSlot() ##静音控制 def on_btnSound_clicked(self): pass @pyqtSlot(int) ##调节音量 def on_sliderVolumn_valueChanged(self, value): pass @pyqtSlot(int) ##文件进度调控 def on_sliderPosition_valueChanged(self, value): pass ## =============自定义槽函数=============================== def do_stateChanged(self, state): ##播放器状态变化 pass def do_positionChanged(self, position): ##当前文件播放位置变化,更新进度显示 pass def do_durationChanged(self, duration): ##文件时长变化 pass def do_currentChanged(self, position): ##playlist当前曲目变化 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui=Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setCentralWidget(self.ui.mdiArea) #填充满工作区 pass ## ==============事件处理函数=================== def closeEvent(self,event): ##关闭窗口事件 pass ## ==============自定义功能函数============ def __enableEditActions(self,enabled): pass ## ==========由connectSlotsByName() 自动连接的槽函数================== @pyqtSlot() ##“新建文档” def on_actDoc_New_triggered(self): pass @pyqtSlot() ##“打开文档” def on_actDoc_Open_triggered(self): pass @pyqtSlot() ##“关闭全部” def on_actDoc_CloseALL_triggered(self): pass @pyqtSlot(bool) ##“MDI模式” def on_actMDI_Mode_triggered(self,checked): pass @pyqtSlot() ##“级联展开” def on_actMDI_Cascade_triggered(self): pass @pyqtSlot() ##“平铺展开” def on_actMDI_Tile_triggered(self): pass @pyqtSlot() ##Cut 操作 def on_actEdit_Cut_triggered(self): pass @pyqtSlot() ##Copy 操作 def on_actEdit_Copy_triggered(self): pass @pyqtSlot() ##Paste 操作 def on_actEdit_Paste_triggered(self): pass @pyqtSlot() ##“字体设置” def on_actEdit_Font_triggered(self): pass ## @pyqtSlot(type) ##子窗口切换 def on_mdiArea_subWindowActivated(self,arg1): pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setWindowTitle("Demo13_1, Q3DBars和QBar3DSeries绘制三维柱状图") pass ## ==============自定义功能函数======================== def __iniGraph3D(self): ##创建3D图表 pass ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ ##===工具栏actions== @pyqtSlot() ## "序列基本颜色" def on_actSeries_BaseColor_triggered(self): pass @pyqtSlot() ## "修改数值" def on_actBar_ChangeValue_triggered(self): pass @pyqtSlot() ## "添加行" def on_actData_Add_triggered(self): pass @pyqtSlot() ## "插入行" def on_actData_Insert_triggered(self): pass @pyqtSlot() ## "删除行" def on_actData_Delete_triggered(self): pass ##===三维旋转=== @pyqtSlot(int) ## "预设视角" def on_comboCamera_currentIndexChanged(self, index): pass @pyqtSlot(int) ## "水平旋转" def on_sliderH_valueChanged(self, value): pass @pyqtSlot(int) ## "垂直旋转" def on_sliderV_valueChanged(self, value): pass @pyqtSlot(int) ## "缩放" def on_sliderZoom_valueChanged(self, value): pass @pyqtSlot() ## 复位到FrontHigh视角 def on_btnResetCamera_clicked(self): pass @pyqtSlot() ## "左移" def on_btnMoveLeft_clicked(self): pass @pyqtSlot() ## "右移" def on_btnMoveRight_clicked(self): pass @pyqtSlot() ## "上移" def on_btnMoveUp_clicked(self): pass @pyqtSlot() ## "下移" def on_btnMoveDown_clicked(self): pass ##====图表总体 @pyqtSlot(int) ## "主题" def on_cBoxTheme_currentIndexChanged(self, index): pass @pyqtSlot(int) ## "字体大小" def on_spinFontSize_valueChanged(self, arg1): pass @pyqtSlot(int) ## "选择模式" def on_cBoxSelectionMode_currentIndexChanged(self, index): pass @pyqtSlot(bool) ## "显示背景" def on_chkBoxBackground_clicked(self, checked): pass @pyqtSlot(bool) ## "显示背景的网格" def on_chkBoxGrid_clicked(self, checked): pass @pyqtSlot(bool) ## "数值坐标轴反向" def on_chkBoxReverse_clicked(self, checked): pass @pyqtSlot(bool) ## "显示倒影" def on_chkBoxReflection_clicked(self, checked): pass @pyqtSlot(bool) ## "轴标题可见" def on_chkBoxAxisTitle_clicked(self, checked): pass @pyqtSlot(bool) ## "轴标签背景可见" def on_chkBoxAxisBackground_clicked(self, checked): pass ##===序列设置 @pyqtSlot(int) ## "棒柱样式" def on_cBoxBarStyle_currentIndexChanged(self, index): pass @pyqtSlot(bool) ## "光滑效果" def on_chkBoxSmooth_clicked(self, checked): pass @pyqtSlot(bool) ## "选中棒柱的标签可见" def on_chkBoxItemLabel_clicked(self, checked): pass ## =============自定义槽函数=============================== def do_barSelected(self, position): ##选择一个棒柱时触发 pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui=Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setWindowTitle("Demo8_6, Graphics View绘图") self.__buildStatusBar() #构造状态栏 self.__iniGraphicsSystem() #初始化 graphics View系统 self.__ItemId=1 #绘图项自定义数据的key self.__ItemDesc=2 #绘图项自定义数据的key self.__seqNum=0 #每个图形项设置一个序号 self.__backZ=0 #后置序号 self.__frontZ=0 #前置序号 ## ==============自定义功能函数============ def __buildStatusBar(self): ##构造状态栏 self.__labViewCord=QLabel("View 坐标:") self.__labViewCord.setMinimumWidth(150) self.ui.statusBar.addWidget(self.__labViewCord) self.__labSceneCord=QLabel("Scene 坐标:") self.__labSceneCord.setMinimumWidth(150) self.ui.statusBar.addWidget(self.__labSceneCord) self.__labItemCord=QLabel("Item 坐标:") self.__labItemCord.setMinimumWidth(150) self.ui.statusBar.addWidget(self.__labItemCord) self.__labItemInfo=QLabel("ItemInfo: ") self.ui.statusBar.addPermanentWidget(self.__labItemInfo) def __iniGraphicsSystem(self): ##初始化 Graphics View系统 self.view=QmyGraphicsView(self) #创建图形视图组件 self.setCentralWidget(self.view) self.scene=QGraphicsScene(-300,-200,600,200) #创建QGraphicsScene self.view.setScene(self.scene) #与view关联 self.view.setCursor(Qt.CrossCursor) #设置鼠标 self.view.setMouseTracking(True) self.view.setDragMode(QGraphicsView.RubberBandDrag) ## 4个信号与槽函数的关联 self.view.mouseMove.connect(self.do_mouseMove) #鼠标移动 self.view.mouseClicked.connect(self.do_mouseClicked) #左键按下 self.view.mouseDoubleClick.connect(self.do_mouseDoubleClick) #鼠标双击 self.view.keyPress.connect(self.do_keyPress) #左键按下 def __setItemProperties(self,item,desc): ##item是具体类型的QGraphicsItem item.setFlag(QGraphicsItem.ItemIsFocusable) item.setFlag(QGraphicsItem.ItemIsMovable) item.setFlag(QGraphicsItem.ItemIsSelectable) self.__frontZ=1+self.__frontZ item.setZValue(self.__frontZ) #叠放次序 item.setPos(-150+random.randint(1,200),-200+random.randint(1,200)) self.__seqNum=1+self.__seqNum item.setData(self.__ItemId,self.__seqNum) #图件编号 item.setData(self.__ItemDesc,desc) #图件描述 self.scene.addItem(item) self.scene.clearSelection() item.setSelected(True) def __setBrushColor(self,item): ##设置填充颜色 color=item.brush().color() color=QColorDialog.getColor(color,self,"选择填充颜色") if color.isValid(): item.setBrush(QBrush(color)) ##==============event 处理函数======================= ## ==========由connectSlotsByName() 自动连接的槽函数================== ##==============创建基本图件============== @pyqtSlot() ##添加一个矩形 def on_actItem_Rect_triggered(self): item=QGraphicsRectItem(-50,-25,100,50) item.setBrush(QBrush(Qt.yellow)) #设置填充颜色 self.__setItemProperties(item,"矩形") @pyqtSlot() ##添加一个椭圆 def on_actItem_Ellipse_triggered(self): item=QGraphicsEllipseItem(-50,-30,100,60) item.setBrush(QBrush(Qt.blue)) #设置填充颜色 self.__setItemProperties(item,"椭圆") @pyqtSlot() ##添加一个圆 def on_actItem_Circle_triggered(self): item=QGraphicsEllipseItem(-50,-50,100,100) item.setBrush(QBrush(Qt.cyan)) #设置填充颜色 self.__setItemProperties(item,"圆形") @pyqtSlot() ##添加三角形 def on_actItem_Triangle_triggered(self): item=QGraphicsPolygonItem() points=[QPointF(0,-40), QPointF(60,40), QPointF(-60,40)] item.setPolygon(QPolygonF(points)) item.setBrush(QBrush(Qt.magenta)) #设置填充颜色 self.__setItemProperties(item,"三角形") @pyqtSlot() ##添加梯形 def on_actItem_Polygon_triggered(self): item=QGraphicsPolygonItem() points=[QPointF(-40,-40), QPointF(40,-40), QPointF(100,40),QPointF(-100,40)] item.setPolygon(QPolygonF(points)) item.setBrush(QBrush(Qt.green)) #设置填充颜色 self.__setItemProperties(item,"梯形") @pyqtSlot() ##添加直线 def on_actItem_Line_triggered(self): item=QGraphicsLineItem(-100,0,100,0) pen=QPen(Qt.red) pen.setWidth(4) item.setPen(pen) #设置线条属性 self.__setItemProperties(item,"直线") @pyqtSlot() ##添加文字 def on_actItem_Text_triggered(self): strText,OK=QInputDialog.getText(self,"输入","请输入文字") if (not OK): return item=QGraphicsTextItem(strText) font=self.font() font.setPointSize(20) font.setBold(True) item.setFont(font) #设置字体 item.setDefaultTextColor(Qt.black) #设置颜色 self.__setItemProperties(item,"文字") ##=============图件的编辑操作=================== @pyqtSlot() ##放大 def on_actZoomIn_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) #选中的图形项的个数 if cnt==1: #只有一个图形项 item=items[0] item.setScale(0.1+item.scale()) else: self.view.scale(1.1,1.1) @pyqtSlot() ##缩小 def on_actZoomOut_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) #选中的图形项的个数 if cnt==1: #只有一个图形项 item=items[0] item.setScale(item.scale()-0.1) else: self.view.scale(0.9,0.9) @pyqtSlot() ##"恢复"取消所有缩放和旋转变换 def on_actRestore_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) if cnt==1: #单个图形项 item=items[0] item.setScale(1) #缩放还原 item.setRotation(0) #旋转还原 ## item.resetTransform() #不起作用,BUG, PyQt 5.12 else: self.view.resetTransform() @pyqtSlot() ##左旋转 def on_actRotateLeft_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) if cnt==1: item=items[0] item.setRotation(-30+item.rotation()) else: self.view.rotate(-30) @pyqtSlot() ##右旋转 def on_actRotateRight_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) if cnt==1: item=items[0] item.setRotation(30+item.rotation()) else: self.view.rotate(30) @pyqtSlot() ##前置 def on_actEdit_Front_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) if cnt>0 : item=items[0] self.__frontZ=1+self.__frontZ item.setZValue(self.__frontZ) @pyqtSlot() ##后置 def on_actEdit_Back_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) if cnt>0 : item=items[0] self.__backZ=self.__backZ-1 item.setZValue(self.__backZ) @pyqtSlot() ##组合 def on_actGroup_triggered(self): items=self.scene.selectedItems() # QGraphicsItem的列表 cnt=len(items) #选中的图形项个数 if (cnt<=1): return group =QGraphicsItemGroup() #创建组合 self.scene.addItem(group) #组合添加到场景中 for i in range(cnt): item=items[i] item.setSelected(False) #清除选择虚线框 item.clearFocus() group.addToGroup(item) #添加到组合 group.setFlag(QGraphicsItem.ItemIsFocusable) group.setFlag(QGraphicsItem.ItemIsMovable) group.setFlag(QGraphicsItem.ItemIsSelectable) self.__frontZ=1+self.__frontZ group.setZValue(self.__frontZ) self.scene.clearSelection() group.setSelected(True) @pyqtSlot() ##打散组合 def on_actGroupBreak_triggered(self): items=self.scene.selectedItems() cnt=len(items) if (cnt==1): #假设选中的是QGraphicsItemGroup group=items[0] self.scene.destroyItemGroup(group) @pyqtSlot() ##删除所有选中的绘图项 def on_actEdit_Delete_triggered(self): items=self.scene.selectedItems() cnt=len(items) for i in range(cnt): item=items[i] self.scene.removeItem(item) #删除绘图项 ## =============自定义槽函数=============================== def do_mouseMove(self,point): ##鼠标移动 ##鼠标移动事件,point是 GraphicsView的坐标,物理坐标 self.__labViewCord.setText("View 坐标:%d,%d" %(point.x(),point.y())) pt=self.view.mapToScene(point) #转换到Scene坐标 self.__labSceneCord.setText("Scene 坐标:%.0f,%.0f"%(pt.x(),pt.y())) def do_mouseClicked(self,point): ##鼠标单击 pt=self.view.mapToScene(point) #转换到Scene坐标 item=self.scene.itemAt(pt,self.view.transform()) #获取光标下的图形项 if (item == None): return pm=item.mapFromScene(pt) #转换为绘图项的局部坐标 self.__labItemCord.setText("Item 坐标:%.0f,%.0f"%(pm.x(),pm.y())) self.__labItemInfo.setText(str(item.data(self.__ItemDesc)) +", ItemId="+str(item.data(self.__ItemId))) def do_mouseDoubleClick(self,point): ##鼠标双击 pt=self.view.mapToScene(point) #转换到Scene坐标,QPointF item=self.scene.itemAt(pt,self.view.transform()) #获取光标下的绘图项 if (item == None): return className=str(type(item)) #将类名称转换为字符串 ## print(className) if (className.find("QGraphicsRectItem") >=0): #矩形框 self.__setBrushColor(item) elif (className.find("QGraphicsEllipseItem")>=0): #椭圆和圆都是 QGraphicsEllipseItem self.__setBrushColor(item) elif (className.find("QGraphicsPolygonItem")>=0): #梯形和三角形 self.__setBrushColor(item) elif (className.find("QGraphicsLineItem")>=0): #直线,设置线条颜色 pen=item.pen() color=item.pen().color() color=QColorDialog.getColor(color,self,"选择线条颜色") if color.isValid(): pen.setColor(color) item.setPen(pen) elif (className.find("QGraphicsTextItem")>=0): #文字,设置字体 font=item.font() font,OK=QFontDialog.getFont(font) if OK: item.setFont(font) def do_keyPress(self,event): ##按键操作 items=self.scene.selectedItems() cnt=len(items) if (cnt!=1): return item=items[0] key=event.key() if (key==Qt.Key_Delete): #删除 self.scene.removeItem(item) elif (key==Qt.Key_Space): #顺时针旋转90度 item.setRotation(90+item.rotation()) elif (key==Qt.Key_PageUp): #放大 item.setScale(0.1+item.scale()) elif (key==Qt.Key_PageDown): #缩小 item.setScale(-0.1+item.scale()) elif (key==Qt.Key_Left): #左移 item.setX(-1+item.x()) elif (key==Qt.Key_Right): #右移 item.setX(1+item.x()) elif (key==Qt.Key_Up): #上移 item.setY(-1+item.y()) elif (key==Qt.Key_Down): #下移 item.setY(1+item.y())
class MainWindow(QMainWindow): _tr = QCoreApplication.translate def __init__(self, parent=None): super().__init__(parent) # 调用父类构造函数,创建窗体 self.__scene = None # 创建QGraphicsScene self.__view = None # 创建图形视图组件 self.ui = Ui_MainWindow() # 创建UI对象 self.ui.setupUi(self) # 构造UI界面 self.operatorFile = OperatorFile(self) self.__translator = None title = self.tr("基于Python的图的绘制及相关概念的可视化展示") self.setWindowTitle(title) self.ui.nodeDetails.setEnabled(False) self.ui.edgeDetails.setEnabled(False) self.ui.actionSave.setEnabled(False) self.edgeModel = QStandardItemModel(5, 5, self) self.edgeSelectionModel = QItemSelectionModel(self.edgeModel) self.edgeModel.dataChanged.connect(self.do_updateEdgeWeight) self.nodeModel = QStandardItemModel(5, 4, self) self.nodeSelectionModel = QItemSelectionModel(self.nodeModel) self.nodeModel.dataChanged.connect(self.do_updateNodeWeight) self.spinWeight = WeightSpinDelegate(0, 200, 1, self) self.ui.tabWidget.setVisible(False) self.ui.tabWidget.clear() self.ui.tabWidget.setTabsClosable(True) self.ui.tabWidget.setDocumentMode(True) self.setCentralWidget(self.ui.tabWidget) self.setAutoFillBackground(True) self.__buildStatusBar() # 构造状态栏 self.__buildUndoCommand() # 初始化撤销重做系统 self.__initModeMenu() self.__lastColumnFlag = Qt.NoItemFlags self.iniGraphicsSystem() self.__ItemId = 0 # 绘图项自定义数据的key self.__ItemDesc = 1 # 绘图项自定义数据的key self.__nodeNum = 0 # 结点的序号 self.__edgeNum = 0 # 边的序号 self.__textNum = 0 self.lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) self.__graph = Graph() ## ==============自定义功能函数============ def nodeNum(self): return self.__nodeNum def edgeNum(self): return self.__edgeNum def scene(self): self.viewAndScene() return self.__scene def view(self): self.viewAndScene() return self.__view def graph(self): return self.__graph def __buildStatusBar(self): ##构造状态栏 self.__labViewCord = QLabel(self._tr("MainWindow", "视图坐标:")) self.__labViewCord.setMinimumWidth(150) self.ui.statusbar.addWidget(self.__labViewCord) self.__labSceneCord = QLabel(self._tr("MainWindow", "场景坐标:")) self.__labSceneCord.setMinimumWidth(150) self.ui.statusbar.addWidget(self.__labSceneCord) self.__labItemCord = QLabel(self._tr("MainWindow", "图元坐标:")) self.__labItemCord.setMinimumWidth(150) self.ui.statusbar.addWidget(self.__labItemCord) self.__labItemInfo = QLabel(self._tr("MainWindow", "图元信息: ")) self.ui.statusbar.addPermanentWidget(self.__labItemInfo) self.__labModeInfo = QLabel(self._tr("MainWindow", "有向图模式")) self.ui.statusbar.addPermanentWidget(self.__labModeInfo) def __buildUndoCommand(self): self.undoStack = QUndoStack() self.addAction(self.ui.actionUndo) self.addAction(self.ui.actionRedo) self.ui.undoView.setStack(self.undoStack) def __setItemProperties(self, item, desc): ##item是具体类型的QGraphicsItem self.__nodeNum = len(self.singleItems(BezierNode)) self.__edgeNum = len(self.singleItems(BezierEdge)) self.__textNum = len(self.singleItems(BezierText)) item.setFlag(QGraphicsItem.ItemIsFocusable) item.setFlag(QGraphicsItem.ItemIsMovable) item.setFlag(QGraphicsItem.ItemIsSelectable) item.setPos(-150 + randint(1, 200), -200 + randint(1, 200)) if type(item) is BezierNode: newNum = self.checkSort(self.__scene.uniqueIdList(BezierNode)) if newNum is not None: item.setData(self.__ItemId, newNum) item.textCp.setPlainText("V" + str(newNum)) else: item.setData(self.__ItemId, self.__nodeNum) item.textCp.setPlainText("V" + str(self.__nodeNum)) self.__nodeNum = 1 + self.__nodeNum elif type(item) is BezierEdge: newNum = self.checkSort(self.__scene.uniqueIdList(BezierEdge)) if newNum is not None: item.setData(self.__ItemId, newNum) item.textCp.setPlainText("e" + str(newNum)) else: item.setData(self.__ItemId, self.__edgeNum) item.textCp.setPlainText("e" + str(self.__edgeNum)) self.__edgeNum = 1 + self.__edgeNum elif type(item) is BezierText: newNum = self.checkSort(self.__scene.uniqueIdList(BezierText)) if newNum is not None: item.setData(self.__ItemId, newNum) else: item.setData(self.__ItemId, self.__textNum) self.__textNum = 1 + self.__textNum item.setData(self.__ItemDesc, desc) # 图件描述 self.__scene.addItem(item) self.__scene.clearSelection() item.setSelected(True) def __setBrushColor(self, item): ##设置填充颜色 color = item.brush().__color() color = QColorDialog.getColor(color, self, self._tr("MainWindow", "选择填充颜色")) if color.isValid(): item.setBrush(QBrush(color)) def __initFileMenu(self): self.ui.actionOpen.triggered.connect(self.do_open_file) self.ui.actionSave.triggered.connect(self.do_save_file) self.ui.actionQuit.triggered.connect(self.close) def __initModeMenu(self): modeMenuGroup = QActionGroup(self) modeMenuGroup.addAction(self.ui.actionDigraph_Mode) modeMenuGroup.addAction(self.ui.actionRedigraph_Mode) def __updateEdgeView(self): edges = self.singleItems(BezierEdge) if len(edges): self.ui.edgeDetails.setEnabled(True) else: return edgeColCount = 5 self.edgeModel.clear() edgeHeaderList = [ self._tr("MainWindow", 'ID'), self._tr("MainWindow", '始点'), self._tr("MainWindow", '终点'), self._tr("MainWindow", '坐标'), self._tr("MainWindow", '权重') ] self.edgeModel.setHorizontalHeaderLabels(edgeHeaderList) self.edgeSelectionModel.currentChanged.connect(self.do_curEdgeChanged) self.ui.edgeDetails.setModel(self.edgeModel) self.ui.edgeDetails.setSelectionModel(self.edgeSelectionModel) self.ui.edgeDetails.verticalHeader().setSectionResizeMode( QHeaderView.Fixed) self.ui.edgeDetails.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.ui.edgeDetails.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.ui.edgeDetails.setAlternatingRowColors(True) self.edgeModel.setRowCount(len(edges)) self.ui.edgeDetails.setItemDelegateForColumn(4, self.spinWeight) edges.reverse() for i in range(len(edges)): edge: BezierEdge = edges[i] sourceNode = f'V{edge.sourceNode.data(self.__ItemId)}' if edge.sourceNode else None destNode = f'V{edge.destNode.data(self.__ItemId)}' if edge.destNode else None strList = [ f"e{edge.data(self.__ItemId)}", sourceNode, destNode, f"x:{edge.pos().x()},y:{edge.pos().y()}", f"{edge.weight()}" ] for j in range(edgeColCount): item = QStandardItem(strList[j]) if j != edgeColCount - 1: item.setFlags(self.__lastColumnFlag) self.edgeModel.setItem(i, j, item) def __updateNodeView(self): nodes = self.singleItems(BezierNode) if len(nodes): self.ui.nodeDetails.setEnabled(True) else: return nodeColCount = 4 self.nodeModel.clear() nodeHeaderList = [ self._tr("MainWindow", 'ID'), self._tr("MainWindow", '边数'), self._tr("MainWindow", '坐标'), self._tr("MainWindow", '权重') ] if self.ui.actionDigraph_Mode.isChecked(): nodeHeaderList.append(self._tr("MainWindow", '出度')) nodeHeaderList.append(self._tr("MainWindow", '入度')) nodeColCount += 2 else: nodeHeaderList.append(self._tr("MainWindow", "度")) nodeColCount += 1 self.nodeModel.setHorizontalHeaderLabels(nodeHeaderList) self.nodeModel.setRowCount(len(nodes)) self.nodeSelectionModel.currentChanged.connect(self.do_curNodeChanged) self.ui.nodeDetails.setModel(self.nodeModel) self.ui.nodeDetails.setSelectionModel(self.nodeSelectionModel) self.ui.nodeDetails.verticalHeader().setSectionResizeMode( QHeaderView.Fixed) self.ui.nodeDetails.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.ui.nodeDetails.setAlternatingRowColors(True) self.ui.nodeDetails.setItemDelegateForColumn(3, self.spinWeight) nodes.reverse() for i in range(len(nodes)): node: BezierNode = nodes[i] strList = [ f"V{node.data(self.__ItemId)}", str(len(node.bezierEdges)), f"x:{node.pos().x()},y:{node.pos().y()}", str(node.weight()) ] if self.ui.actionDigraph_Mode.isChecked(): strList.append( f'{node.degrees(self.ui.actionDigraph_Mode.isChecked())[1]}' ) strList.append( f'{node.degrees(self.ui.actionDigraph_Mode.isChecked())[0]}' ) else: strList.append( f'{node.degrees(self.ui.actionDigraph_Mode.isChecked())}') for j in range(nodeColCount): item = QStandardItem(strList[j]) if j != 3: item.setFlags(self.__lastColumnFlag) self.nodeModel.setItem(i, j, item) def iniGraphicsSystem(self, name=None): ##初始化 Graphics View系统 scene = GraphicsScene() # 创建QGraphicsScene view = GraphicsView(self, scene) # 创建图形视图组件 view.mouseMove.connect(self.do_mouseMove) # 鼠标移动 view.mouseClicked.connect(self.do_mouseClicked) # 左键按下 scene.itemMoveSignal.connect(self.do_shapeMoved) scene.itemLock.connect(self.do_nodeLock) scene.isHasItem.connect(self.do_checkIsHasItems) if name: title = name else: text = self.tr('未命名') title = f'{text}{self.ui.tabWidget.count()}' curIndex = self.ui.tabWidget.addTab(view, title) self.ui.tabWidget.setCurrentIndex(curIndex) self.ui.tabWidget.setVisible(True) ## 4个信号与槽函数的关联 # self.view.mouseDoubleClick.connect(self.do_mouseDoubleClick) # 鼠标双击 # self.view.keyPress.connect(self.do_keyPress) # 左键按下 def singleItems(self, className) -> list: self.viewAndScene() return self.__scene.singleItems(className) def connectGraph(self): self.__graph.setMode(self.ui.actionDigraph_Mode.isChecked()) items = self.__scene.uniqueItems() nodeList = [] edgeList = [] if not len(items): return for item in items: if type(item) is BezierNode: nodeList.append(item) elif type(item) is BezierEdge: edgeList.append(item) for node in nodeList: self.__graph.addVertex(node.data(self.__ItemId)) badEdgeList = [] for i in range(len(edgeList)): for edge in edgeList: edge: BezierEdge if edge.data(self.__ItemId) == i: if edge.sourceNode and edge.destNode: self.__graph.addEdge( edge.sourceNode.data(self.__ItemId), edge.destNode.data(self.__ItemId), edge.weight()) else: badEdgeList.append(edge) if len(badEdgeList) != 0: self.disconnectGraph() string = "" for x in range(len(badEdgeList)): demo = "、" if x == len(badEdgeList) - 1: demo = "" string = f'{string}e{badEdgeList[x].data(self.__ItemId)}{demo}' QMessageBox.warning( self, self._tr("MainWindow", "连接故障!"), self._tr("MainWindow", "警告,") + string + self._tr("MainWindow", "的连接不完整")) return False return True def disconnectGraph(self): self.__graph.clearAllData() def viewAndScene(self): if self.ui.tabWidget.count(): self.__view: GraphicsView = self.ui.tabWidget.currentWidget() self.__scene = self.__view.scene() def standardGraphData(self): mode = int(self.ui.actionDigraph_Mode.isChecked()) nodes = self.__scene.singleItems(BezierNode) edges = self.__scene.singleItems(BezierEdge) texts = self.__scene.singleItems(BezierText) nodeDataList = [] edgeDataList = [] textDataList = [] for node in nodes: node: BezierNode data = [ node.data(self.__ItemId), node.weight(), node.pos().x(), node.pos().y() ] nodeDataList.append(data) for edge in edges: edge: BezierEdge data = [edge.data(self.__ItemId)] if edge.sourceNode: data.append(edge.sourceNode.data(self.__ItemId)) else: data.append(-1) if edge.destNode: data.append(edge.destNode.data(self.__ItemId)) else: data.append(-1) data = data + [ edge.weight(), edge.beginCp.point().x(), edge.beginCp.point().y(), edge.edge1Cp.point().x(), edge.edge1Cp.point().y(), edge.edge2Cp.point().x(), edge.edge2Cp.point().y(), edge.endCp.point().x(), edge.endCp.point().y(), edge.scenePos().x(), edge.scenePos().y() ] edgeDataList.append(data) for text in texts: text: BezierText data = [ text.data(self.__ItemId), text.toPlainText(), text.scenePos().x(), text.scenePos().y() ] textDataList.append(data) nodeDataList.reverse() edgeDataList.reverse() textDataList.reverse() return [mode, nodeDataList, edgeDataList, textDataList] def reverseStandardData(self, excelData): graphName = excelData[0] mode = excelData[1] nodes = [] edges = [] texts = [] self.ui.actionDigraph_Mode.setChecked(bool(mode)) for nodeDetail in excelData[2]: node = BezierNode() node.textCp.setPlainText(f"V{nodeDetail[0]}") node.setData(self.__ItemId, nodeDetail[0]) nodeText = self._tr("MainWindow", "顶点") node.setData(self.__ItemDesc, nodeText) if len(nodeDetail) < 3: for i in range(2): intRandom = randint(-400, 400) nodeDetail.append(intRandom) node.setPos(QPointF(nodeDetail[2], nodeDetail[3])) node.weightCp.setPlainText(str(nodeDetail[1])) nodes.append(node) for edgeDetail in excelData[3]: edge = BezierEdge() edge.setData(self.__ItemId, edgeDetail[0]) edge.setData(self.__ItemDesc, "边") edge.textCp.setPlainText(f"e{edgeDetail[0]}") edge.weightCp.setPlainText(str(edgeDetail[3])) if len(edgeDetail) <= 4: for i in range(10): intRandom = randint(-400, 400) edgeDetail.append(intRandom) edge.setPos(QPointF(edgeDetail[12], edgeDetail[13])) if edgeDetail[1] >= 0: for node in nodes: node: BezierNode if node.data(self.__ItemId) == edgeDetail[1]: edge.setSourceNode(node) node.addBezierEdge(edge, ItemType.SourceType) line = QLineF(edge.mapFromScene(node.pos()), edge.edge1Cp.point()) length = line.length() edgeOffset = QPointF(line.dx() * 10 / length, line.dy() * 10 / length) source = edge.mapFromScene(node.pos()) + edgeOffset edge.setSpecialControlPoint(source, ItemType.SourceType) edge.beginCp.setVisible(False) else: edge.setSpecialControlPoint( QPointF(edgeDetail[4], edgeDetail[5]), ItemType.SourceType) if edgeDetail[2] >= 0: for node in nodes: node: BezierNode if node.data(self.__ItemId) == edgeDetail[2]: edge.setDestNode(node) node.addBezierEdge(edge, ItemType.DestType) line = QLineF(edge.mapFromScene(node.pos()), edge.edge2Cp.point()) length = line.length() edgeOffset = QPointF(line.dx() * 10 / length, line.dy() * 10 / length) if mode: dest = edge.mapFromScene( node.pos()) + edgeOffset * 2.3 else: dest = edge.mapFromScene(node.pos()) + edgeOffset edge.setSpecialControlPoint(dest, ItemType.DestType) edge.endCp.setVisible(False) else: edge.setSpecialControlPoint( QPointF(edgeDetail[10], edgeDetail[11]), ItemType.DestType) edge.setEdgeControlPoint(QPointF(edgeDetail[6], edgeDetail[7]), ItemType.SourceType) edge.setEdgeControlPoint(QPointF(edgeDetail[8], edgeDetail[9]), ItemType.DestType) edge.centerCp.setPoint(edge.updateCenterPos()) edges.append(edge) if len(excelData) <= 4: return [graphName, nodes + edges] for textDetail in excelData[4]: text = BezierText(str(textDetail[1])) text.setData(self.__ItemId, textDetail[0]) text.setData(self.__ItemDesc, "文本") text.setPos(textDetail[2], textDetail[3]) texts.append(text) return [graphName, nodes + edges + texts] def setTranslator(self, translator, language): self.__translator = translator if language == 'EN': self.ui.actionSetEnglish.setChecked(True) else: self.ui.actionSetChinese.setChecked(True) @classmethod def checkSort(cls, index: list): index.sort() for i in range(len(index)): if i != index[i]: return i # ==============event处理函数========================== # def closeEvent(self, event): # 退出函数 # # msgBox = QMessageBox() # msgBox.setWindowTitle('关闭') # msgBox.setText("是否保存") # msgBox.setIcon(QMessageBox.Question) # btn_Do_notSave = msgBox.addButton('不保存', QMessageBox.AcceptRole) # btn_cancel = msgBox.addButton('取消', QMessageBox.RejectRole) # btn_save = msgBox.addButton('保存', QMessageBox.AcceptRole) # msgBox.setDefaultButton(btn_save) # msgBox.exec_() # # if msgBox.clickedButton() == btn_Do_notSave: # event.accept() # elif msgBox.clickedButton() == btn_cancel: # event.ignore() # elif msgBox.clickedButton() == btn_save: # self.do_save_file() # event.accept() # def contextMenuEvent(self, event): # 右键菜单功能 # rightMouseMenu = QMenu(self) # # rightMouseMenu.addAction(self.ui.actionNew) # rightMouseMenu.addAction(self.ui.actionOpen) # # self.action = rightMouseMenu.exec_(self.mapToGlobal(event.pos())) # ==========由connectSlotsByName()自动连接的槽函数============ @Slot() # 新建画板 def on_actionNew_triggered(self): self.iniGraphicsSystem() @Slot() # 添加边 def on_actionArc_triggered(self): # 添加曲线 item = BezierEdge() item.setGraphMode(self.ui.actionDigraph_Mode.isChecked()) self.__setItemProperties(item, self._tr("MainWindow", "边")) self.do_addItem(item) self.__updateEdgeView() self.__updateNodeView() @Slot() # 添加顶点 def on_actionCircle_triggered(self): # 添加原点 self.viewAndScene() item = BezierNode() self.__setItemProperties(item, self._tr("MainWindow", "顶点")) self.do_addItem(item) self.__updateNodeView() self.__updateEdgeView() @Slot() # 添加注释 def on_actionAdd_Annotation_triggered(self): self.viewAndScene() strText, OK = QInputDialog.getText(self, self._tr("MainWindow", "输入"), self._tr("MainWindow", "请输入文字")) if not OK: return item = BezierText(strText) self.__setItemProperties(item, self._tr("MainWindow", "注释")) self.do_addItem(item) @Slot(bool) # 显示和隐藏结点权重 def on_actionShowNodesWeight_toggled(self, check: bool): nodes = self.__scene.singleItems(BezierNode) for node in nodes: node: BezierNode node.weightCp.setVisible(check) # if check: # self.ui.actionShowNodesWeight.setText("隐藏顶点权重") # else: # self.ui.actionShowNodesWeight.setText("显示顶点权重") @Slot(bool) # 显示和隐藏边权重 def on_actionShowEdgesWeight_toggled(self, check: bool): edges = self.__scene.singleItems(BezierEdge) for edge in edges: edge: BezierEdge edge.weightCp.setVisible(check) # if check: # self.ui.actionShowEdgesWeight.setText("隐藏边权重") # else: # self.ui.actionShowEdgesWeight.setText("显示边权重") @Slot(bool) # 显示和隐藏边的控制点 def on_actionHideControlPoint_toggled(self, check: bool): edges = self.__scene.singleItems(BezierEdge) for edge in edges: edge: BezierEdge for point in edge.pointList: point.setVisible(check) if edge.sourceNode: edge.beginCp.setVisible(False) if edge.destNode: edge.endCp.setVisible(False) @Slot() # 简单通路 def on_actionEasy_Pathway_triggered(self): self.viewAndScene() items = self.__scene.nodeList if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "对不起,你没有选择起始节点")) return elif len(items) != 2: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "选择的起始点数目不符合要求")) return if self.connectGraph(): PathWay = ShowDataWidget(self, items, self.__graph, name=self._tr("MainWindow", "简单通路")) PathWay.pathSignal.connect(self.do_ShowSelectPath) if PathWay.easyPath(): PathWay.updateToolWidget() PathWay.show() self.disconnectGraph() @Slot() # 简单回路 def on_actionEasy_Loop_triggered(self): self.viewAndScene() items = self.__scene.nodeList if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "对不起,你没有选择起点")) return if self.connectGraph(): LoopWay = ShowDataWidget(self, items, self.__graph, name=self._tr("MainWindow", "简单回路")) LoopWay.pathSignal.connect(self.do_ShowSelectPath) if LoopWay.easyLoop(): LoopWay.updateToolWidget(mode=1) LoopWay.show() self.disconnectGraph() @Slot() # 初级通路 def on_actionPrimary_Pathway_triggered(self): items = self.__scene.nodeList if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "对不起,你没有选择起始节点")) return elif len(items) != 2: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "选择的起始点数目不符合要求")) return if self.connectGraph(): PathWay = ShowDataWidget(self, items, self.__graph, name="初级通路") PathWay.pathSignal.connect(self.do_ShowSelectPath) if PathWay.primaryPath(): PathWay.updateToolWidget(path=1) PathWay.show() self.disconnectGraph() @Slot() # 初级回路 def on_actionPrimary_Loop_triggered(self): items = self.__scene.nodeList if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "对不起,你没有选择起点")) return if self.connectGraph(): LoopWay = ShowDataWidget(self, items, self.__graph, name=self._tr("MainWindow", "初级回路")) LoopWay.pathSignal.connect(self.do_ShowSelectPath) if LoopWay.primaryLoop(): LoopWay.updateToolWidget(mode=1, path=1) LoopWay.show() self.disconnectGraph() @Slot() # 邻接矩阵 边数 def on_action_EdgeNum_triggered(self): self.viewAndScene() items = self.__scene.singleItems(BezierNode) if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "图中没有结点")) return if self.connectGraph(): MatrixTable = ShowMatrixWidget(self, self.__graph, self._tr("MainWindow", "邻接矩阵"), 0) MatrixTable.show() @Slot() # 邻接矩阵 权重 def on_actionWeight_triggered(self): self.viewAndScene() items = self.__scene.singleItems(BezierNode) if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "图中没有结点")) return if self.connectGraph(): if not self.__graph.multipleOrSimple(): MatrixTable = ShowMatrixWidget(self, self.__graph, self._tr("MainWindow", "邻接矩阵"), 1) MatrixTable.show() else: QMessageBox.information(self, "Sorry", "这个图不是简单图") self.disconnectGraph() @Slot() # 可达矩阵 def on_actionReachable_Matrix_triggered(self): self.viewAndScene() items = self.__scene.singleItems(BezierNode) if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "图中没有结点")) return if self.connectGraph(): MatrixTable = ShowMatrixWidget(self, self.__graph, self._tr("MainWindow", "可达矩阵")) MatrixTable.show() @Slot() # 关联矩阵 def on_actionIncidence_Matrix_Undigraph_triggered(self): self.viewAndScene() items = self.__scene.singleItems(BezierNode) if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "图中没有结点")) return if self.ui.actionDigraph_Mode.isChecked(): items = self.singleItems(BezierEdge) badNodeList = [] badNodes = '' for x in range(len(items)): if items[x].sourceNode is not None and items[ x].destNode is not None: if items[x].sourceNode == items[x].destNode: badNodeList.append(items[x]) demo = "、" if x == len(items) - 1: demo = "" badNodes = f"{badNodes}V{items[x].sourceNode.data(self.__ItemId)}{demo}" if len(badNodeList): text = self._tr("MainWindow", '有向图的关联矩阵需要有向图无环,而') text1 = self._tr("MainWindow", '存在环!') QMessageBox.warning(self, self._tr("MainWindow", "致命错误"), f"{text}{badNodes}{text1}") return if self.connectGraph(): MatrixTable = ShowMatrixWidget(self, self.__graph, self._tr("MainWindow", "关联矩阵")) MatrixTable.show() @Slot() # 图的连通性 def on_actionConnectivity_triggered(self): name = '' if self.connectGraph(): num = self.__graph.connectivity() if num is False: name = self._tr("MainWindow", '此图为非连通图') elif num == 2: name = self._tr("MainWindow", "此图为单向连通图") elif num == 3: name = self._tr("MainWindow", "此图为强连通图") elif num == 1: name = self._tr("MainWindow", '此图为连通图') QMessageBox.information(self, self._tr("MainWindow", "图的连通性"), name) self.disconnectGraph() @Slot() # 完全图判定 def on_actionCompleteGraph_triggered(self): if self.connectGraph(): edge = self.__graph.completeGraph() if edge: name = self._tr("MainWindow", "此图为完全图") else: name = self._tr("MainWindow", '此图不是完全图') QMessageBox.information(self, self._tr("MainWindow", "完全图判定"), name) self.disconnectGraph() @Slot() # 简单图多重图判定 def on_actionMultipleOrSimple_triggered(self): if self.connectGraph(): edges = self.__graph.multipleOrSimple() if not edges: QMessageBox.information(self, self._tr("MainWindow", "简单图与多重图的判定"), self._tr("MainWindow", "此图为简单图")) else: parallelSides = ShowDataWidget( self, edges, self.__graph, self._tr("MainWindow", "简单图与多重图的判定")) parallelSides.multipleOrSimple() parallelSides.show() @Slot() # 最短路径 def on_actionShortestPath_triggered(self): items = self.__scene.nodeList if len(items) == 0: QMessageBox.warning(self, self._tr("MainWindow", "警告"), self._tr("MainWindow", "对不起,你没有选择结点")) return if self.connectGraph(): ShortestPath = ShowDataWidget(self, items, self.__graph, name=self._tr("MainWindow", "最短路径")) ShortestPath.pathSignal.connect(self.do_ShowSelectPath) if ShortestPath.shortestPath(): ShortestPath.updateToolWidget(mode=1, path=2) ShortestPath.show() @Slot() # 撤销 def on_actionUndo_triggered(self): # 撤销 self.undoStack.undo() self.__updateEdgeView() self.__updateNodeView() @Slot() # 重做 def on_actionRedo_triggered(self): # 重做 self.viewAndScene() self.undoStack.redo() self.__updateEdgeView() self.__updateNodeView() @Slot() # 帮助 def on_actionHelp_Document_triggered(self): open("https://github.com/BBlance/Discrete_math.graph_theory") # @Slot() # def on_actionPen_Color_triggered(self): # 画笔颜色 # iniColor = self.view.getPenColor() # color = QColorDialog.getColor(iniColor, self, "选择颜色") # if color.isValid(): # self.view.setPenColor(color) # @Slot() # def on_actionPen_Thickness_triggered(self): # 画笔粗细 # self.viewAndScene() # iniThickness = self.__view.getPenThickness() # intPenStyle = self.__view.getPenStyle() # thicknessDialog = ThicknessDialog(None, self._tr("MainWindow", "画笔粗细与样式"), iniThickness, intPenStyle) # ret = thicknessDialog.exec_() # thickness = thicknessDialog.getThickness() # penStyle = thicknessDialog.getPenStyle() # self.__view.setPenStyle(penStyle) # self.__view.setPenThickness(thickness) @Slot() def on_actionBackground_Color_triggered(self): self.viewAndScene() # iniColor = self.__view.getBackgroundColor() # color = QColorDialog.getColor(iniColor, self, "选择颜色") # if color.isValid(): # self.__view.setBackgroundBrush(color) for item in self.standardGraphData(): print(item) # @Slot(bool) # def on_actionProperty_And_History_triggered(self, checked): # self.ui.dockWidget.setVisible(checked) @Slot() # 保存文件 def on_actionSave_triggered(self): self.viewAndScene() tableName = self.ui.tabWidget.tabText(self.ui.tabWidget.currentIndex()) filename = self.operatorFile.saveGraphData(self.standardGraphData(), tableName) if filename: index = self.ui.tabWidget.currentIndex() self.ui.tabWidget.setTabText(index, filename.baseName()) @Slot() # 读取文件 def on_actionOpen_triggered(self): graph = self.operatorFile.openGraphData() if graph: graph = self.reverseStandardData(graph) self.iniGraphicsSystem(graph[0]) for item in graph[1]: self.__scene.addItem(item) self.__updateNodeView() self.__updateEdgeView() self.__scene.update() @Slot() # 另存为 def on_actionSave_As_triggered(self): filename = self.operatorFile.saveExcelAs(self.standardGraphData()) if filename: index = self.ui.tabWidget.currentIndex() self.ui.tabWidget.setTabText(index, filename.baseName()) @Slot() # 导出数据 def on_actionOutputData_triggered(self): data = self.standardGraphData() data = data[:3] dataCpoy = [data[0], [], []] for node in data[1]: node = node[:2] dataCpoy[1].append(node) for edge in data[2]: edge = edge[:4] dataCpoy[2].append(edge) if self.operatorFile.outputData(dataCpoy): title = self.tr("恭喜") strInfo = self.tr("数据导出成功") QMessageBox.information(self, title, strInfo) @Slot() # 导入数据 def on_actionImportData_triggered(self): data = self.operatorFile.inputData() if data: graph = self.reverseStandardData(data) self.iniGraphicsSystem(graph[0]) for item in graph[1]: self.__scene.addItem(item) self.__updateNodeView() self.__updateEdgeView() self.__scene.update() @Slot() def on_actionSave_Image_triggered(self): self.viewAndScene() savePath, fileType = QFileDialog.getSaveFileName( self, self._tr("MainWindow", '保存图片'), '.\\', '*bmp;;*.png') filename = os.path.basename(savePath) if filename != "": self.__view.saveImage(savePath, fileType) @Slot() def on_actionDelete_triggered(self): self.viewAndScene() self.do_deleteItem() @Slot(bool) def on_actionDigraph_Mode_toggled(self, checked: bool): self.__labModeInfo.setText(self._tr("MainWindow", "有向图模式")) self.__graph.setMode(checked) items = self.__scene.singleItems(BezierEdge) for item in items: item: BezierEdge item.setGraphMode(True) item.update() @Slot(bool) def on_actionRedigraph_Mode_toggled(self, checked: bool): self.__labModeInfo.setText(self._tr("MainWindow", "无向图模式")) self.__graph.setMode(checked) items = self.__scene.singleItems(BezierEdge) for item in items: item: BezierEdge item.setGraphMode(False) item.update() @Slot(int) def on_tabWidget_currentChanged(self, index): # ui.tabWidget当前页面变化 self.viewAndScene() if self.__view and self.__scene: self.__updateEdgeView() self.__updateNodeView() hasTabs = self.ui.tabWidget.count() > 0 # 再无页面时 self.ui.tabWidget.setVisible(hasTabs) self.ui.dockWidget.setVisible(hasTabs) self.ui.actionProperty_And_History.setChecked(hasTabs) @Slot(int) def on_tabWidget_tabCloseRequested(self, index): # 分页关闭时关闭窗体 if index < 0: return view = self.ui.tabWidget.widget(index) view.close() # self.__view = None # self.__scene = None # =============自定义槽函数=============================== def do_nodeLock(self, item): self.__updateNodeView() self.__updateEdgeView() def do_mouseMove(self, point): ##鼠标移动 ##鼠标移动事件,point是 GraphicsView的坐标,物理坐标 view = self._tr("MainWindow", '视图坐标:') scene = self._tr("MainWindow", '场景坐标:') self.__labViewCord.setText("%s%d,%d" % (view, point.x(), point.y())) pt = self.ui.tabWidget.currentWidget().mapToScene(point) # 转换到Scene坐标 self.__labSceneCord.setText("%s%.0f,%.0f" % (scene, pt.x(), pt.y())) def do_mouseClicked(self, point): ##鼠标单击 pt = self.__view.mapToScene(point) # 转换到Scene坐标 item = self.__scene.itemAt(pt, self.__view.transform()) # 获取光标下的图形项 if item is None: return pm = item.mapFromScene(pt) # 转换为绘图项的局部坐标 itemInfo = self._tr("MainWindow", "Item 坐标:") self.__labItemCord.setText("%s%.0f,%.0f" % (itemInfo, pm.x(), pm.y())) data = f"{item.data(self.__ItemDesc)}, ItemId={item.data(self.__ItemId)}" if type(item) is BezierEdge: data = f"{data},EdgeId=e{item.data(self.__ItemId)}" elif type(item) is BezierNode: data = f"{data}, NodeId=V{item.data(self.__ItemId)}" self.__labItemInfo.setText(data) def do_mouseDoubleClick(self, point): ##鼠标双击 pt = self.__view.mapToScene(point) # 转换到Scene坐标,QPointF item = self.__scene.itemAt(pt, self.__view.transform()) # 获取光标下的绘图项 if item is None: return className = str(type(item)) # 将类名称转换为字符串 if className.find("QGraphicsRectItem") >= 0: # 矩形框 self.__setBrushColor(item) elif className.find( "QGraphicsEllipseItem") >= 0: # 椭圆和圆都是 QGraphicsEllipseItem self.__setBrushColor(item) elif className.find("QGraphicsPolygonItem") >= 0: # 梯形和三角形 self.__setBrushColor(item) elif className.find("QGraphicsLineItem") >= 0: # 直线,设置线条颜色 pen = item.pen() color = item.pen().__color() color = QColorDialog.getColor(color, self, "选择线条颜色") if color.isValid(): pen.setColor(color) item.setPen(pen) elif className.find("QGraphicsTextItem") >= 0: # 文字,设置字体 font = item.font() font, OK = QFontDialog.getFont(font) if OK: item.setFont(font) def do_addItem(self, item): add = AddCommand(self, self.__scene, item) self.undoStack.push(add) def do_shapeMoved(self, item, pos): move = MoveCommand(item, pos) self.undoStack.push(move) def do_deleteItem(self): items = self.__scene.selectedItems() cnt = len(items) for i in range(cnt): item = items[i] if str(type(item)).find("BezierNode") >= 0: item: BezierNode for edge in item.bezierEdges: for node, itemType in edge.items(): if itemType == ItemType.SourceType: node.setSourceNode(None) elif itemType == ItemType.DestType: node.setDestNode(None) self.__nodeNum -= 1 elif str(type(item)).find("BezierEdge") >= 0: item: BezierEdge sourceNode: BezierNode = item.sourceNode destNode: BezierNode = item.destNode if sourceNode: sourceNodeList = sourceNode.bezierEdges for sourceEdge in sourceNodeList: for edge in sourceEdge.keys(): if item is edge: sourceNodeList.remove(sourceEdge) if destNode: destNodeList = destNode.bezierEdges for destEdge in destNodeList: for edge in destEdge.keys(): if item is edge: destNodeList.remove(destEdge) self.__edgeNum -= 1 self.__scene.removeItem(item) # 删除绘图项 def do_curEdgeChanged(self, current, previous): if current is not None: text = f"当前单元格{current.row()},{current.column()}" item = self.edgeModel.itemFromIndex(current) def do_curNodeChanged(self, current, previous): if current is not None: text = f"当前单元格{current.row()},{current.column()}" item = self.nodeModel.itemFromIndex(current) def do_updateEdgeWeight(self, topLeft, bottomRight): if topLeft.column() == 4: edges = self.__scene.singleItems(BezierEdge) for edge in edges: edge: BezierEdge if edge.textCp.toPlainText() == self.edgeModel.index( topLeft.row(), 0, QModelIndex()).data(): edge.weightCp.setPlainText(str(topLeft.data())) self.__scene.update() def do_updateNodeWeight(self, topLeft, bottomRight): if topLeft.column() == 3: nodes = self.__scene.singleItems(BezierNode) for node in nodes: node: BezierNode if node.textCp.toPlainText() == self.nodeModel.index( topLeft.row(), 0, QModelIndex()).data(): node.weightCp.setPlainText(str(topLeft.data())) self.__scene.update() def do_ShowSelectPath(self, pathList: list): self.__scene.clearSelection() items = self.__scene.uniqueItems() for item in items: if item.textCp.toPlainText() in pathList: item.setSelected(True) def do_checkIsHasItems(self, num): if num: self.ui.actionSave.setEnabled(True) else: self.ui.actionSave.setEnabled(False)
class MainWindow ( QtGui.QMainWindow ) : # # __init__ # def __init__ ( self ) : # QtGui.QMainWindow.__init__ ( self ) self.ui = Ui_MainWindow () self.ui.setupUi ( self ) # # setup WhatsThis help action # self.ui.actionHelpMode = QtGui.QWhatsThis.createAction ( ) self.ui.actionHelpMode.setToolTip ( 'Enter "WhatsThis" help mode' ) self.ui.menuHelp.addAction ( self.ui.actionHelpMode ) self.ui.toolBar.addSeparator() self.ui.toolBar.addAction ( self.ui.actionHelpMode ) QtCore.QObject.connect ( self.ui.actionHelpMode, QtCore.SIGNAL ( 'toggled(bool)' ), self.onHelpMode ) self.clipboard = QtGui.QApplication.clipboard () self.recentProjects = app_settings.value ( 'RecentProjects' ).toStringList () self.recentNetworks = app_settings.value ( 'RecentNetworks' ).toStringList () self.addRecentProject ( app_global_vars [ 'ProjectPath' ] ) self.setupMenuBar () self.setupPanels () self.activeNodeList = None self.workArea = None # current work area self.onNew () # create new document grid_enabled = getDefaultValue ( app_settings, 'WorkArea', 'grid_enabled' ) grid_snap = getDefaultValue ( app_settings, 'WorkArea', 'grid_snap' ) grid_size = int ( getDefaultValue ( app_settings, 'WorkArea', 'grid_size' ) ) reverse_flow = getDefaultValue ( app_settings, 'WorkArea', 'reverse_flow' ) straight_links = getDefaultValue ( app_settings, 'WorkArea', 'straight_links' ) #self.ui.workArea.gridSize = grid_size #self.ui.workArea.gridSnap = grid_snap self.workArea.drawGrid = grid_enabled #self.ui.workArea.reverseFlow = reverse_flow #self.ui.workArea.straightLinks = straight_links self.ui.actionShowGrid.setChecked ( grid_enabled ) self.ui.actionSnapGrid.setChecked ( grid_snap ) self.ui.actionReverseFlow.setChecked ( reverse_flow ) self.ui.actionStraightLinks.setChecked ( straight_links ) self.ui.nodeList_ctl.setLibrary ( app_global_vars [ 'NodesPath' ] ) self.ui.project_ctl.setLibrary ( app_global_vars [ 'ProjectNetworks' ] ) #self.ui.dockNodes.setWindowTitle ( 'Library: %s' % app_global_vars [ 'NodesPath' ] ) #self.ui.dockProject.setWindowTitle ( 'Project: %s' % app_global_vars [ 'ProjectNetworks' ] ) QtCore.QObject.connect ( self.ui.nodeList_ctl.ui.nodeList, QtCore.SIGNAL ( 'setActiveNodeList' ), self.setActiveNodeList ) QtCore.QObject.connect ( self.ui.project_ctl.ui.nodeList, QtCore.SIGNAL ( 'setActiveNodeList' ), self.setActiveNodeList ) QtCore.QObject.connect ( self.ui.tabs, QtCore.SIGNAL ( 'currentChanged(int)' ), self.onTabSelected ) QtCore.QObject.connect ( self.ui.tabs, QtCore.SIGNAL ( 'tabCloseRequested(int)' ), self.onTabCloseRequested ) QtCore.QObject.connect ( self.ui.nodeParam_ctl, QtCore.SIGNAL ( 'nodeLabelChanged' ), self.onNodeLabelChanged ) QtCore.QObject.connect ( self.ui.nodeParam_ctl, QtCore.SIGNAL ( 'nodeParamChanged' ), self.onNodeParamChanged ) self.setupActions () self.setupWindowTitle () # # connectWorkAreaSignals # def connectWorkAreaSignals ( self ) : # if self.workArea != None : if self.activeNodeList != None : QtCore.QObject.connect ( self.activeNodeList, QtCore.SIGNAL ( 'addNode' ), self.workArea.insertNodeNet ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL ( 'selectNodes' ), self.onSelectGfxNodes ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL ( 'nodeConnectionChanged' ), self.onGfxNodeParamChanged ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL ( 'gfxNodeAdded' ), self.onAddGfxNode ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL ( 'gfxNodeRemoved' ), self.onRemoveGfxNode ) #QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL ( 'editGfxNode' ), self.editGfxNode ) QtCore.QObject.connect ( self.workArea.scene(), QtCore.SIGNAL ( 'nodeUpdated' ), self.updateNodeParamView ) QtCore.QObject.connect ( self.workArea.scene(), QtCore.SIGNAL ( 'gfxNodeParamChanged' ), self.onGfxNodeParamChanged ) # # disconnectWorkAreaSignals # def disconnectWorkAreaSignals ( self ) : # if self.workArea != None : if self.activeNodeList != None : QtCore.QObject.disconnect ( self.activeNodeList, QtCore.SIGNAL ( 'addNode' ), self.workArea.insertNodeNet ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL ( 'selectNodes' ), self.onSelectGfxNodes ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL ( 'nodeConnectionChanged' ), self.onGfxNodeParamChanged ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL ( 'gfxNodeAdded' ), self.onAddGfxNode ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL ( 'gfxNodeRemoved' ), self.onRemoveGfxNode ) #QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL ( 'editGfxNode' ), self.editGfxNode ) QtCore.QObject.disconnect ( self.workArea.scene(), QtCore.SIGNAL ( 'nodeUpdated' ), self.updateNodeParamView ) QtCore.QObject.disconnect ( self.workArea.scene(), QtCore.SIGNAL ( 'gfxNodeParamChanged' ), self.onGfxNodeParamChanged ) # # # def setupWindowTitle ( self ) : # self.setWindowTitle ( 'meShaderEd %s (%s) %s' % ( app_global_vars [ 'version' ], app_renderer.getCurrentPresetName(), app_global_vars [ 'ProjectPath' ] ) ) self.ui.dockNodes.setToolTip ( app_global_vars [ 'NodesPath' ] ) self.ui.dockNodes.setStatusTip ( app_global_vars [ 'NodesPath' ] ) self.ui.dockProject.setToolTip ( app_global_vars [ 'ProjectNetworks' ] ) self.ui.dockProject.setStatusTip ( app_global_vars [ 'ProjectNetworks' ] ) # # setupMenuBar # def setupMenuBar ( self ) : # override font for menu from Designer's settings to system default font = QtGui.QFont () if ( sys.platform == 'win32' ): # Runing on windows, override font sizes from Designer to default font.setPointSize ( 8 ) elif ( sys.platform == 'darwin' ): font.setPointSize ( 10 ) self.ui.menubar.setFont ( font ) self.ui.menuFile.setFont ( font ) self.ui.menuEdit.setFont ( font ) self.ui.menuCommand.setFont ( font ) self.ui.menuWindow.setFont ( font ) self.ui.menuHelp.setFont ( font ) self.buildRecentProjectsMenu () self.buildRecentNetworksMenu () # # buildRecentProjectsMenu # def buildRecentProjectsMenu ( self ) : #self.recentProjects = app_settings.value ( 'RecentProjects' ).toStringList () #self.recentNetworks = app_settings.value ( 'RecentNetworks' ).toStringList () self.ui.menuRecent_Projects.clear () if len ( self.recentProjects ) : icon = QtGui.QIcon.fromTheme ( 'folder', QtGui.QIcon ( ':/file_icons/resources/open.png' ) ) # QtGui.QIcon ( ':/file_icons/resources/recentFile.png' ) 'folder' for i, fname in enumerate ( self.recentProjects ) : # QtCore.QFileInfo ( fname ).fileName () action = QtGui.QAction ( icon, '&%d %s' % ( i + 1, fname ), self ) action.setData ( QtCore.QVariant ( fname ) ) self.connect ( action, QtCore.SIGNAL ( 'triggered()' ), self.onOpenRecentProject ) self.ui.menuRecent_Projects.addAction ( action ) # # buildRecentNetworksMenu # def buildRecentNetworksMenu ( self ) : # self.ui.menuRecent_Networks.clear () if len ( self.recentNetworks ) : for i, fname in enumerate ( self.recentNetworks ) : icon = QtGui.QIcon.fromTheme ( 'document-new', QtGui.QIcon ( ':/file_icons/resources/new.png' ) ) # QtCore.QFileInfo ( fname ).fileName () action = QtGui.QAction ( icon, '&%d %s' % ( i + 1, fname ), self ) action.setData ( QtCore.QVariant ( fname ) ) self.connect ( action, QtCore.SIGNAL ( 'triggered()' ), self.onOpenRecentNetwork ) self.ui.menuRecent_Networks.addAction ( action ) # # setupPanels # def setupPanels ( self ) : # self.tabifyDockWidget ( self.ui.dockNodes, self.ui.dockProject ) self.tabifyDockWidget ( self.ui.dockPreview, self.ui.dockGeom ) self.tabifyDockWidget ( self.ui.dockParam, self.ui.dockSwatch ) # temporary hide unused panels #self.removeDockWidget ( self.ui.dockGeom ) #self.removeDockWidget ( self.ui.dockSwatch ) self.ui.dockGeom.hide () self.ui.dockSwatch.hide () self.ui.dockNodes.raise_ () self.ui.dockPreview.raise_ () self.ui.dockParam.raise_ () #self.addDockWidget ( QtCore.Qt.DockWidgetArea ( 2 ), self.ui.dockParam ) #self.ui.dockParam.show () # # addRecentProject # def addRecentProject ( self, project ) : # if project is not None : recent_projects_max = getDefaultValue ( app_settings, '', 'recent_projects_max' ) if not self.recentProjects.contains ( project ) : self.recentProjects.prepend ( QtCore.QString ( project ) ) while self.recentProjects.count () > recent_projects_max : self.recentProjects.takeLast () recentProjects = QtCore.QVariant ( self.recentProjects ) if self.recentProjects else QtCore.QVariant () app_settings.setValue ( 'RecentProjects', recentProjects ) # # addRecentNetwork # def addRecentNetwork ( self, network ) : # if network is not None : recent_networks_max = getDefaultValue ( app_settings, '', 'recent_networks_max' ) if not self.recentNetworks.contains ( network ) : self.recentNetworks.prepend ( QtCore.QString ( network ) ) while self.recentNetworks.count () > recent_networks_max : self.recentNetworks.takeLast () recentNetworks = QtCore.QVariant ( self.recentNetworks ) if self.recentNetworks else QtCore.QVariant () app_settings.setValue ( 'RecentNetworks', recentNetworks ) # # setupActions # def setupActions ( self ) : # #if DEBUG_MODE : print '>> MainWindow.setupActions' numNodes = 0 numSelectedNodes = 0 numSelectedLinks = 0 selectedNodeType = None if self.workArea is not None : numNodes = len ( self.workArea.getAllGfxNodes () ) numSelectedNodes = len ( self.workArea.selectedNodes ) numSelectedLinks = len ( self.workArea.selectedLinks ) if numSelectedNodes == 1 : selectedNodeType = self.getSelectedNode ().node.type enableForPaste = False if self.clipboard.ownsClipboard () or (sys.platform == 'darwin'): if DEBUG_MODE : print '** self.clipboard.ownsClipboard' data = self.clipboard.mimeData () if data is not None : if data.hasText () : enableForPaste = True self.ui.actionExportShader.setEnabled ( selectedNodeType in VALID_RSL_SHADER_TYPES ) self.ui.actionViewComputedCode.setEnabled ( selectedNodeType in VALID_RSL_NODE_TYPES or selectedNodeType in VALID_RIB_NODE_TYPES ) self.ui.actionSaveSelected.setEnabled ( numSelectedNodes > 0 ) self.ui.actionSelectAll.setEnabled ( numNodes > 0 ) self.ui.actionSelectAbove.setEnabled ( numSelectedNodes == 1 ) self.ui.actionSelectBelow.setEnabled ( numSelectedNodes == 1 ) self.ui.actionDuplicate.setEnabled ( numSelectedNodes > 0 ) self.ui.actionDuplicateWithLinks.setEnabled ( numSelectedNodes > 0 ) self.ui.actionDelete.setEnabled ( ( numSelectedNodes > 0 ) or ( numSelectedLinks > 0 ) ) self.ui.actionCut.setEnabled ( numSelectedNodes > 0 ) self.ui.actionCopy.setEnabled ( numSelectedNodes > 0 ) self.ui.actionPaste.setEnabled ( enableForPaste ) self.ui.actionFitAll.setEnabled ( numNodes > 0 ) self.ui.actionFitSelected.setEnabled ( numSelectedNodes > 0 ) # # onProjectSetup # def onProjectSetup ( self ) : # if DEBUG_MODE : print ">> MainWindow.onProjectSetup" projectSetupDlg = ProjectSetup ( app_settings ) projectSetupDlg.exec_() self.ui.project_ctl.setLibrary ( app_global_vars [ 'ProjectNetworks' ] ) createDefaultProject ( app_settings ) self.setupWindowTitle () self.addRecentProject ( app_global_vars [ 'ProjectPath' ] ) self.buildRecentProjectsMenu () # # onSettingsSetup # def onSettingsSetup ( self ) : # if DEBUG_MODE : print '>> MainWindow.onSettingsSetup' settingsSetupDlg = SettingsSetup ( app_settings ) settingsSetupDlg.exec_() self.ui.nodeList_ctl.setLibrary ( app_global_vars [ 'NodesPath' ] ) # # onRenderSettings # def onRenderSettings ( self ) : # if DEBUG_MODE : print '>> MainWindow.onRenderSettings' renderSettingsDlg = meRendererSetup ( app_renderer ) QtCore.QObject.connect ( renderSettingsDlg, QtCore.SIGNAL ( 'presetChanged' ), self.onRenderPresetChanged ) QtCore.QObject.connect ( renderSettingsDlg, QtCore.SIGNAL ( 'savePreset' ), self.onRenderSavePreset ) renderSettingsDlg.exec_ () # # onRenderPresetChanged # def onRenderPresetChanged ( self ) : # presetName = app_renderer.getCurrentPresetName () if DEBUG_MODE : print '>> MainWindow.onRenderPresetChanged preset = %s' % presetName #self.setWindowTitle ( 'meShaderEd %s (%s) %s' % ( app_global_vars [ 'version' ], presetName, app_global_vars [ 'ProjectNetworks' ] ) ) app_settings.setValue ( 'defRenderer', presetName ) app_global_vars [ 'RendererPreset' ] = presetName app_global_vars [ 'Renderer' ] = app_renderer.getCurrentValue ( 'renderer', 'name' ) app_global_vars [ 'RendererFlags' ] = app_renderer.getCurrentValue ( 'renderer', 'flags' ) app_global_vars [ 'ShaderCompiler' ] = app_renderer.getCurrentValue ( 'shader', 'compiler' ) app_global_vars [ 'ShaderDefines' ] = app_renderer.getCurrentValue ( 'shader', 'defines' ) app_global_vars [ 'ShaderInfo' ] = app_renderer.getCurrentValue ( 'shader', 'sloinfo' ) app_global_vars [ 'TEX' ] = app_renderer.getCurrentValue ( 'texture', 'extension' ) app_global_vars [ 'SLO' ] = app_renderer.getCurrentValue ( 'shader', 'extension' ) app_global_vars [ 'TexMake' ] = app_renderer.getCurrentValue ( 'texture', 'texmake' ) self.setupWindowTitle () # # onRenderSavePreset # def onRenderSavePreset ( self ) : # if DEBUG_MODE : print '>> MainWindow.onRenderSavePreset preset = %s' % app_renderer.getCurrentPresetName() app_renderer.saveSettings () # # onShowGrid # def onShowGrid ( self, check ) : # self.workArea.drawGrid = bool ( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'grid_enabled', bool ( check ) ) app_settings.endGroup () self.workArea.resetCachedContent () #self.ui.workArea.update() # # onSnapGrid # def onSnapGrid ( self, check ) : # self.workArea.gridSnap = bool ( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'grid_snap', bool ( check ) ) app_settings.endGroup () # # onReverseFlow # def onReverseFlow ( self, check ) : # self.workArea.reverseFlow = bool ( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'reverse_flow', bool ( check ) ) app_settings.endGroup () #self.ui.workArea.resetCachedContent() # # onStraightLinks # def onStraightLinks ( self, check ) : # self.workArea.straightLinks = bool ( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'straight_links', bool ( check ) ) app_settings.endGroup () self.workArea.resetCachedContent () self.workArea.adjustLinks () # # setActiveNodeList # def setActiveNodeList ( self, nodeList ) : # if DEBUG_MODE : print '>> MainWindow.setActiveNodeList' if self.activeNodeList != None : QtCore.QObject.disconnect ( self.activeNodeList, QtCore.SIGNAL ( 'addNode' ), self.workArea.insertNodeNet ) self.activeNodeList = nodeList QtCore.QObject.connect ( self.activeNodeList, QtCore.SIGNAL ( 'addNode' ), self.workArea.insertNodeNet ) # # onGetNode # # Called by WorkArea after drag&drop event # Here we choose selected nodeList panel (Library or Project) # for processing node request # def onGetNode ( self, itemFilename, pos ) : # if self.activeNodeList != None : self.activeNodeList.onGetNode ( itemFilename, pos ) # # onAddGfxNode # def onAddGfxNode ( self, gfxNode ) : # #print ">> MainWindow: onAddGfxNode = %s" % gfxNode.node.label if gfxNode.node.type == 'image' : self.ui.imageView_ctl.addViewer ( gfxNode ) #if self.ui.nodeParam_ctl.receivers( QtCore.SIGNAL( 'onNodeParamChanged(QObject,QObject)' ) ) == 0 : # QtCore.QObject.connect( self.ui.nodeParam_ctl, QtCore.SIGNAL( 'onNodeParamChanged(QObject,QObject)' ), self.ui.imageView_ctl.onNodeParamChanged ) #else : # print ">> MainWindow: nodeParam_ctl onNodeParamChanged already connected to imageView_ctl" # # onRemoveGfxNode # def onRemoveGfxNode ( self, gfxNode ) : # if DEBUG_MODE : print '>> MainWindow.onRemoveGfxNode = %s' % gfxNode.node.label if gfxNode.node.type == 'image' : self.ui.imageView_ctl.removeViewer ( gfxNode ) #QtCore.QObject.disconnect ( self.ui.nodeParam_ctl, QtCore.SIGNAL ( 'onNodeParamChanged(QObject,QObject)' ), self.ui.imageView_ctl.onNodeParamChanged ) # # getSelectedNode # def getSelectedNode ( self ) : return self.workArea.selectedNodes [0] # # onRenderPreview # def onRenderPreview ( self ) : print ">> MainWindow.onRenderPreview (not implemented yet...)" # # onShowSwatch # def onShowSwatch ( self ) : print ">> MainWindow.onShowSwatch (not implemented yet...)" # # onHideSwatch # def onHideSwatch ( self ) : print ">> MainWindow.onHideSwatch (not implemented yet...)" # # onCreateNode # def onCreateNode ( self ) : print ">> MainWindow.onCreateNode (not implemented yet...)" # # onExportShader # def onExportShader ( self ) : # if DEBUG_MODE : print ">> MainWindow.onExportShader" gfxNode = self.getSelectedNode () exportShaderDlg = ExportShaderDialog ( gfxNode.node ) exportShaderDlg.exec_ () if exportShaderDlg.ui.chk_save_changes.isChecked () : if DEBUG_MODE : print '>> MainWindow.exportShaderDlg save changes' gfxNode.updateGfxNode ( removeLinks = False ) self.workArea.updateBelow ( gfxNode ) self.updateNodeParamView () self.workArea.scene().update () # # onViewComputedCode # def onViewComputedCode ( self ) : ViewComputedCodeDialog ( self.getSelectedNode ().node ).exec_ () # # onEditNode # def onEditNode ( self ) : # if DEBUG_MODE : print ">> MainWindow.onEditNode" gfxNode = self.getSelectedNode () editNode = gfxNode.node.copy () dupNodeNet = NodeNetwork ( 'duplicate' ) dupNodeNet.addNode ( editNode ) # # copy input links to new node # if DEBUG_MODE : print '** duplicate input links ...' for link in gfxNode.node.getInputLinks () : newLink = link.copy () newParam = editNode.getInputParamByName ( link.dstParam.name ) newLink.setDst ( editNode, newParam ) dupNodeNet.addLink ( newLink ) newLink.printInfo () # # copy output links to new node # if DEBUG_MODE : print '** duplicate output links ...' for link in gfxNode.node.getOutputLinks () : newLink = link.copy () newParam = editNode.getOutputParamByName ( link.srcParam.name ) newLink.setSrc ( editNode, newParam ) dupNodeNet.addLink ( newLink ) newLink.printInfo () nodeEditDlg = NodeEditorDialog ( editNode ) if nodeEditDlg.exec_ () == QtGui.QDialog.Accepted : # if DEBUG_MODE : print '>> MainWindow.nodeEditDlg Accepted' # # remove original node with links ( inputLinksToRemove, outputLinksToRemove ) = self.workArea.nodeNet.removeNode ( gfxNode.node ) for link in inputLinksToRemove : self.workArea.nodeNet.removeLink ( link ) for link in outputLinksToRemove : self.workArea.nodeNet.removeLink ( link ) # add duplicate network to current node net self.workArea.nodeNet.add ( dupNodeNet ) if gfxNode.node.label != editNode.label : self.ui.imageView_ctl.onNodeLabelChanged ( gfxNode, editNode.label ) # set new node to gfxNode.node gfxNode.node = editNode gfxNode.updateGfxNode () for link in editNode.getInputLinks () : self.workArea.addGfxLink ( link ) for link in editNode.getOutputLinks () : self.workArea.addGfxLink ( link ) self.updateNodeParamView () self.workArea.scene().update () else : # remove duplicate node network dupNodeNet.clear () # # onDelete # def onDelete ( self ) : # selected = self.workArea.scene ().selectedItems () if len ( selected ) : self.workArea.removeSelected () else : self.ui.imageView_ctl.removeAllViewers () self.workArea.clear() # # onSelectAll # def onSelectAll ( self ) : self.workArea.selectAllNodes () # # onSelectAbove # def onSelectAbove ( self ) : self.workArea.selectAbove ( self.getSelectedNode () ) # # onSelectBelow # def onSelectBelow ( self ) : self.workArea.selectBelow ( self.getSelectedNode () ) # # onCopy # def onCopy ( self ) : if DEBUG_MODE : print '>> MainWindow.onCopy' self.workArea.copyNodes ( self.clipboard, cutNodes = False ) self.setupActions () # # onCut # def onCut ( self ) : if DEBUG_MODE : print '>> MainWindow.onCut' self.workArea.copyNodes ( self.clipboard, cutNodes = True ) self.setupActions () # # onPaste # def onPaste ( self ) : if DEBUG_MODE : print '>> MainWindow.onPaste' self.workArea.pasteNodes ( self.clipboard ) # # onDuplicate # def onDuplicate ( self ) : self.workArea.duplicateNodes ( preserveLinks = False ) # # onDuplicateWithLinks # def onDuplicateWithLinks ( self ) : self.workArea.duplicateNodes ( preserveLinks = True ) # # onSelectGfxNodes # def onSelectGfxNodes ( self, gfxNodes = [], gfxLinks = [] ) : # self.setupActions () self.workArea.inspectedNode = None if len ( gfxNodes ) == 1 : self.workArea.inspectedNode = gfxNodes[ 0 ] self.ui.nodeParam_ctl.setNode ( self.workArea.inspectedNode ) # # onNodeLabelChanged # def onNodeLabelChanged ( self, gfxNode, newLabel ) : # self.workArea.nodeNet.renameNodeLabel ( gfxNode.node, newLabel ) gfxNode.updateNodeLabel () self.ui.imageView_ctl.onNodeLabelChanged ( gfxNode, newLabel ) self.workArea.scene ().update () # # onNodeParamChanged # def onNodeParamChanged ( self, gfxNode, param ) : # if DEBUG_MODE : print ">> MainWindow.onNodeParamChanged" #param.shaderParam = not gfxNode.node.isInputParamLinked ( param ) # from WorkArea we have GfxNode in signal nodeConnectionChanged # hence need to update nodeParam_ctl if isinstance ( gfxNode, GfxNote ) : #if DEBUG_MODE : print "* update GfxNote" gfxNode.updateGfxNode () #node.update () self.workArea.scene ().update () elif isinstance ( gfxNode, GfxSwatchNode ) : if DEBUG_MODE : print "* update GfxSwatchNode" gfxNode.setupSwatchParams () gfxNode.setupGeometry () gfxNode.adjustLinks () self.workArea.scene ().update () elif isinstance ( gfxNode, GfxNode ) : if DEBUG_MODE : print "* update GfxNode" gfxNode.updateGfxNode ( removeLinks = False ) self.updateNodeParamView () if self.ui.imageView_ctl.autoUpdate () : self.ui.imageView_ctl.updateViewer() # # onGxNodeParamChanged # def onGfxNodeParamChanged ( self, gfxNode, param = None ) : # if DEBUG_MODE : print ">> MainWindow.onGxNodeParamChanged" # from WorkArea we have GfxNode in signal nodeConnectionChanged # hence need to update nodeParam_ctl if isinstance ( gfxNode, GfxNode ) or isinstance ( gfxNode, GfxSwatchNode ) : #if DEBUG_MODE : print "* update nodeView" # gfxNode.updateInputParams () self.updateNodeParamView () self.workArea.scene ().update () if self.ui.imageView_ctl.autoUpdate () : self.ui.imageView_ctl.updateViewer() # # updateNodeParamView # def updateNodeParamView ( self, gfxNode = None ) : # if DEBUG_MODE : print '>> MainWindow.updateNodeParamView' if gfxNode is not None : print '** gfxNode = "%s"' % gfxNode.node.label self.ui.nodeParam_ctl.disconnectParamSignals () self.ui.nodeParam_ctl.connectParamSignals () self.ui.nodeParam_ctl.updateGui () # # onFitAll # def onFitAll ( self ) : self.workArea.fitGfxNodesInView ( self.workArea.getAllGfxNodes () ) # # onFitSelected # def onFitSelected ( self ) : self.workArea.fitGfxNodesInView ( self.workArea.selectedNodes ) # # onZoomReset # def onZoomReset ( self ) : self.workArea.resetZoom () # # onNewParamView # def onNewParamView ( self ) : print ">> MainWindow.onNewParamView (not implemented yet...)" # # onTabSelected # def onTabSelected ( self, idx ) : # if DEBUG_MODE : print '>> MainWindow.onTabSelected (%d)' % idx self.disconnectWorkAreaSignals () self.ui.imageView_ctl.removeAllViewers () self.workArea = self.ui.tabs.currentWidget () imageNodes = self.workArea.getGfxNodesByType ( 'image' ) # setup imageView menu for image nodes in new tab for gfxNode in imageNodes : self.ui.imageView_ctl.addViewer ( gfxNode ) self.connectWorkAreaSignals () self.ui.nodeParam_ctl.setNode ( self.workArea.inspectedNode ) self.workArea.adjustLinks () # # onTabCloseRequested # def onTabCloseRequested ( self, idx ) : # if DEBUG_MODE : print '>> MainWindow: onTabCloseRequested (%d)' % idx if self.ui.tabs.count () > 1 : self.workArea.nodeNet.clear () self.ui.tabs.removeTab ( idx ) # # onNew # def onNew ( self, tabName = 'untitled' ) : # def tabNameExists ( self, name ) : ret = False for i in range ( 0, self.ui.tabs.count () ) : if name == str ( self.ui.tabs.tabText ( i ) ): ret = True break return ret newName = tabName if DEBUG_MODE : print '-> self.ui.tabs.count() = %d ' % self.ui.tabs.count () if self.workArea != None : if DEBUG_MODE : print '-> create new WorkArea widget' # set unique new name name = newName i = 0 while True : if tabNameExists ( self, name ) : name = newName + str ( i ) i += 1 continue else : break newName = name workArea = WorkArea () # create new WorkArea instance newTab = self.ui.tabs.addTab ( workArea, newName ) else : if DEBUG_MODE : print '-> use initial WorkArea widget' workArea = self.ui.workArea # use initial WorkArea widget self.workArea = workArea self.connectWorkAreaSignals () nodeNet = NodeNetwork ( newName ) workArea.setNodeNetwork ( nodeNet ) self.ui.tabs.setTabText ( self.ui.tabs.indexOf ( workArea ), newName ) self.ui.tabs.setCurrentIndex ( self.ui.tabs.indexOf ( workArea ) ) # # onOpen # def onOpen ( self ) : # if DEBUG_MODE : print ">> MainWindow.onOpen" # curDir = app_global_vars [ 'ProjectNetworks' ] typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str ( QtGui.QFileDialog.getOpenFileName ( self, "Open file", curDir, typeFilter ) ) if filename != '' : if self.openNetwork ( filename ) : self.addRecentNetwork ( normPath ( filename ) ) self.buildRecentNetworksMenu () # # openNetwork # def openNetwork ( self, filename ) : # ret = True if DEBUG_MODE : print "-> open file %s" % filename if QtCore.QFile.exists ( filename ) : ( name, ext ) = os.path.splitext ( os.path.basename ( filename ) ) self.ui.imageView_ctl.removeAllViewers () self.workArea.clear () self.workArea.nodeNet.name = name self.workArea.nodeNet.fileName = '' self.ui.tabs.setTabText ( self.ui.tabs.indexOf ( self.workArea ), name ) self.workArea.openNodeNet ( normPath ( filename ) ) else : print "ERROR! filename %s doesn't exist" % filename ret = False return ret # # onOpenRecentNetwork # def onOpenRecentNetwork ( self ) : # action = self.sender () if isinstance ( action, QtGui.QAction ): network = unicode ( action.data ().toString () ) if network is not None : if DEBUG_MODE : print '>> onOpenRecentNetwork : %s' % network if not self.openNetwork ( network ) : # TODO!!! remove network from rescentNetworks pass # # onOpenRecentProject # def onOpenRecentProject ( self ) : # action = self.sender () if isinstance ( action, QtGui.QAction ): project = unicode ( action.data ().toString () ) if project is not None : print '>> onOpenRecentProject : %s' % project if openDefaultProject ( app_settings, app_global_vars, project ) : # very strange... app_settings doesn't update inside meCommon.openDefaultProject... # though app_global_vars does # have to duplicate this action here... app_settings.setValue ( 'project', app_global_vars [ 'ProjectPath' ] ) app_settings.setValue ( 'project_shaders', app_global_vars [ 'ProjectShaders' ] ) app_settings.setValue ( 'project_textures', app_global_vars [ 'ProjectTextures' ] ) app_settings.setValue ( 'shader_networks', app_global_vars [ 'ProjectNetworks' ] ) app_settings.setValue ( 'shader_sources', app_global_vars [ 'ProjectSources' ] ) self.ui.project_ctl.setLibrary ( app_global_vars [ 'ProjectNetworks' ] ) self.setupWindowTitle () else : print "ERROR! project %s doesn't exist" % project # TODO!!! remove project from rescentProjects # # onImport # def onImport ( self ) : # if DEBUG_MODE : print ">> MainWindow.onImport" # curDir = app_global_vars [ 'ProjectNetworks' ] typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str ( QtGui.QFileDialog.getOpenFileName ( self, "Import file", curDir, typeFilter ) ) if filename != '' : if DEBUG_MODE : print "-> import file %s" % filename self.workArea.insertNodeNet ( normPath ( filename ) ) # # onSaveSelected # def onSaveSelected ( self ) : # if DEBUG_MODE : print ">> MainWindow.onSaveSelected" singleNode = ( len ( self.workArea.selectedNodes ) == 1 ) curDir = app_global_vars [ 'ProjectNetworks' ] saveName = os.path.join ( curDir, self.workArea.nodeNet.name + '.xml' ) typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str( QtGui.QFileDialog.getSaveFileName ( self, "Save file as", saveName, typeFilter ) ) if filename != '' : if DEBUG_MODE : print '-> save file As %s' % filename ( name, ext ) = os.path.splitext ( os.path.basename ( filename ) ) if singleNode : # save single node print '*** save as single Node' gfxNode = self.getSelectedNode () saveNode = gfxNode.node.copy () saveNode.name = name saveNode.master = normPath ( filename ) saveNode.save () else : # save selected as network print '*** save as nodenet' saveNodeNet = self.workArea.nodeNetFromSelected ( name ) saveNodeNet.fileName = normPath ( filename ) saveNodeNet.save () # # onSave # def onSave ( self ) : # if DEBUG_MODE : print ">> MainWindow.onSave" # if file is new -- use onSaveAs function # curDir = app_global_vars [ 'ProjectNetworks' ] if self.workArea.nodeNet.fileName == '' : self.onSaveAs () else : if DEBUG_MODE : print '-> save file %s' % self.workArea.nodeNet.fileName self.workArea.nodeNet.save () # # onSaveAs # def onSaveAs ( self ) : # if DEBUG_MODE : print ">> MainWindow.onSaveAs" # curDir = app_global_vars [ 'ProjectNetworks' ] saveName = os.path.join ( curDir, self.workArea.nodeNet.name + '.xml' ) typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str( QtGui.QFileDialog.getSaveFileName ( self, "Save file as", saveName, typeFilter ) ) if filename != '' : if DEBUG_MODE : print '-> save file As %s' % filename ( name, ext ) = os.path.splitext ( os.path.basename ( filename ) ) self.workArea.nodeNet.fileName = normPath ( filename ) self.workArea.nodeNet.name = name self.ui.tabs.setTabText ( self.ui.tabs.indexOf ( self.workArea ), name ) self.workArea.nodeNet.save () self.addRecentNetwork ( normPath ( filename ) ) self.buildRecentNetworksMenu () self.ui.project_ctl.onReload () # # onHelpNode # def onHelpMode ( self, showWhatsThis ) : # #if showWhatsThis : QtGui.QWhatsThis.enterWhatsThisMode ()
class MainWindow(QtGui.QMainWindow): """ Class of Main Window (top) """ def __init__(self, parent=None): """ Initialization and set up """ # Base class QtGui.QMainWindow.__init__(self,parent) # UI Window (from Qt Designer) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Make UI scrollable self._scrollbars = MantidQt.API.WidgetScrollbarDecorator(self) self._scrollbars.setEnabled(True) # Must follow after setupUi(self)! # Mantid configuration self._instrument = str(self.ui.comboBox_instrument.currentText()) # config = ConfigService.Instance() # self._instrument = config["default.instrument"] # Event handling definitions # Top self.connect(self.ui.pushButton_setExp, QtCore.SIGNAL('clicked()'), self.do_set_experiment) # Tab 'Data Access' self.connect(self.ui.pushButton_applySetup, QtCore.SIGNAL('clicked()'), self.do_apply_setup) self.connect(self.ui.pushButton_browseLocalDataDir, QtCore.SIGNAL('clicked()'), self.do_browse_local_spice_data) self.connect(self.ui.pushButton_testURLs, QtCore.SIGNAL('clicked()'), self.do_test_url) self.connect(self.ui.pushButton_ListScans, QtCore.SIGNAL('clicked()'), self.do_list_scans) self.connect(self.ui.pushButton_downloadExpData, QtCore.SIGNAL('clicked()'), self.do_download_spice_data) self.connect(self.ui.comboBox_mode, QtCore.SIGNAL('currentIndexChanged(int)'), self.change_data_access_mode) # Tab 'View Raw Data' self.connect(self.ui.pushButton_setScanInfo, QtCore.SIGNAL('clicked()'), self.do_load_scan_info) self.connect(self.ui.pushButton_plotRawPt, QtCore.SIGNAL('clicked()'), self.do_plot_pt_raw) self.connect(self.ui.pushButton_prevPtNumber, QtCore.SIGNAL('clicked()'), self.do_plot_prev_pt_raw) self.connect(self.ui.pushButton_nextPtNumber, QtCore.SIGNAL('clicked()'), self.do_plot_next_pt_raw) self.connect(self.ui.pushButton_showPtList, QtCore.SIGNAL('clicked()'), self.show_scan_pt_list) self.connect(self.ui.pushButton_usePt4UB, QtCore.SIGNAL('clicked()'), self.do_add_peak_to_find) # Tab 'calculate ub matrix' self.connect(self.ui.pushButton_findPeak, QtCore.SIGNAL('clicked()'), self.do_find_peak) self.connect(self.ui.pushButton_addPeakToCalUB, QtCore.SIGNAL('clicked()'), self.do_add_ub_peak) self.connect(self.ui.pushButton_calUB, QtCore.SIGNAL('clicked()'), self.do_cal_ub_matrix) self.connect(self.ui.pushButton_acceptUB, QtCore.SIGNAL('clicked()'), self.doAcceptCalUB) self.connect(self.ui.pushButton_indexUBPeaks, QtCore.SIGNAL('clicked()'), self.do_index_ub_peaks) self.connect(self.ui.pushButton_deleteUBPeak, QtCore.SIGNAL('clicked()'), self.do_del_ub_peaks) self.connect(self.ui.pushButton_clearUBPeakTable, QtCore.SIGNAL('clicked()'), self.do_clear_ub_peaks) self.connect(self.ui.pushButton_resetPeakHKLs, QtCore.SIGNAL('clicked()'), self.do_reset_ub_peaks_hkl) # Tab 'Slice View' self.connect(self.ui.pushButton_setUBSliceView, QtCore.SIGNAL('clicked()'), self.do_set_ub_sv) self.connect(self.ui.pushButton_process4SliceView, QtCore.SIGNAL('clicked()'), self.do_merge_scans) # Tab 'Advanced' self.connect(self.ui.pushButton_useDefaultDir, QtCore.SIGNAL('clicked()'), self.do_setup_dir_default) self.connect(self.ui.pushButton_browseLocalCache, QtCore.SIGNAL('clicked()'), self.do_browse_local_cache_dir) self.connect(self.ui.pushButton_browseWorkDir, QtCore.SIGNAL('clicked()'), self.do_browse_working_dir) self.connect(self.ui.comboBox_instrument, QtCore.SIGNAL('currentIndexChanged(int)'), self.change_instrument_name) # Refine UB matrix self.connect(self.ui.pushButton_addToRefine, QtCore.SIGNAL('clicked()'), self.do_refine_ub) self.connect(self.ui.pushButton_addAllRefineUB, QtCore.SIGNAL('clicked()'), self.do_refine_ub) self.connect(self.ui.pushButton_acceptRefinedUB, QtCore.SIGNAL('clicked()'), self.do_refine_ub) self.connect(self.ui.pushButton_resetRefinedUB, QtCore.SIGNAL('clicked()'), self.do_refine_ub) # Tab 'Integrate Peaks' self.connect(self.ui.pushButton_integratePeak, QtCore.SIGNAL('clicked()'), self.do_integrate_peaks) # Menu self.connect(self.ui.actionExit, QtCore.SIGNAL('triggered()'), self.menu_quit) self.connect(self.ui.actionSave_Session, QtCore.SIGNAL('triggered()'), self.save_current_session) self.connect(self.ui.actionLoad_Session, QtCore.SIGNAL('triggered()'), self.load_session) # Event handling for tab 'refine ub matrix' self.connect(self.ui.pushButton_addToRefine, QtCore.SIGNAL('clicked()'), self.doAddScanPtToRefineUB) # Validator ... (NEXT) # Declaration of class variable # some configuration self._homeSrcDir = os.getcwd() self._homeDir = os.getcwd() # Control self._myControl = r4c.CWSCDReductionControl(self._instrument) self._allowDownload = True self._dataAccessMode = 'Download' # Initial setup self.ui.tabWidget.setCurrentIndex(0) self.ui.tabWidget.setTabEnabled(4, False) self.ui.tabWidget.setTabEnabled(5, False) self._init_ub_table() self.ui.radioButton_ubFromTab1.setChecked(True) # Tab 'Access' self.ui.lineEdit_url.setText('http://neutron.ornl.gov/user_data/hb3a/') self.ui.comboBox_mode.setCurrentIndex(0) self.ui.lineEdit_localSpiceDir.setEnabled(True) self.ui.pushButton_browseLocalDataDir.setEnabled(True) return def do_integrate_peaks(self): """ :return: """ raise RuntimeError('ASAP') def do_refine_ub(self): """ :return: """ raise RuntimeError('Next Release') def _init_ub_table(self): """ DOC :return: """ # UB-peak table # NOTE: have to call this because pyqt set column and row to 0 after __init__ # thus a 2-step initialization has to been adopted self.ui.tableWidget_peaksCalUB.setup() self.ui.tableWidget_ubMatrix.setup() self.ui.tableWidget_ubSiceView.setup() self.ui.tableWidget_refinedUB.setup() self.ui.tableWidget_sliceViewProgress.setup() return def change_data_access_mode(self): """ Change data access mode between downloading from server and local Event handling methods :return: """ new_mode = str(self.ui.comboBox_mode.currentText()) self._dataAccessMode = new_mode if new_mode.startswith('Local') is True: self.ui.lineEdit_localSpiceDir.setEnabled(True) self.ui.pushButton_browseLocalDataDir.setEnabled(True) self.ui.lineEdit_url.setEnabled(False) self.ui.lineEdit_localSrcDir.setEnabled(False) self.ui.pushButton_browseLocalCache.setEnabled(False) self._allowDownload = False else: self.ui.lineEdit_localSpiceDir.setEnabled(False) self.ui.pushButton_browseLocalDataDir.setEnabled(False) self.ui.lineEdit_url.setEnabled(True) self.ui.lineEdit_localSrcDir.setEnabled(True) self.ui.pushButton_browseLocalCache.setEnabled(True) self._allowDownload = True return def change_instrument_name(self): """ Handing the event as the instrument name is changed :return: """ new_instrument = str(self.ui.comboBox_instrument.currentText()) self.pop_one_button_dialog('Change of instrument during data processing is dangerous.') status, error_message = self._myControl.set_instrument_name(new_instrument) if status is False: self.pop_one_button_dialog(error_message) return def do_add_ub_peak(self): """ Add current to ub peaks :return: """ # Add peak status, int_list = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_scanNumber, self.ui.lineEdit_ptNumber]) if status is False: self.pop_one_button_dialog(int_list) exp_no, scan_no, pt_no = int_list # Get HKL from GUI status, float_list = gutil.parse_float_editors([self.ui.lineEdit_H, self.ui.lineEdit_K, self.ui.lineEdit_L]) if status is False: err_msg = float_list self.pop_one_button_dialog(err_msg) return h, k, l = float_list status, peak_info_obj = self._myControl.get_peak_info(exp_no, scan_no, pt_no) if status is False: error_message = peak_info_obj self.pop_one_button_dialog(error_message) return assert isinstance(peak_info_obj, r4c.PeakInfo) if self.ui.checkBox_roundHKLInt.isChecked(): h = math.copysign(1, h)*int(abs(h)+0.5) k = math.copysign(1, k)*int(abs(k)+0.5) l = math.copysign(1, l)*int(abs(l)+0.5) peak_info_obj.set_user_hkl(h, k, l) self.set_ub_peak_table(peak_info_obj) # Clear self.ui.lineEdit_scanNumber.setText('') self.ui.lineEdit_ptNumber.setText('') self.ui.lineEdit_sampleQx.setText('') self.ui.lineEdit_sampleQy.setText('') self.ui.lineEdit_sampleQz.setText('') self.ui.lineEdit_H.setText('') self.ui.lineEdit_K.setText('') self.ui.lineEdit_L.setText('') return def doAcceptCalUB(self): """ Accept the calculated UB matrix """ raise RuntimeError('ASAP') return def doAddScanPtToRefineUB(self): """ Add scan/pt numbers to the list of data points for refining ub matrix And the added scan number and pt numbers will be reflected in the (left sidebar) """ raise RuntimeError("ASAP") def do_add_peak_to_find(self): """ Add the scan/pt to the next :return: """ scan_no = self.ui.lineEdit_run.text() pt_no = self.ui.lineEdit_rawDataPtNo.text() self.ui.lineEdit_scanNumber.setText(scan_no) self.ui.lineEdit_ptNumber.setText(pt_no) self.ui.tabWidget.setCurrentIndex(2) def do_browse_local_cache_dir(self): """ Browse local cache directory :return: """ local_cache_dir = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Local Cache Directory', self._homeSrcDir)) # Set local directory to control status, error_message = self._myControl.set_local_data_dir(local_cache_dir) if status is False: self.pop_one_button_dialog(error_message) return # Synchronize to local data/spice directory and local cache directory if str(self.ui.lineEdit_localSpiceDir.text()) != '': prev_dir = str(self.ui.lineEdit_localSrcDir.text()) self.pop_one_button_dialog('Local data directory was set up as %s' % prev_dir) self.ui.lineEdit_localSrcDir.setText(local_cache_dir) self.ui.lineEdit_localSpiceDir.setText(local_cache_dir) return def do_browse_local_spice_data(self): """ Browse local source SPICE data directory """ src_spice_dir = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Directory', self._homeSrcDir)) # Set local data directory to controller status, error_message = self._myControl.set_local_data_dir(src_spice_dir) if status is False: self.pop_one_button_dialog(error_message) return self._homeSrcDir = src_spice_dir self.ui.lineEdit_localSpiceDir.setText(src_spice_dir) return def do_browse_working_dir(self): """ Browse and set up working directory :return: """ work_dir = str(QtGui.QFileDialog.getExistingDirectory(self, 'Get Working Directory', self._homeDir)) status, error_message = self._myControl.set_working_directory(work_dir) if status is False: self.pop_one_button_dialog(error_message) else: self.ui.lineEdit_workDir.setText(work_dir) return def do_cal_ub_matrix(self): """ Calculate UB matrix by 2 or 3 reflections """ # Get reflections num_rows = self.ui.tableWidget_peaksCalUB.rowCount() peak_info_list = list() status, exp_number = gutil.parse_integers_editors(self.ui.lineEdit_exp) for i_row in xrange(num_rows): if self.ui.tableWidget_peaksCalUB.is_selected(i_row) is True: scan_num, pt_num = self.ui.tableWidget_peaksCalUB.get_exp_info(i_row) status, peak_info = self._myControl.get_peak_info(exp_number, scan_num, pt_num) peak_info.set_peak_ws_hkl_from_user() if status is False: self.pop_one_button_dialog(peak_info) return assert isinstance(peak_info, r4c.PeakInfo) peak_info_list.append(peak_info) # END-FOR # Get lattice status, ret_obj = self._get_lattice_parameters() if status is True: a, b, c, alpha, beta, gamma = ret_obj else: err_msg = ret_obj self.pop_one_button_dialog(err_msg) return # Calculate UB matrix status, ub_matrix = self._myControl.calculate_ub_matrix(peak_info_list, a, b, c, alpha, beta, gamma) # Deal with result if status is True: self._show_ub_matrix(ub_matrix) else: err_msg = ub_matrix self.pop_one_button_dialog(err_msg) return def do_clear_ub_peaks(self): """ Clear all peaks in UB-Peak table :return: """ self.ui.tableWidget_peaksCalUB.clear() return def do_del_ub_peaks(self): """ Delete a peak in UB-Peak table :return: """ # Find out the lines to get deleted row_num_list = self.ui.tableWidget_peaksCalUB.get_selected_rows() print '[DB] Row %s are selected' % str(row_num_list) # Delete self.ui.tableWidget_peaksCalUB.delete_rows(row_num_list) return def do_download_spice_data(self): """ Download SPICE data :return: """ # Check scans to download scan_list_str = str(self.ui.lineEdit_downloadScans.text()) if len(scan_list_str) > 0: # user specifies scans to download valid, scan_list = fcutil.parse_int_array(scan_list_str) if valid is False: error_message = scan_list self.pop_one_button_dialog(error_message) else: # Get all scans status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp]) if status is False: self.pop_one_button_dialog(ret_obj) return exp_no = ret_obj assert isinstance(exp_no, int) server_url = str(self.ui.lineEdit_url.text()) scan_list = fcutil.get_scans_list(server_url, exp_no, return_list=True) self.pop_one_button_dialog('Going to download scans %s.' % str(scan_list)) # Check location destination_dir = str(self.ui.lineEdit_localSrcDir.text()) status, error_message = self._myControl.set_local_data_dir(destination_dir) if status is False: self.pop_one_button_dialog(error_message) else: self.pop_one_button_dialog('Spice files will be downloaded to %s.' % destination_dir) # Set up myControl for downloading data exp_no = int(self.ui.lineEdit_exp.text()) self._myControl.set_exp_number(exp_no) server_url = str(self.ui.lineEdit_url.text()) status, error_message = self._myControl.set_server_url(server_url) if status is False: self.pop_one_button_dialog(error_message) return # Download self._myControl.download_data_set(scan_list) return def do_find_peak(self): """ Find peak in a given scan/pt and record it """ # Get experiment, scan and pt status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_scanNumber, self.ui.lineEdit_ptNumber]) if status is True: exp_no, scan_no, pt_no = ret_obj else: self.pop_one_button_dialog(ret_obj) return # Find peak status, err_msg = self._myControl.find_peak(exp_no, scan_no, pt_no) if status is False: self.pop_one_button_dialog(ret_obj) return if self.ui.checkBox_loadHKLfromFile.isChecked() is True: # This is the first time that in the workflow to get HKL from MD workspace status, err_msg = self._myControl.set_hkl_to_peak(exp_no, scan_no, pt_no) if status is False: self.pop_one_button_dialog('Unable to locate peak info due to %s.' % err_msg) # Set up correct values to table tableWidget_peaksCalUB self._myControl.add_peak_info(exp_no, scan_no, pt_no) status, peak_info = self._myControl.get_peak_info(exp_no, scan_no, pt_no) if status is False: err_msg = peak_info raise KeyError(err_msg) assert isinstance(peak_info, r4c.PeakInfo) # Set the HKL value from PeakInfo directly # BAD PROGRAMMING! THERE ARE TOO MANY WAYS TO ACCESS STORED HKL h, k, l = peak_info.get_peak_ws_hkl() self.ui.lineEdit_H.setText('%.2f' % h) self.ui.lineEdit_K.setText('%.2f' % k) self.ui.lineEdit_L.setText('%.2f' % l) q_sample = peak_info.getQSample() self.ui.lineEdit_sampleQx.setText('%.5E' % q_sample[0]) self.ui.lineEdit_sampleQy.setText('%.5E' % q_sample[1]) self.ui.lineEdit_sampleQz.setText('%.5E' % q_sample[2]) # self.set_ub_peak_table(peak_info) return def do_index_ub_peaks(self): """ Index the peaks in the UB matrix peak table :return: """ # Get UB matrix ub_matrix = self.ui.tableWidget_ubMatrix.get_matrix() print '[DB] Get UB matrix ', ub_matrix # Do it for each peak num_peaks = self.ui.tableWidget_peaksCalUB.rowCount() err_msg = '' for i_peak in xrange(num_peaks): scan_no, pt_no = self.ui.tableWidget_peaksCalUB.get_exp_info(i_peak) status, ret_obj = self._myControl.index_peak(ub_matrix, scan_number=scan_no, pt_number=pt_no) if status is True: new_hkl = ret_obj[0] error = ret_obj[1] self.ui.tableWidget_peaksCalUB.set_hkl(i_peak, new_hkl, error) else: err_msg += ret_obj + '\n' # END-FOR if len(err_msg) > 0: self.pop_one_button_dialog(err_msg) return def do_list_scans(self): """ List all scans available :return: """ # Experiment number exp_no = int(self.ui.lineEdit_exp.text()) access_mode = str(self.ui.comboBox_mode.currentText()) if access_mode == 'Local': spice_dir = str(self.ui.lineEdit_localSpiceDir.text()) message = fcutil.get_scans_list_local_disk(spice_dir, exp_no) else: url = str(self.ui.lineEdit_url.text()) message = fcutil.get_scans_list(url, exp_no) self.pop_one_button_dialog(message) return def do_load_scan_info(self): """ Load SIICE's scan file :return: """ # Get scan number status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_run]) if status is True: scan_no = ret_obj[0] else: err_msg = ret_obj self.pop_one_button_dialog('Unable to get scan number in raw data tab due to %s.' % err_msg) return status, err_msg = self._myControl.load_spice_scan_file(exp_no=None, scan_no=scan_no) if status is False: self.pop_one_button_dialog(err_msg) return def do_plot_pt_raw(self): """ Plot the Pt. """ # Get measurement pt and the file number status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_run, self.ui.lineEdit_rawDataPtNo]) if status is True: exp_no = ret_obj[0] scan_no = ret_obj[1] pt_no = ret_obj[2] else: self.pop_one_button_dialog(ret_obj) return # Call to plot 2D self._plot_raw_xml_2d(exp_no, scan_no, pt_no) return def do_plot_prev_pt_raw(self): """ Plot the Pt. """ # Get measurement pt and the file number status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_run, self.ui.lineEdit_rawDataPtNo]) if status is True: exp_no = ret_obj[0] scan_no = ret_obj[1] pt_no = ret_obj[2] else: self.pop_one_button_dialog(ret_obj) return # Previous one pt_no -= 1 if pt_no <= 0: self.pop_one_button_dialog('Pt. = 1 is the first one.') return else: self.ui.lineEdit_rawDataPtNo.setText('%d' % pt_no) # Plot self._plot_raw_xml_2d(exp_no, scan_no, pt_no) return def do_plot_next_pt_raw(self): """ Plot the Pt. """ # Get measurement pt and the file number status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_run, self.ui.lineEdit_rawDataPtNo]) if status is True: exp_no = ret_obj[0] scan_no = ret_obj[1] pt_no = ret_obj[2] else: self.pop_one_button_dialog(ret_obj) return # Previous one pt_no += 1 # get last Pt. number status, last_pt_no = self._myControl.get_pt_numbers(exp_no, scan_no) if status is False: error_message = last_pt_no self.pop_one_button_dialog('Unable to access Spice table for scan %d. Reason" %s.' % ( scan_no, error_message)) if pt_no > last_pt_no: self.pop_one_button_dialog('Pt. = %d is the last one of scan %d.' % (pt_no, scan_no)) return else: self.ui.lineEdit_rawDataPtNo.setText('%d' % pt_no) # Plot self._plot_raw_xml_2d(exp_no, scan_no, pt_no) return def do_merge_scans(self): """ Process data for slicing view :return: """ # Get UB matrix ub_matrix = self.ui.tableWidget_ubSiceView.get_matrix() self._myControl.set_ub_matrix(exp_number=None, ub_matrix=ub_matrix) # Get list of scans scan_list = gutil.parse_integer_list(str(self.ui.lineEdit_listScansSliceView.text())) if len(scan_list) == 0: self.pop_one_button_dialog('Scan list is empty.') # Set table self.ui.tableWidget_sliceViewProgress.append_scans(scans=scan_list) # Warning self.pop_one_button_dialog('Data processing is long. Be patient!') # Process base_name = str(self.ui.lineEdit_baseMergeMDName.text()) scan_list.sort() frame = str(self.ui.comboBox_mergeScanFrame.currentText()) for scan_no in scan_list: # Download/check SPICE file self._myControl.download_spice_file(None, scan_no, over_write=False) # Get some information status, pt_list = self._myControl.get_pt_numbers(None, scan_no, load_spice_scan=True) if status is False: err_msg = pt_list self.pop_one_button_dialog('Failed to get Pt. number: %s' % err_msg) return else: # Set information to table err_msg = self.ui.tableWidget_sliceViewProgress.set_scan_pt(scan_no, pt_list) if len(err_msg) > 0: self.pop_one_button_dialog(err_msg) out_ws_name = base_name + '%04d' % scan_no self.ui.tableWidget_sliceViewProgress.set_scan_pt(scan_no, 'In Processing') try: ret_tup = self._myControl.merge_pts_in_scan(exp_no=None, scan_no=scan_no, target_ws_name=out_ws_name, target_frame=frame) merge_status = 'Done' merged_name = ret_tup[0] group_name = ret_tup[1] except RuntimeError as e: merge_status = 'Failed. Reason: %s' % str(e) merged_name = '' group_name = '' finally: self.ui.tableWidget_sliceViewProgress.set_status(scan_no, merge_status) self.ui.tableWidget_sliceViewProgress.set_ws_names(scan_no, merged_name, group_name) # Sleep for a while time.sleep(0.1) # END-FOR return def do_reset_ub_peaks_hkl(self): """ Reset user specified HKL value to peak table :return: """ num_rows = self.ui.tableWidget_peaksCalUB.rowCount() for i_row in xrange(num_rows): print '[DB] Update row %d' % (i_row) scan, pt = self.ui.tableWidget_peaksCalUB.get_scan_pt(i_row) status, peak_info = self._myControl.get_peak_info(None, scan, pt) if status is False: error_message = peak_info raise RuntimeError(error_message) h, k, l = peak_info.get_user_hkl() self.ui.tableWidget_peaksCalUB.update_hkl(i_row, h, k, l) # END-FOR return def do_set_experiment(self): """ Set experiment :return: """ status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp]) if status is True: exp_number = ret_obj[0] curr_exp_number = self._myControl.get_experiment() if curr_exp_number is not None and exp_number != curr_exp_number: self.pop_one_button_dialog('Changing experiment to %d. Clean previous experiment %d\'s result' ' in Mantid manually.' % (exp_number, curr_exp_number)) self._myControl.set_exp_number(exp_number) self.ui.lineEdit_exp.setStyleSheet('color: black') else: err_msg = ret_obj self.pop_one_button_dialog('Unable to set experiment as %s' % err_msg) self.ui.lineEdit_exp.setStyleSheet('color: red') self.ui.tabWidget.setCurrentIndex(0) return def do_set_ub_sv(self): """ Set UB matrix in Slice view :return: """ if self.ui.radioButton_ubFromTab1.isChecked(): self.ui.tableWidget_ubSiceView.set_from_matrix(self.ui.tableWidget_ubMatrix.get_matrix()) elif self.ui.radioButton_ubFromTab3.isChecked(): self.ui.tableWidget_ubSiceView.set_from_matrix(self.ui.tableWidget_refinedUB.get_matrix()) elif self.ui.radioButton_ubFromList.isChecked(): status, ret_obj = gutil.parse_float_array(str(self.ui.plainTextEdit_ubInput.toPlainText())) if status is False: self.pop_one_button_dialog(ret_obj) elif len(ret_obj) != 9: self.pop_one_button_dialog('Requiring 9 floats for UB matrix. Only %d are given.' % len(ret_obj)) else: self.ui.tableWidget_ubSiceView.set_from_list(ret_obj) else: self.pop_one_button_dialog('None is selected to set UB matrix.') return def do_setup_dir_default(self): """ Set up default directory for storing data and working :return: """ home_dir = os.path.expanduser('~') # Data cache directory data_cache_dir = os.path.join(home_dir, 'Temp/HB3ATest') self.ui.lineEdit_localSpiceDir.setText(data_cache_dir) self.ui.lineEdit_localSrcDir.setText(data_cache_dir) work_dir = os.path.join(data_cache_dir, 'Workspace') self.ui.lineEdit_workDir.setText(work_dir) return def do_apply_setup(self): """ Apply set up ... :return: """ # Local data directory local_data_dir = str(self.ui.lineEdit_localSpiceDir.text()) if os.path.exists(local_data_dir) is False: try: os.mkdir(local_data_dir) except OSError as os_error: self.pop_one_button_dialog('Unable to create local data directory %s due to %s.' % ( local_data_dir, str(os_error))) self.ui.lineEdit_localSpiceDir.setStyleSheet("color: red;") return else: self.ui.lineEdit_localSpiceDir.setStyleSheet("color: black;") # END-IF # Working directory working_dir = str(self.ui.lineEdit_workDir.text()) if os.path.exists(working_dir) is False: try: os.mkdir(working_dir) except OSError as os_error: self.pop_one_button_dialog('Unable to create working directory %s due to %s.' % ( working_dir, str(os_error))) self.ui.lineEdit_workDir.setStyleSheet("color: red;") return else: self.ui.lineEdit_workDir.setStyleSheet("color: black;") # END-IF # Server URL data_server = str(self.ui.lineEdit_url.text()) url_is_good = self.do_test_url() if url_is_good is False: self.ui.lineEdit_url.setStyleSheet("color: red;") return else: self.ui.lineEdit_url.setStyleSheet("color: black;") # Set to control self._myControl.set_local_data_dir(local_data_dir) self._myControl.set_working_directory(working_dir) self._myControl.set_server_url(data_server) return def do_test_url(self): """ Test whether the root URL provided specified is good """ url = str(self.ui.lineEdit_url.text()) url_is_good, err_msg = fcutil.check_url(url) if url_is_good is True: self.pop_one_button_dialog("URL %s is valid." % url) else: self.pop_one_button_dialog(err_msg) return url_is_good def pop_one_button_dialog(self, message): """ Pop up a one-button dialog :param message: :return: """ assert isinstance(message, str) QtGui.QMessageBox.information(self, '4-circle Data Reduction', message) return def save_current_session(self, filename=None): """ Save current session/value setup to :return: """ # Set up dictionary save_dict = dict() # Setup save_dict['lineEdit_localSpiceDir'] = str(self.ui.lineEdit_localSpiceDir.text()) save_dict['lineEdit_url'] = str(self.ui.lineEdit_url.text()) save_dict['lineEdit_workDir']= str(self.ui.lineEdit_workDir.text()) # Experiment save_dict['lineEdit_exp'] = str(self.ui.lineEdit_exp.text()) save_dict['lineEdit_scanNumber'] = self.ui.lineEdit_scanNumber.text() save_dict['lineEdit_ptNumber'] = str(self.ui.lineEdit_ptNumber.text()) # Lattice save_dict['lineEdit_a'] = str(self.ui.lineEdit_a.text()) save_dict['lineEdit_b'] = str(self.ui.lineEdit_b.text()) save_dict['lineEdit_c'] = str(self.ui.lineEdit_c.text()) save_dict['lineEdit_alpha'] = str(self.ui.lineEdit_alpha.text()) save_dict['lineEdit_beta'] = str(self.ui.lineEdit_beta.text()) save_dict['lineEdit_gamma'] = str(self.ui.lineEdit_gamma.text()) # Merge scan save_dict['plainTextEdit_ubInput'] = str(self.ui.plainTextEdit_ubInput.toPlainText()) save_dict['lineEdit_listScansSliceView'] = str(self.ui.lineEdit_listScansSliceView.text()) save_dict['lineEdit_baseMergeMDName'] = str(self.ui.lineEdit_baseMergeMDName.text()) # Save to csv file if filename is None: filename = 'session_backup.csv' ofile = open(filename, 'w') writer = csv.writer(ofile) for key, value in save_dict.items(): writer.writerow([key, value]) ofile.close() return def load_session(self, filename=None): """ To load a session, i.e., read it back: :param filename: :return: """ if filename is None: filename = 'session_backup.csv' in_file = open(filename, 'r') reader = csv.reader(in_file) my_dict = dict(x for x in reader) # ... for key, value in my_dict.items(): if key.startswith('lineEdit') is True: self.ui.__getattribute__(key).setText(value) elif key.startswith('plainText') is True: self.ui.__getattribute__(key).setPlainText(value) elif key.startswith('comboBox') is True: self.ui.__getattribute__(key).setCurrentIndex(int(value)) else: self.pop_one_button_dialog('Error! Widget name %s is not supported' % key) # END-FOR # ... self._myControl.set_local_data_dir(str(self.ui.lineEdit_localSpiceDir.text())) return def menu_quit(self): """ :return: """ self.close() def show_scan_pt_list(self): """ Show the range of Pt. in a scan :return: """ # Get parameters status, inp_list = gutil.parse_integers_editors([self.ui.lineEdit_exp, self.ui.lineEdit_run]) if status is False: self.pop_one_button_dialog(inp_list) return else: exp_no = inp_list[0] scan_no = inp_list[1] status, ret_obj = self._myControl.get_pt_numbers(exp_no, scan_no) # Form message if status is False: # Failed to get Pt. list error_message = ret_obj self.pop_one_button_dialog(error_message) else: # Form message pt_list = sorted(ret_obj) num_pts = len(pt_list) info = 'Exp %d Scan %d has %d Pt. ranging from %d to %d.\n' % (exp_no, scan_no, num_pts, pt_list[0], pt_list[-1]) num_miss_pt = pt_list[-1] - pt_list[0] + 1 - num_pts if num_miss_pt > 0: info += 'There are %d Pt. skipped.\n' % num_miss_pt self.pop_one_button_dialog(info) return def set_ub_peak_table(self, peakinfo): """ DOC :param peak_info: :return: """ assert isinstance(peakinfo, r4c.PeakInfo) # Get data exp_number, scan_number, pt_number = peakinfo.getExpInfo() h, k, l = peakinfo.get_user_hkl() q_sample = peakinfo.getQSample() m1 = self._myControl.get_sample_log_value(exp_number, scan_number, pt_number, '_m1') # Set to table status, err_msg = self.ui.tableWidget_peaksCalUB.append_row( [scan_number, pt_number, h, k, l, q_sample[0], q_sample[1], q_sample[2], False, m1, '']) if status is False: self.pop_one_button_dialog(err_msg) return def _get_lattice_parameters(self): """ Get lattice parameters from GUI :return: (Boolean, Object). True, 6-tuple as a, b, c, alpha, beta, gamm False: error message """ status, ret_list = gutil.parse_float_editors([self.ui.lineEdit_a, self.ui.lineEdit_b, self.ui.lineEdit_c, self.ui.lineEdit_alpha, self.ui.lineEdit_beta, self.ui.lineEdit_gamma]) if status is False: err_msg = ret_list err_msg = 'Unable to parse unit cell due to %s' % err_msg return False, err_msg a, b, c, alpha, beta, gamma = ret_list return True, (a, b, c, alpha, beta, gamma) def _plot_raw_xml_2d(self, exp_no, scan_no, pt_no): """ Plot raw workspace from XML file for a measurement/pt. """ # Check and load SPICE table file does_exist = self._myControl.does_spice_loaded(exp_no, scan_no) if does_exist is False: # Download data status, error_message = self._myControl.download_spice_file(exp_no, scan_no, over_write=False) if status is True: status, error_message = self._myControl.load_spice_scan_file(exp_no, scan_no) if status is False and self._allowDownload is False: self.pop_one_button_dialog(error_message) return else: self.pop_one_button_dialog(error_message) return # END-IF(does_exist) # Load Data for Pt's xml file does_exist = self._myControl.does_raw_loaded(exp_no, scan_no, pt_no) if does_exist is False: # Check whether needs to download status, error_message = self._myControl.download_spice_xml_file(scan_no, pt_no, exp_no=exp_no) if status is False: self.pop_one_button_dialog(error_message) return # Load SPICE xml file status, error_message = self._myControl.load_spice_xml_file(exp_no, scan_no, pt_no) if status is False: self.pop_one_button_dialog(error_message) return # Convert a list of vector to 2D numpy array for imshow() # Get data and plot raw_det_data = self._myControl.get_raw_detector_counts(exp_no, scan_no, pt_no) self.ui.graphicsView.clear_canvas() self.ui.graphicsView.add_plot_2d(raw_det_data, x_min=0, x_max=256, y_min=0, y_max=256, hold_prev_image=False) return def _show_ub_matrix(self, ubmatrix): """ Show UB matrix :param ubmatrix: :return: """ assert ubmatrix.shape == (3, 3) self.ui.tableWidget_ubMatrix.set_from_matrix(ubmatrix) return
class MainWindow ( QtGui.QMainWindow ): # # def __init__ ( self ) : # QtGui.QMainWindow.__init__ ( self ) # This is always the same self.ui = Ui_MainWindow () self.ui.setupUi ( self ) self.setupMenuBar () self.setupPanels () self.setWindowTitle ( "meShaderEd (" + app_renderer.getCurrentPresetName() + ")") self.activeNodeList = None self.workArea = None # current work area self.onNew () # create new document grid_enabled = getDefaultValue( app_settings, 'WorkArea', 'grid_enabled' ) grid_snap = getDefaultValue ( app_settings, 'WorkArea', 'grid_snap' ) grid_size = int( getDefaultValue ( app_settings, 'WorkArea', 'grid_size' ) ) reverse_flow = getDefaultValue ( app_settings, 'WorkArea', 'reverse_flow' ) straight_links = getDefaultValue ( app_settings, 'WorkArea', 'straight_links' ) #self.ui.workArea.gridSize = grid_size #self.ui.workArea.gridSnap = grid_snap self.workArea.drawGrid = grid_enabled #self.ui.workArea.reverseFlow = reverse_flow #self.ui.workArea.straightLinks = straight_links self.ui.actionShowGrid.setChecked( grid_enabled ) self.ui.actionSnapGrid.setChecked( grid_snap ) self.ui.actionReverseFlow.setChecked( reverse_flow ) self.ui.actionStraightLinks.setChecked( straight_links ) self.ui.nodeList_ctl.setLibrary ( app_global_vars[ 'NodesPath' ] ) self.ui.project_ctl.setLibrary ( app_global_vars[ 'ProjectNetworks' ] ) QtCore.QObject.connect ( self.ui.nodeList_ctl.ui.nodeList, QtCore.SIGNAL( "setActiveNodeList" ), self.setActiveNodeList ) QtCore.QObject.connect ( self.ui.project_ctl.ui.nodeList, QtCore.SIGNAL( "setActiveNodeList" ), self.setActiveNodeList ) QtCore.QObject.connect ( self.ui.tabs, QtCore.SIGNAL( "currentChanged(int)" ), self.onTabSelected ) QtCore.QObject.connect ( self.ui.tabs, QtCore.SIGNAL( "tabCloseRequested(int)" ), self.onTabCloseRequested ) QtCore.QObject.connect ( self.ui.nodeParam_ctl, QtCore.SIGNAL( "nodeLabelChanged" ), self.onNodeLabelChanged ) # # def connectWorkAreaSignals ( self ) : if self.workArea != None : if self.activeNodeList != None : QtCore.QObject.connect ( self.activeNodeList, QtCore.SIGNAL( "addNode" ), self.workArea.insertNodeNet ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL( "selectNodes" ), self.onSelectGfxNodes ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL( "nodeParamChanged" ), self.onNodeParamChanged ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL( "gfxNodeAdded" ), self.onAddGfxNode ) QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL( "gfxNodeRemoved" ), self.onRemoveGfxNode ) # # def disconnectWorkAreaSignals ( self ) : if self.workArea != None : if self.activeNodeList != None : QtCore.QObject.disconnect ( self.activeNodeList, QtCore.SIGNAL( "addNode" ), self.workArea.insertNodeNet ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL( "selectNodes" ), self.onSelectGfxNodes ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL( "nodeParamChanged" ), self.onNodeParamChanged ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL( "gfxNodeAdded" ), self.onAddGfxNode ) QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL( "gfxNodeRemoved" ), self.onRemoveGfxNode ) # # def setupMenuBar ( self ) : # override font for menu from Designer's settings to system default font = QtGui.QFont () if ( sys.platform == 'win32' ): # Runing on windows, override font sizes from Designer to default font.setPointSize ( 8 ) elif ( sys.platform == 'darwin' ): font.setPointSize ( 10 ) self.ui.menubar.setFont ( font ) self.ui.menuFile.setFont ( font ) self.ui.menuEdit.setFont ( font ) self.ui.menuCommand.setFont ( font ) self.ui.menuWindow.setFont ( font ) self.ui.menuHelp.setFont ( font ) # # def setupPanels ( self ) : self.tabifyDockWidget ( self.ui.dockGeom, self.ui.dockPreview ) self.tabifyDockWidget ( self.ui.dockProject, self.ui.dockNodes ) self.removeDockWidget ( self.ui.dockParam ) self.addDockWidget ( QtCore.Qt.DockWidgetArea(2), self.ui.dockParam ) self.ui.dockParam.show () # # def onProjectSetup ( self ): print ">> MainWindow: onProjectSetup" projectSetupDlg = ProjectSetup ( app_settings ) projectSetupDlg.exec_() self.ui.project_ctl.setLibrary ( app_global_vars[ 'ProjectNetworks' ] ) # # def onSettingsSetup ( self ): print ">> MainWindow: onSettingsSetup" settingsSetupDlg = SettingsSetup ( app_settings ) settingsSetupDlg.exec_() self.ui.nodeList_ctl.setLibrary ( app_global_vars[ 'NodesPath' ] ) # # def onRenderSettings ( self ): print ">> MainWindow: onRenderSettings" renderSettingsDlg = meRendererSetup ( app_renderer ) QtCore.QObject.connect( renderSettingsDlg, QtCore.SIGNAL("presetChanged"), self.onRenderPresetChanged ) QtCore.QObject.connect( renderSettingsDlg, QtCore.SIGNAL("savePreset"), self.onRenderSavePreset ) renderSettingsDlg.exec_() # # def onRenderPresetChanged ( self ): # presetName = app_renderer.getCurrentPresetName() print ">> MainWindow: onRenderPresetChanged preset = %s" % presetName self.setWindowTitle ( "meShaderEd (" + presetName + ")") app_settings.setValue ( 'defRenderer', presetName ) app_global_vars[ 'Renderer' ] = app_renderer.getCurrentValue( 'renderer', 'name' ) app_global_vars[ 'RendererFlags' ] = app_renderer.getCurrentValue( 'renderer', 'flags' ) app_global_vars[ 'ShaderCompiler' ] = app_renderer.getCurrentValue( 'shader', 'compiler' ) app_global_vars[ 'ShaderDefines' ] = app_renderer.getCurrentValue( 'shader', 'defines' ) app_global_vars[ 'TEX' ] = app_renderer.getCurrentValue( 'texture', 'extension' ) app_global_vars[ 'SLO' ] = app_renderer.getCurrentValue( 'shader', 'extension' ) # # def onRenderSavePreset ( self ): # print ">> MainWindow: onRenderSavePreset preset = %s" % app_renderer.getCurrentPresetName() app_renderer.saveSettings () # # def onShowGrid ( self, check ): # print ">> MainWindow: onShowGrid = %d" % check self.workArea.drawGrid = bool( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'grid_enabled', bool( check ) ) app_settings.endGroup () self.workArea.resetCachedContent() #self.ui.workArea.update() # # def onSnapGrid ( self, check ): # print ">> MainWindow: onSnapGrid = %d" % check self.workArea.gridSnap = bool( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'grid_snap', bool( check ) ) app_settings.endGroup () #self.ui.workArea.resetCachedContent() # # def onReverseFlow ( self, check ): # print ">> MainWindow: onReverseFlow = %d" % check self.workArea.reverseFlow = bool( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'reverse_flow', bool( check ) ) app_settings.endGroup () #self.ui.workArea.resetCachedContent() # # def onStraightLinks ( self, check ): # print ">> MainWindow: onStraightLinks = %d" % check self.workArea.straightLinks = bool( check ) app_settings.beginGroup ( 'WorkArea' ) app_settings.setValue ( 'straight_links', bool( check ) ) app_settings.endGroup () self.workArea.resetCachedContent () # # def setActiveNodeList ( self, nodeList ) : print '>> MainWindow: setActiveNodeList' if self.activeNodeList != None : QtCore.QObject.disconnect ( self.activeNodeList, QtCore.SIGNAL( "addNode" ), self.workArea.insertNodeNet ) self.activeNodeList = nodeList QtCore.QObject.connect ( self.activeNodeList, QtCore.SIGNAL( "addNode" ), self.workArea.insertNodeNet ) # # Called by WorkArea after drag&drop event # Here we choose selected nodeList panel (Libray or Project) # for processing node request def onGetNode ( self, itemFilename, pos ): if self.activeNodeList != None : self.activeNodeList.onGetNode ( itemFilename, pos ) # # def onAddGfxNode ( self, gfxNode ): # #print ">> MainWindow: onAddGfxNode = %s" % gfxNode.node.label if gfxNode.node.type == 'image' : self.ui.imageView_ctl.addViewer ( gfxNode ) #if self.ui.nodeParam_ctl.receivers( QtCore.SIGNAL( 'onNodeParamChanged(QObject,QObject)' ) ) == 0 : # QtCore.QObject.connect( self.ui.nodeParam_ctl, QtCore.SIGNAL( 'onNodeParamChanged(QObject,QObject)' ), self.ui.imageView_ctl.onNodeParamChanged ) #else : # print ">> MainWindow: nodeParam_ctl onNodeParamChanged already connected to imageView_ctl" # # def onRemoveGfxNode ( self, gfxNode ): # print ">> MainWindow: onRemoveGfxNode = %s" % gfxNode.node.label if gfxNode.node.type == 'image' : self.ui.imageView_ctl.removeViewer ( gfxNode ) #QtCore.QObject.disconnect ( self.ui.nodeParam_ctl, QtCore.SIGNAL( 'onNodeParamChanged(QObject,QObject)' ), self.ui.imageView_ctl.onNodeParamChanged ) # # def onDelete ( self ): # print ">> MainWindow: onDelete" selected = self.workArea.scene().selectedItems() if len ( selected ) : self.workArea.removeSelected() else : self.ui.imageView_ctl.removeAllViewers () self.workArea.clear() # # def onSelectGfxNodes ( self, gfxNodes = [], gfxLinks = [] ): # #print ">> MainWindow: onSelectGfxNodes" self.workArea.inspectedNode = None if len( gfxNodes ) == 1 : self.workArea.inspectedNode = gfxNodes[ 0 ] self.ui.nodeParam_ctl.setNode ( self.workArea.inspectedNode ) # # def onNodeLabelChanged ( self, gfxNode, newLabel ) : self.workArea.nodeNet.renameNodeLabel ( gfxNode.node, newLabel ) gfxNode.updateNodeLabel() self.ui.imageView_ctl.onNodeLabelChanged ( gfxNode, newLabel ) self.workArea.scene().update() # # def onNodeParamChanged ( self, gfxNode, param ) : #param.shaderParam = not gfxNode.node.isInputParamLinked ( param ) gfxNode.updateInputParams () self.ui.nodeParam_ctl.updateGui () # # def onFitAll ( self ) : print ">> MainWindow: onFitAll" # # def onFitSelected ( self ) : print ">> MainWindow: onFitSelected" # # def onZoomReset ( self ) : print ">> MainWindow: onZoomReset" # # def onNewParamView ( self ) : print ">> MainWindow: onNewParamView" # # def onTabSelected ( self, idx ) : # print '>> MainWindow: onTabSelected (%d)' % idx self.disconnectWorkAreaSignals () self.ui.imageView_ctl.removeAllViewers () self.workArea = self.ui.tabs.currentWidget () imageNodes = self.workArea.getGfxNodesByType ( 'image' ) # setup imageView menu for image nodes in new tab for gfxNode in imageNodes : self.ui.imageView_ctl.addViewer ( gfxNode ) self.connectWorkAreaSignals () self.ui.nodeParam_ctl.setNode ( self.workArea.inspectedNode ) # # def onTabCloseRequested ( self, idx ) : # print '>> MainWindow: onTabCloseRequested (%d)' % idx if self.ui.tabs.count() > 1 : self.workArea.nodeNet.clear() self.ui.tabs.removeTab ( idx ) # # def onNew ( self, tabName = 'untitled' ): # def tabNameExists ( self, name ): ret = False for i in range ( 0, self.ui.tabs.count() ) : if name == str ( self.ui.tabs.tabText ( i ) ): ret = True break return ret newName = tabName print '-> self.ui.tabs.count() = %d ' % self.ui.tabs.count() if self.workArea != None : print '-> create new WorkArea widget' # set unique new name name = newName i = 0 while True : if tabNameExists ( self, name ) : name = newName + str ( i ) i += 1 continue else : break newName = name workArea = WorkArea () # create new WorkArea instance newTab = self.ui.tabs.addTab ( workArea, newName ) else : print '-> use initial WorkArea widget' workArea = self.ui.workArea # use initial WorkArea widget self.workArea = workArea self.connectWorkAreaSignals () nodeNet = NodeNetwork ( newName ) workArea.setNodeNetwork ( nodeNet ) self.ui.tabs.setTabText ( self.ui.tabs.indexOf( workArea ), newName ) self.ui.tabs.setCurrentIndex ( self.ui.tabs.indexOf( workArea ) ) # # def onOpen ( self ): print ">> MainWindow: onOpen" # curDir = app_global_vars[ 'ProjectNetworks' ] typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str( QtGui.QFileDialog.getOpenFileName( self, "Open file", curDir, typeFilter ) ) if filename != '' : print "-> open file %s" % filename ( name, ext ) = os.path.splitext( os.path.basename( filename ) ) self.ui.imageView_ctl.removeAllViewers () self.workArea.clear () self.workArea.nodeNet.name = name self.workArea.nodeNet.fileName = '' self.ui.tabs.setTabText ( self.ui.tabs.indexOf( self.workArea ), name ) self.workArea.openNodeNet ( normPath ( filename ) ) # # def onImport ( self ): print ">> MainWindow: onImport" # curDir = app_global_vars[ 'ProjectNetworks' ] typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str( QtGui.QFileDialog.getOpenFileName( self, "Import file", curDir, typeFilter ) ) if filename != '' : print "-> import file %s" % filename self.workArea.insertNodeNet ( normPath ( filename ) ) # # def onSave ( self ): print ">> MainWindow: onSave" # if file is new -- use onSaveAs function # curDir = app_global_vars[ 'ProjectNetworks' ] if self.workArea.nodeNet.fileName == '' : self.onSaveAs () else : print '-> save file %s' % self.workArea.nodeNet.fileName self.workArea.nodeNet.save () # # def onSaveAs ( self ): print ">> MainWindow: onSaveAs" # curDir = app_global_vars[ 'ProjectNetworks' ] saveName = os.path.join ( curDir, self.workArea.nodeNet.name + '.xml' ) typeFilter = 'Shader networks *.xml;;All files *.*;;' filename = str( QtGui.QFileDialog.getSaveFileName ( self, "Save file as", saveName, typeFilter ) ) if filename != '' : print '-> save file As %s' % filename ( name, ext ) = os.path.splitext( os.path.basename( filename ) ) self.workArea.nodeNet.fileName = normPath ( filename ) self.workArea.nodeNet.name = name self.ui.tabs.setTabText ( self.ui.tabs.indexOf( self.workArea ), name ) self.workArea.nodeNet.save () self.ui.project_ctl.onReload()
class QmyMainWindow(QMainWindow): def __init__(self, parrent=None): super().__init__(parrent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle('串口调试助手') # 串口相关操作 self.ser = serial.Serial() self.currentCom = 'COM1' self.currentBps = 9600 self.on_btnSerial_clicked() # 定时器 self.timer = QTimer(self) self.timer.timeout.connect(self.serial_monitor) self.timer.start(100) ######## 串口操作相关函数 ################## def get_serial_ports(self): ports_ = list(serial.tools.list_ports.comports()) self.ports = {} for i in ports_: # i[0] -- 端口号 # i[1] -- 端口名或描述 self.ports[i[1]] = i[0] ######## PyQt 界面绑定函数 ################## @pyqtSlot() def on_btnSerial_clicked(self): self.get_serial_ports() self.ui.comboBox_SerialPort.clear() for k in self.ports: self.ui.comboBox_SerialPort.addItem(k, self.ports[k]) @pyqtSlot(str) def on_comboBox_SerialPort_currentIndexChanged(self, curText): com = self.ui.comboBox_SerialPort.currentData() self.currentCom = com self.ser.setPort(self.currentCom) @pyqtSlot(str) def on_comboBox_Baudrate_currentIndexChanged(self, curText): self.currentBps = int(curText) self.ser.baudrate = self.currentBps @pyqtSlot() def on_checkBox_RxHex_clicked(self): checked = self.ui.checkBox_RxHex.isChecked() def on_btn_Clr_clicked(self): self.ui.textEdit_Rec.setPlainText('') @pyqtSlot() def on_btn_SerOpen_clicked(self): self.ser.setPort(self.currentCom) self.ser.baudrate = self.currentBps self.timeout = 1 self.ser.writeTimeout = 1 if self.ser.isOpen() == False: self.ser.open() self.PrintLog(self.currentCom + ' open Sucess') return 1 else: self.PrintLog(self.currentCom + ' had been opened') return 0 @pyqtSlot() def on_btn_SerClose_clicked(self): if self.ser.isOpen(): self.ser.close() self.PrintLog(self.currentCom + ' Close success') @pyqtSlot() def on_btn_Send_clicked(self): text = self.ui.textEdit_Send.toPlainText() text_list = re.split(r'\s+', text) hex_list = [] for i in text_list: if i != '': hex_list.append(int(i, 16)) if self.ser.isOpen(): if len(hex_list) != 0: self.ser.write(bytes(hex_list)) def serial_monitor(self): self.timer.start(100) LineWrap = self.ui.chkBox_LineWrap.isChecked() if self.ser.isOpen(): n = self.ser.inWaiting() if n != 0: checked = self.ui.checkBox_RxHex.isChecked() if (checked): data = list(self.ser.read(n)) text = '' for i in data: text += '%02x ' % i if LineWrap: self.PrintLog(text) else: self.ui.textEdit_Rec.insertPlainText(text) else: text = str(self.ser.read(n)) self.PrintLog(text) def PrintLog(self, text): self.ui.textEdit_Rec.appendPlainText(str(text))
class MainWindow(QtModule.QMainWindow): # # __init__ # def __init__(self): # QtModule.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) # # setup WhatsThis help action # self.ui.actionHelpMode = QtModule.QWhatsThis.createAction() self.ui.actionHelpMode.setToolTip('Enter "WhatsThis" help mode') self.ui.menuHelp.addAction(self.ui.actionHelpMode) self.ui.toolBar.addSeparator() self.ui.toolBar.addAction(self.ui.actionHelpMode) self.clipboard = QtModule.QApplication.clipboard() if usePyQt4: self.recentProjects = app_settings.value("RecentProjects").toStringList() self.recentNetworks = app_settings.value("RecentNetworks").toStringList() else: self.recentProjects = [] self.recentNetworks = [] recentProjects = app_settings.value("RecentProjects") if recentProjects is not None: if isinstance(recentProjects, list): for proj in recentProjects: self.recentProjects.append(proj) else: self.recentProjects.append(recentProjects) recentNetworks = app_settings.value("RecentNetworks") if recentNetworks is not None: if isinstance(recentNetworks, list): for network in recentNetworks: self.recentNetworks.append(network) else: self.recentNetworks.append(recentNetworks) print "* recentProjects =", self.recentProjects print "* recentNetworks =", self.recentNetworks print "* ProjectPath =", app_global_vars["ProjectPath"] self.addRecentProject(app_global_vars["ProjectPath"]) self.setupMenuBar() self.setupPanels() self.activeNodeList = None self.workArea = None # current work area self.onNew() # create new document grid_enabled = getDefaultValue(app_settings, "WorkArea", "grid_enabled") grid_snap = getDefaultValue(app_settings, "WorkArea", "grid_snap") grid_size = int(getDefaultValue(app_settings, "WorkArea", "grid_size")) reverse_flow = getDefaultValue(app_settings, "WorkArea", "reverse_flow") straight_links = getDefaultValue(app_settings, "WorkArea", "straight_links") # self.ui.workArea.gridSize = grid_size # self.ui.workArea.gridSnap = grid_snap self.workArea.drawGrid = grid_enabled # self.ui.workArea.reverseFlow = reverse_flow # self.ui.workArea.straightLinks = straight_links self.ui.actionShowGrid.setChecked(grid_enabled) self.ui.actionSnapGrid.setChecked(grid_snap) self.ui.actionReverseFlow.setChecked(reverse_flow) self.ui.actionStraightLinks.setChecked(straight_links) self.ui.nodeList_ctl.setLibrary(app_global_vars["NodesPath"]) self.ui.project_ctl.setLibrary(app_global_vars["ProjectNetworks"]) # self.ui.dockNodes.setWindowTitle ( 'Library: %s' % app_global_vars [ 'NodesPath' ] ) # self.ui.dockProject.setWindowTitle ( 'Project: %s' % app_global_vars [ 'ProjectNetworks' ] ) self.connectSignals() self.setupActions() self.setupWindowTitle() # # connectSignals # def connectSignals(self): # if usePyQt4: QtCore.QObject.connect(self.ui.actionHelpMode, QtCore.SIGNAL("toggled(bool)"), self.onHelpMode) QtCore.QObject.connect( self.ui.nodeList_ctl.ui.nodeList, QtCore.SIGNAL("setActiveNodeList"), self.setActiveNodeList ) QtCore.QObject.connect( self.ui.project_ctl.ui.nodeList, QtCore.SIGNAL("setActiveNodeList"), self.setActiveNodeList ) QtCore.QObject.connect(self.ui.tabs, QtCore.SIGNAL("currentChanged(int)"), self.onTabSelected) QtCore.QObject.connect(self.ui.tabs, QtCore.SIGNAL("tabCloseRequested(int)"), self.onTabCloseRequested) QtCore.QObject.connect( self.ui.nodeParam_ctl, QtCore.SIGNAL("nodeLabelChangedSignal"), self.onNodeLabelChanged ) QtCore.QObject.connect( self.ui.nodeParam_ctl, QtCore.SIGNAL("nodeParamChangedSignal"), self.onNodeParamChanged ) else: self.ui.actionHelpMode.toggled.connect(self.onHelpMode) self.ui.nodeList_ctl.ui.nodeList.setActiveNodeList.connect(self.setActiveNodeList) self.ui.project_ctl.ui.nodeList.setActiveNodeList.connect(self.setActiveNodeList) self.ui.tabs.currentChanged.connect(self.onTabSelected) self.ui.tabs.tabCloseRequested.connect(self.onTabCloseRequested) self.ui.nodeParam_ctl.nodeLabelChangedSignal.connect(self.onNodeLabelChanged) self.ui.nodeParam_ctl.nodeParamChangedSignal.connect(self.onNodeParamChanged) # # connectWorkAreaSignals # def connectWorkAreaSignals(self): # if usePyQt4: if self.workArea != None: if self.activeNodeList != None: QtCore.QObject.connect(self.activeNodeList, QtCore.SIGNAL("addNode"), self.workArea.insertNodeNet) QtCore.QObject.connect(self.workArea, QtCore.SIGNAL("selectNodes"), self.onSelectGfxNodes) QtCore.QObject.connect( self.workArea, QtCore.SIGNAL("nodeConnectionChanged"), self.onGfxNodeParamChanged ) QtCore.QObject.connect(self.workArea, QtCore.SIGNAL("gfxNodeAdded"), self.onAddGfxNode) QtCore.QObject.connect(self.workArea, QtCore.SIGNAL("gfxNodeRemoved"), self.onRemoveGfxNode) # QtCore.QObject.connect ( self.workArea, QtCore.SIGNAL ( 'editGfxNode' ), self.editGfxNode ) QtCore.QObject.connect(self.workArea.scene(), QtCore.SIGNAL("nodeUpdated"), self.updateNodeParamView) QtCore.QObject.connect( self.workArea.scene(), QtCore.SIGNAL("gfxNodeParamChanged"), self.onGfxNodeParamChanged ) else: if self.workArea != None: if self.activeNodeList != None: self.activeNodeList.addNode.connect(self.workArea.insertNodeNet) self.workArea.selectNodes.connect(self.onSelectGfxNodes) self.workArea.nodeConnectionChanged.connect(self.onGfxNodeParamChanged) self.workArea.gfxNodeAdded.connect(self.onAddGfxNode) self.workArea.gfxNodeRemoved.connect(self.onRemoveGfxNode) # self.workArea.editGfxNode.connect ( self.editGfxNode ) self.workArea.scene().nodeUpdated.connect(self.updateNodeParamView) self.workArea.scene().gfxNodeParamChanged.connect(self.onGfxNodeParamChanged) # # disconnectWorkAreaSignals # def disconnectWorkAreaSignals(self): # if usePyQt4: if self.workArea != None: if self.activeNodeList != None: QtCore.QObject.disconnect( self.activeNodeList, QtCore.SIGNAL("addNode"), self.workArea.insertNodeNet ) QtCore.QObject.disconnect(self.workArea, QtCore.SIGNAL("selectNodes"), self.onSelectGfxNodes) QtCore.QObject.disconnect( self.workArea, QtCore.SIGNAL("nodeConnectionChanged"), self.onGfxNodeParamChanged ) QtCore.QObject.disconnect(self.workArea, QtCore.SIGNAL("gfxNodeAdded"), self.onAddGfxNode) QtCore.QObject.disconnect(self.workArea, QtCore.SIGNAL("gfxNodeRemoved"), self.onRemoveGfxNode) # QtCore.QObject.disconnect ( self.workArea, QtCore.SIGNAL ( 'editGfxNode' ), self.editGfxNode ) QtCore.QObject.disconnect(self.workArea.scene(), QtCore.SIGNAL("nodeUpdated"), self.updateNodeParamView) QtCore.QObject.disconnect( self.workArea.scene(), QtCore.SIGNAL("gfxNodeParamChanged"), self.onGfxNodeParamChanged ) else: if self.workArea != None: if self.activeNodeList != None: self.activeNodeList.addNode.disconnect(self.workArea.insertNodeNet) self.workArea.selectNodes.disconnect(self.onSelectGfxNodes) self.workArea.nodeConnectionChanged.disconnect(self.onGfxNodeParamChanged) self.workArea.gfxNodeAdded.disconnect(self.onAddGfxNode) self.workArea.gfxNodeRemoved.disconnect(self.onRemoveGfxNode) # self.workArea.editGfxNode.disconnect ( self.editGfxNode ) self.workArea.scene().nodeUpdated.disconnect(self.updateNodeParamView) self.workArea.scene().gfxNodeParamChanged.disconnect(self.onGfxNodeParamChanged) # # setupWindowTitle # def setupWindowTitle(self): # self.setWindowTitle( "meShaderEd %s (%s) %s" % ( app_global_vars["version"], app_global_vars["RendererPreset"].getCurrentPresetName(), app_global_vars["ProjectPath"], ) ) self.ui.dockNodes.setToolTip(app_global_vars["NodesPath"]) self.ui.dockNodes.setStatusTip(app_global_vars["NodesPath"]) self.ui.dockProject.setToolTip(app_global_vars["ProjectNetworks"]) self.ui.dockProject.setStatusTip(app_global_vars["ProjectNetworks"]) # # setupMenuBar # def setupMenuBar(self): # override font for menu from Designer's settings to system default import sys font = QtGui.QFont() if sys.platform == "win32": # Runing on windows, override font sizes from Designer to default font.setPointSize(8) elif sys.platform == "darwin": font.setPointSize(10) self.ui.menubar.setFont(font) self.ui.menuFile.setFont(font) self.ui.menuEdit.setFont(font) self.ui.menuCommand.setFont(font) self.ui.menuWindow.setFont(font) self.ui.menuHelp.setFont(font) self.buildRecentProjectsMenu() self.buildRecentNetworksMenu() # # buildRecentProjectsMenu # def buildRecentProjectsMenu(self): # print ">> buildRecentProjectsMenu ..." if usePyQt4: # self.recentProjects = app_settings.value ( 'RecentProjects' ).toStringList () print ">> self.recentProjects:", self.recentProjects self.ui.menuRecent_Projects.clear() if len(self.recentProjects): icon = QtGui.QIcon.fromTheme("folder", QtGui.QIcon(":/file_icons/resources/open.png")) # QtGui.QIcon ( ':/file_icons/resources/recentFile.png' ) 'folder' for i, fname in enumerate(self.recentProjects): # QtCore.QFileInfo ( fname ).fileName () action = QtModule.QAction(icon, "&%d %s" % (i + 1, fname), self) action.setData(QtCore.QVariant(fname)) self.connect(action, QtCore.SIGNAL("triggered()"), self.onOpenRecentProject) self.ui.menuRecent_Projects.addAction(action) else: # self.recentProjects = app_settings.value ( 'RecentProjects' ) print ">> self.recentProjects:", self.recentProjects self.ui.menuRecent_Projects.clear() if len(self.recentProjects): icon = QtGui.QIcon.fromTheme("folder", QtGui.QIcon(":/file_icons/resources/open.png")) # QtGui.QIcon ( ':/file_icons/resources/recentFile.png' ) 'folder' for i, fname in enumerate(self.recentProjects): # QtCore.QFileInfo ( fname ).fileName () action = QtModule.QAction(icon, "&%d %s" % (i + 1, fname), self) action.setData(fname) action.triggered.connect(self.onOpenRecentProject) self.ui.menuRecent_Projects.addAction(action) # # buildRecentNetworksMenu # def buildRecentNetworksMenu(self): # if usePyQt4: # self.recentNetworks = app_settings.value ( 'RecentNetworks' ).toStringList () self.ui.menuRecent_Networks.clear() if len(self.recentNetworks): for i, fname in enumerate(self.recentNetworks): icon = QtGui.QIcon.fromTheme("document-new", QtGui.QIcon(":/file_icons/resources/new.png")) # QtCore.QFileInfo ( fname ).fileName () action = QtModule.QAction(icon, "&%d %s" % (i + 1, fname), self) action.setData(QtCore.QVariant(fname)) self.connect(action, QtCore.SIGNAL("triggered()"), self.onOpenRecentNetwork) self.ui.menuRecent_Networks.addAction(action) else: # self.recentNetworks = app_settings.value ( 'RecentNetworks' ) self.ui.menuRecent_Networks.clear() if len(self.recentNetworks): for i, fname in enumerate(self.recentNetworks): icon = QtGui.QIcon.fromTheme("document-new", QtGui.QIcon(":/file_icons/resources/new.png")) # QtCore.QFileInfo ( fname ).fileName () action = QtModule.QAction(icon, "&%d %s" % (i + 1, fname), self) action.setData(fname) action.triggered.connect(self.onOpenRecentNetwork) self.ui.menuRecent_Networks.addAction(action) # # setupPanels # def setupPanels(self): # self.tabifyDockWidget(self.ui.dockNodes, self.ui.dockProject) # self.tabifyDockWidget ( self.ui.dockPreview, self.ui.dockGeom ) self.tabifyDockWidget(self.ui.dockParam, self.ui.dockSwatch) # temporary hide unused panels # self.removeDockWidget ( self.ui.dockGeom ) # self.removeDockWidget ( self.ui.dockSwatch ) # self.ui.dockGeom.hide () self.ui.dockSwatch.hide() self.ui.dockNodes.raise_() self.ui.dockPreview.raise_() self.ui.dockParam.raise_() # self.addDockWidget ( QtCore.Qt.DockWidgetArea ( 2 ), self.ui.dockParam ) # self.ui.dockParam.show () # # addRecentProject # def addRecentProject(self, project): # print ">> addRecentProject ", project if project is not None: if usePyQt4: recent_projects_max = getDefaultValue(app_settings, "", "recent_projects_max") if project not in self.recentProjects: self.recentProjects.prepend(QtCore.QString(project)) while self.recentProjects.count() > recent_projects_max: self.recentProjects.takeLast() recentProjects = QtCore.QVariant(self.recentProjects) if self.recentProjects else QtCore.QVariant() app_settings.setValue("RecentProjects", recentProjects) else: recent_projects_max = getDefaultValue(app_settings, "", "recent_projects_max") if project not in self.recentProjects: self.recentProjects.insert(0, project) while len(self.recentProjects) > recent_projects_max: self.recentProjects.pop() app_settings.setValue("RecentProjects", self.recentProjects) print "* project added recentProjects =", self.recentProjects print "* recentProjects =", self.recentProjects # # addRecentNetwork # def addRecentNetwork(self, network): # if network is not None: if usePyQt4: recent_networks_max = getDefaultValue(app_settings, "", "recent_networks_max") if network not in self.recentNetworks: self.recentNetworks.prepend(QtCore.QString(network)) while self.recentNetworks.count() > recent_networks_max: self.recentNetworks.takeLast() recentNetworks = QtCore.QVariant(self.recentNetworks) if self.recentNetworks else QtCore.QVariant() app_settings.setValue("RecentNetworks", recentNetworks) else: recent_networks_max = getDefaultValue(app_settings, "", "recent_networks_max") if network not in self.recentNetworks: self.recentNetworks.insert(0, network) while len(self.recentNetworks) > recent_networks_max: self.recentNetworks.pop() app_settings.setValue("RecentNetworks", self.recentNetworks) # # setupActions # def setupActions(self): # # if DEBUG_MODE : print '>> MainWindow.setupActions' import sys numNodes = 0 numSelectedNodes = 0 numSelectedLinks = 0 # selectedNodeType = None # selectedNodeFormat = None isShader = False isCode = False if self.workArea is not None: numNodes = len(self.workArea.getAllGfxNodes()) numSelectedNodes = len(self.workArea.selectedNodes) numSelectedLinks = len(self.workArea.selectedLinks) if numSelectedNodes == 1: selectedNode = self.getSelectedNode().node selectedNodeType = selectedNode.type selectedNodeFormat = selectedNode.format if selectedNodeFormat in ["rsl", "rib"]: isCode = True if selectedNode.thisIs() == "rsl_shader_node": isShader = True enableForPaste = False if self.clipboard.ownsClipboard() or (sys.platform == "darwin"): if DEBUG_MODE: print "** self.clipboard.ownsClipboard" data = self.clipboard.mimeData() if data is not None: if data.hasText(): enableForPaste = True self.ui.actionExportShader.setEnabled(isShader) self.ui.actionCompileShader.setEnabled(isShader) self.ui.actionViewComputedCode.setEnabled(isCode) self.ui.actionSaveSelected.setEnabled(numSelectedNodes > 0) self.ui.actionSelectAll.setEnabled(numNodes > 0) self.ui.actionSelectAbove.setEnabled(numSelectedNodes == 1) self.ui.actionSelectBelow.setEnabled(numSelectedNodes == 1) self.ui.actionDuplicate.setEnabled(numSelectedNodes > 0) self.ui.actionDuplicateWithLinks.setEnabled(numSelectedNodes > 0) self.ui.actionDelete.setEnabled((numSelectedNodes > 0) or (numSelectedLinks > 0)) self.ui.actionCut.setEnabled(numSelectedNodes > 0) self.ui.actionCopy.setEnabled(numSelectedNodes > 0) self.ui.actionPaste.setEnabled(enableForPaste) self.ui.actionFitAll.setEnabled(numNodes > 0) self.ui.actionFitSelected.setEnabled(numSelectedNodes > 0) # # onProjectSetup # def onProjectSetup(self): # if DEBUG_MODE: print ">> MainWindow.onProjectSetup" projectSetupDlg = ProjectSetup(app_settings) projectSetupDlg.exec_() self.ui.project_ctl.setLibrary(app_global_vars["ProjectNetworks"]) createDefaultProject(app_settings) self.setupWindowTitle() self.addRecentProject(app_global_vars["ProjectPath"]) self.buildRecentProjectsMenu() # # onSettingsSetup # def onSettingsSetup(self): # if DEBUG_MODE: print ">> MainWindow.onSettingsSetup" settingsSetupDlg = SettingsSetup(app_settings) settingsSetupDlg.exec_() self.ui.nodeList_ctl.setLibrary(app_global_vars["NodesPath"]) # # onRenderSettings # def onRenderSettings(self): # if DEBUG_MODE: print (">> MainWindow::onRenderSettings") import copy self.RendererPreset = copy.deepcopy(app_global_vars["RendererPreset"]) if DEBUG_MODE: print (":: self.RendererPreset.getCurrentPresetName = %s" % self.RendererPreset.getCurrentPresetName()) renderSettingsDlg = meRendererSetup(self.RendererPreset) if usePyQt4: QtCore.QObject.connect(renderSettingsDlg, QtCore.SIGNAL("presetChanged"), self.onRenderPresetChanged) QtCore.QObject.connect(renderSettingsDlg, QtCore.SIGNAL("savePreset"), self.onRenderPresetSave) else: renderSettingsDlg.presetChanged.connect(self.onRenderPresetChanged) renderSettingsDlg.savePreset.connect(self.onRenderPresetSave) renderSettingsDlg.exec_() # # onRenderPresetChanged # def onRenderPresetChanged(self): # if DEBUG_MODE: print (">> MainWindow::onRenderPresetChanged preset = %s" % self.RendererPreset.getCurrentPresetName()) app_settings.setValue("defRenderer", self.RendererPreset.getCurrentPresetName()) app_global_vars["RendererName"] = self.RendererPreset.currentPreset.RendererName app_global_vars["RendererFlags"] = self.RendererPreset.currentPreset.RendererFlags app_global_vars["ShaderCompiler"] = self.RendererPreset.currentPreset.ShaderCompiler app_global_vars["ShaderDefines"] = self.RendererPreset.currentPreset.ShaderDefines app_global_vars["ShaderInfo"] = self.RendererPreset.currentPreset.ShaderInfo app_global_vars["SLO"] = self.RendererPreset.currentPreset.ShaderExt app_global_vars["TextureMake"] = self.RendererPreset.currentPreset.TextureMake app_global_vars["TextureInfo"] = self.RendererPreset.currentPreset.TextureInfo app_global_vars["TextureViewer"] = self.RendererPreset.currentPreset.TextureViewer app_global_vars["TEX"] = self.RendererPreset.currentPreset.TextureExt app_global_vars["RendererPreset"] = self.RendererPreset self.setupWindowTitle() # # onRenderPresetSave # def onRenderPresetSave(self): # if DEBUG_MODE: print (">> MainWindow::onRenderPresetSave preset = %s" % self.RendererPreset.getCurrentPresetName()) self.RendererPreset.saveSettings() app_global_vars["RendererPreset"] = self.RendererPreset # # onShowGrid # def onShowGrid(self, check): # self.workArea.drawGrid = bool(check) app_settings.beginGroup("WorkArea") app_settings.setValue("grid_enabled", bool(check)) app_settings.endGroup() self.workArea.resetCachedContent() # self.ui.workArea.update() # # onSnapGrid # def onSnapGrid(self, check): # self.workArea.gridSnap = bool(check) app_settings.beginGroup("WorkArea") app_settings.setValue("grid_snap", bool(check)) app_settings.endGroup() # # onReverseFlow # def onReverseFlow(self, check): # self.workArea.reverseFlow = bool(check) app_settings.beginGroup("WorkArea") app_settings.setValue("reverse_flow", bool(check)) app_settings.endGroup() # self.ui.workArea.resetCachedContent() # # onStraightLinks # def onStraightLinks(self, check): # self.workArea.straightLinks = bool(check) app_settings.beginGroup("WorkArea") app_settings.setValue("straight_links", bool(check)) app_settings.endGroup() self.workArea.resetCachedContent() self.workArea.adjustLinks() # # setActiveNodeList # def setActiveNodeList(self, nodeList): # if DEBUG_MODE: print (">> MainWindow.setActiveNodeList") if usePyQt4: if self.activeNodeList != None: QtCore.QObject.disconnect(self.activeNodeList, QtCore.SIGNAL("addNode"), self.workArea.insertNodeNet) self.activeNodeList = nodeList QtCore.QObject.connect(self.activeNodeList, QtCore.SIGNAL("addNode"), self.workArea.insertNodeNet) else: if self.activeNodeList != None: self.activeNodeList.addNode.disconnect(self.workArea.insertNodeNet) self.activeNodeList = nodeList self.activeNodeList.addNode.connect(self.workArea.insertNodeNet) # # onGetNode # # Called by WorkArea after drag&drop event # Here we choose selected nodeList panel (Library or Project) # for processing node request # def onGetNode(self, itemFilename, pos): # if self.activeNodeList != None: self.activeNodeList.onGetNode(itemFilename, pos) # # onAddGfxNode # def onAddGfxNode(self, gfxNode): # # print ">> MainWindow: onAddGfxNode = %s" % gfxNode.node.label if gfxNode.node.format == "image": if gfxNode.node.thisIs() == "image_render_node": self.ui.imageView_ctl.addViewer(gfxNode) # # onRemoveGfxNode # def onRemoveGfxNode(self, gfxNode): # if DEBUG_MODE: print (">> MainWindow.onRemoveGfxNode = %s" % gfxNode.node.label) if gfxNode.node.format == "image": if gfxNode.node.thisIs() == "image_render_node": self.ui.imageView_ctl.removeViewer(gfxNode) # # getSelectedNode # def getSelectedNode(self): return self.workArea.selectedNodes[0] # # onRenderPreview # def onRenderPreview(self): print ">> MainWindow.onRenderPreview (not implemented yet...)" # # onShowSwatch # def onShowSwatch(self): print ">> MainWindow.onShowSwatch (not implemented yet...)" # # onHideSwatch # def onHideSwatch(self): print ">> MainWindow.onHideSwatch (not implemented yet...)" # # onCreateNode # def onCreateNode(self): print ">> MainWindow.onCreateNode (not implemented yet...)" # # onExportShader # def onExportShader(self): # if DEBUG_MODE: print ">> MainWindow.onExportShader" gfxNode = self.getSelectedNode() exportShaderDlg = ExportShaderDialog(gfxNode.node) exportShaderDlg.exec_() if exportShaderDlg.ui.chk_save_changes.isChecked(): if DEBUG_MODE: print ">> MainWindow.exportShaderDlg save changes" gfxNode.updateGfxNode(removeLinks=False) self.workArea.updateBelow(gfxNode) self.updateNodeParamView() self.workArea.scene().update() # # onViewComputedCode # def onViewComputedCode(self): ViewComputedCodeDialog(self.getSelectedNode().node).exec_() # # onEditNode # def onEditNode(self): # if DEBUG_MODE: print ">> MainWindow.onEditNode" gfxNode = self.getSelectedNode() editNode = gfxNode.node.copy() dupNodeNet = NodeNetwork("duplicate") dupNodeNet.addNode(editNode) # # copy input links to new node # if DEBUG_MODE: print "** duplicate input links ..." for link in gfxNode.node.getInputLinks(): newLink = link.copy() newParam = editNode.getInputParamByName(link.dstParam.name) newLink.setDst(editNode, newParam) dupNodeNet.addLink(newLink) newLink.printInfo() # # copy output links to new node # if DEBUG_MODE: print "** duplicate output links ..." for link in gfxNode.node.getOutputLinks(): newLink = link.copy() newParam = editNode.getOutputParamByName(link.srcParam.name) newLink.setSrc(editNode, newParam) dupNodeNet.addLink(newLink) newLink.printInfo() nodeEditDlg = NodeEditorDialog(editNode) if nodeEditDlg.exec_() == QtModule.QDialog.Accepted: # if DEBUG_MODE: print ">> MainWindow.nodeEditDlg Accepted" # # remove original node with links (inputLinksToRemove, outputLinksToRemove) = self.workArea.nodeNet.removeNode(gfxNode.node) for link in inputLinksToRemove: self.workArea.nodeNet.removeLink(link) for link in outputLinksToRemove: self.workArea.nodeNet.removeLink(link) # add duplicate network to current node net self.workArea.nodeNet.add(dupNodeNet) if gfxNode.node.label != editNode.label: self.ui.imageView_ctl.onNodeLabelChanged(gfxNode, editNode.label) # set new node to gfxNode.node gfxNode.node = editNode gfxNode.updateGfxNode() for link in editNode.getInputLinks(): self.workArea.addGfxLink(link) for link in editNode.getOutputLinks(): self.workArea.addGfxLink(link) self.updateNodeParamView() self.workArea.scene().update() else: # remove duplicate node network dupNodeNet.clear() # # onDelete # def onDelete(self): # selected = self.workArea.scene().selectedItems() if len(selected): self.workArea.removeSelected() else: self.ui.imageView_ctl.removeAllViewers() self.workArea.clear() # # onSelectAll # def onSelectAll(self): self.workArea.selectAllNodes() # # onSelectAbove # def onSelectAbove(self): self.workArea.selectAbove(self.getSelectedNode()) # # onSelectBelow # def onSelectBelow(self): self.workArea.selectBelow(self.getSelectedNode()) # # onCopy # def onCopy(self): if DEBUG_MODE: print (">> MainWindow.onCopy") self.workArea.copyNodes(self.clipboard, cutNodes=False) self.setupActions() # # onCut # def onCut(self): if DEBUG_MODE: print (">> MainWindow.onCut") self.workArea.copyNodes(self.clipboard, cutNodes=True) self.setupActions() # # onPaste # def onPaste(self): if DEBUG_MODE: print (">> MainWindow.onPaste") self.workArea.pasteNodes(self.clipboard) # # onDuplicate # def onDuplicate(self): self.workArea.duplicateNodes(preserveLinks=False) # # onDuplicateWithLinks # def onDuplicateWithLinks(self): self.workArea.duplicateNodes(preserveLinks=True) # # onSelectGfxNodes # def onSelectGfxNodes(self, gfxNodes=[], gfxLinks=[]): # self.setupActions() self.workArea.inspectedNode = None if len(gfxNodes) == 1: gfxNode = gfxNodes[0] self.workArea.inspectedNode = gfxNode if gfxNode.node.format == "image": if gfxNode.node.thisIs() == "image_render_node": self.ui.imageView_ctl.selectViewer(gfxNode) self.ui.nodeParam_ctl.setNode(self.workArea.inspectedNode) # # onNodeLabelChanged # def onNodeLabelChanged(self, gfxNode, newLabel): # self.workArea.nodeNet.renameNodeLabel(gfxNode.node, newLabel) gfxNode.updateNodeLabel() self.ui.imageView_ctl.onNodeLabelChanged(gfxNode, newLabel) self.workArea.scene().update() # # onNodeParamChanged # def onNodeParamChanged(self, gfxNode, param): # if DEBUG_MODE: print (">> MainWindow.onNodeParamChanged") # from WorkArea we have GfxNode in signal nodeConnectionChanged # hence need to update nodeParam_ctl if isinstance(gfxNode, GfxNote): if DEBUG_MODE: print ("* update GfxNote") gfxNode.updateGfxNode() self.workArea.scene().update() elif isinstance(gfxNode, GfxSwatchNode): if DEBUG_MODE: print ("* update GfxSwatchNode") gfxNode.setupSwatchParams() gfxNode.setupGeometry() gfxNode.adjustLinks() self.workArea.scene().update() elif isinstance(gfxNode, GfxNode): if DEBUG_MODE: print ("* update GfxNode") gfxNode.updateGfxNode(removeLinks=False) self.updateNodeParamView(gfxNode, param) if self.ui.imageView_ctl.autoUpdate(): self.ui.imageView_ctl.updateViewer() # # onGxNodeParamChanged # def onGfxNodeParamChanged(self, gfxNode, param=None): # if DEBUG_MODE: print (">> MainWindow.onGxNodeParamChanged") # from WorkArea we have GfxNode in signal nodeConnectionChanged # hence need to update nodeParam_ctl if isinstance(gfxNode, GfxNode) or isinstance(gfxNode, GfxSwatchNode): # if DEBUG_MODE : print "* update nodeView" # gfxNode.updateInputParams () self.updateNodeParamView(gfxNode, param) self.workArea.scene().update() if self.ui.imageView_ctl.autoUpdate(): self.ui.imageView_ctl.updateViewer() # # updateNodeParamView # def updateNodeParamView(self, gfxNode=None, param=None): # if DEBUG_MODE: print (">> MainWindow.updateNodeParamView") if gfxNode is not None: print ('** gfxNode = "%s"' % gfxNode.node.label) if param is not None: print ('** param = "%s"' % param.name) print ("** No update") return print ("** Update all parameters") self.ui.nodeParam_ctl.disconnectParamSignals() self.ui.nodeParam_ctl.connectParamSignals() self.ui.nodeParam_ctl.updateGui() # # onFitAll # def onFitAll(self): self.workArea.fitGfxNodesInView(self.workArea.getAllGfxNodes()) # # onFitSelected # def onFitSelected(self): self.workArea.fitGfxNodesInView(self.workArea.selectedNodes) # # onZoomReset # def onZoomReset(self): self.workArea.resetZoom() # # onNewParamView # def onNewParamView(self): print ">> MainWindow.onNewParamView (not implemented yet...)" # # onTabSelected # def onTabSelected(self, idx): # if DEBUG_MODE: print ">> MainWindow.onTabSelected (%d)" % idx self.disconnectWorkAreaSignals() self.ui.imageView_ctl.removeAllViewers() self.workArea = self.ui.tabs.currentWidget() # setup imageView menu for image nodes in new tab imageNodes = self.workArea.getGfxNodesByFormat("image") for gfxNode in imageNodes: if gfxNode.node.thisIs() == "image_render_node": self.ui.imageView_ctl.addViewer(gfxNode) self.connectWorkAreaSignals() self.ui.nodeParam_ctl.setNode(self.workArea.inspectedNode) self.workArea.adjustLinks() # # onTabCloseRequested # def onTabCloseRequested(self, idx): # if DEBUG_MODE: print ">> MainWindow: onTabCloseRequested (%d)" % idx if self.ui.tabs.count() > 1: self.workArea.nodeNet.clear() self.ui.tabs.removeTab(idx) # # onNew # # @QtCore.pyqtSlot () def onNew(self, foo_param=None, tabName="untitled"): # def tabNameExists(self, name): ret = False for i in range(0, self.ui.tabs.count()): if name == str(self.ui.tabs.tabText(i)): ret = True break return ret # newName = tabName if DEBUG_MODE: print "-> self.ui.tabs.count() = %d " % self.ui.tabs.count() if self.workArea != None: if DEBUG_MODE: print "-> create new WorkArea widget" # set unique new name name = newName i = 0 while True: if tabNameExists(self, name): name = newName + str(i) i += 1 continue else: break newName = name workArea = WorkArea() # create new WorkArea instance newTab = self.ui.tabs.addTab(workArea, newName) else: if DEBUG_MODE: print "-> use initial WorkArea widget" workArea = self.ui.workArea # use initial WorkArea widget self.workArea = workArea self.connectWorkAreaSignals() nodeNet = NodeNetwork(newName) workArea.setNodeNetwork(nodeNet) self.ui.tabs.setTabText(self.ui.tabs.indexOf(workArea), newName) self.ui.tabs.setCurrentIndex(self.ui.tabs.indexOf(workArea)) # # onOpen # def onOpen(self): # if DEBUG_MODE: print ">> MainWindow.onOpen" # curDir = app_global_vars["ProjectNetworks"] typeFilter = "Shader networks *.xml;;All files *.*;;" if usePyQt4: filename = str(QtGui.QFileDialog.getOpenFileName(self, "Open file", curDir, typeFilter)) else: (filename, filter) = QtModule.QFileDialog.getOpenFileName(self, "Open file", curDir, typeFilter) if filename != "": if self.openNetwork(filename): self.addRecentNetwork(normPath(filename)) self.buildRecentNetworksMenu() # # openNetwork # def openNetwork(self, filename): # import os ret = True if DEBUG_MODE: print "-> open file %s" % filename if QtCore.QFile.exists(filename): (name, ext) = os.path.splitext(os.path.basename(filename)) self.ui.imageView_ctl.removeAllViewers() self.workArea.clear() self.workArea.nodeNet.name = name self.workArea.nodeNet.fileName = "" self.ui.tabs.setTabText(self.ui.tabs.indexOf(self.workArea), name) self.workArea.openNodeNet(normPath(filename)) else: print "ERROR! filename %s doesn't exist" % filename ret = False return ret # # onOpenRecentNetwork # def onOpenRecentNetwork(self): # action = self.sender() if isinstance(action, QtModule.QAction): if usePyQt4: network = unicode(action.data().toString()) else: network = action.data() if network is not None: if DEBUG_MODE: print ">> onOpenRecentNetwork : %s" % network if not self.openNetwork(network): if usePyQt4: self.recentNetworks.removeAll(network) else: self.recentNetworks.remove(network) # # onOpenRecentProject # def onOpenRecentProject(self): # action = self.sender() if isinstance(action, QtModule.QAction): if usePyQt4: project = unicode(action.data().toString()) else: project = action.data() if project is not None: print ">> onOpenRecentProject : %s" % project project_filename = getDefaultValue(app_settings, "", "project_filename") if openDefaultProject(app_settings, app_global_vars, project, project_filename): # very strange... app_settings doesn't update inside meCommon.openDefaultProject... # though app_global_vars does # have to duplicate this action here... app_settings.setValue("project", app_global_vars["ProjectPath"]) app_settings.setValue("project_shaders", app_global_vars["ProjectShaders"]) app_settings.setValue("project_textures", app_global_vars["ProjectTextures"]) app_settings.setValue("shader_networks", app_global_vars["ProjectNetworks"]) app_settings.setValue("shader_sources", app_global_vars["ProjectSources"]) self.ui.project_ctl.setLibrary(app_global_vars["ProjectNetworks"]) self.setupWindowTitle() else: print "ERROR! project %s doesn't exist" % project if usePyQt4: self.recentProjects.removeAll(network) else: self.recentProjects.remove(network) # # onImport # def onImport(self): # if DEBUG_MODE: print ">> MainWindow.onImport" # curDir = app_global_vars["ProjectNetworks"] typeFilter = "Shader networks *.xml;;All files *.*;;" if usePyQt4: filename = str(QtModule.QFileDialog.getOpenFileName(self, "Import file", curDir, typeFilter)) else: (filename, filter) = QtModule.QFileDialog.getOpenFileName(self, "Import file", curDir, typeFilter) if filename != "": if DEBUG_MODE: print "-> import file %s" % filename self.workArea.insertNodeNet(normPath(filename)) # # onSaveSelected # def onSaveSelected(self): # import os if DEBUG_MODE: print ">> MainWindow.onSaveSelected" singleNode = len(self.workArea.selectedNodes) == 1 curDir = app_global_vars["ProjectNetworks"] saveName = os.path.join(curDir, self.workArea.nodeNet.name + ".xml") typeFilter = "Shader networks *.xml;;All files *.*;;" if usePyQt4: filename = str(QtModule.QFileDialog.getSaveFileName(self, "Save file as", saveName, typeFilter)) else: (filename, filter) = QtModule.QFileDialog.getSaveFileName(self, "Save file as", saveName, typeFilter) if filename != "": if DEBUG_MODE: print "-> save file As %s" % filename (name, ext) = os.path.splitext(os.path.basename(filename)) if singleNode: # save single node print "*** save as single Node" gfxNode = self.getSelectedNode() saveNode = gfxNode.node.copy() saveNode.name = name saveNode.master = normPath(filename) saveNode.save() else: # save selected as network print "*** save as nodenet" saveNodeNet = self.workArea.nodeNetFromSelected(name) saveNodeNet.fileName = normPath(filename) saveNodeNet.save() # # onSave # def onSave(self): # if DEBUG_MODE: print ">> MainWindow.onSave" # if file is new -- use onSaveAs function # curDir = app_global_vars["ProjectNetworks"] if self.workArea.nodeNet.fileName == "": self.onSaveAs() else: if DEBUG_MODE: print "-> save file %s" % self.workArea.nodeNet.fileName self.workArea.nodeNet.save() # # onSaveAs # def onSaveAs(self): # if DEBUG_MODE: print ">> MainWindow.onSaveAs" # import os curDir = app_global_vars["ProjectNetworks"] saveName = os.path.join(curDir, self.workArea.nodeNet.name + ".xml") typeFilter = "Shader networks *.xml;;All files *.*;;" if usePyQt4: filename = str(QtModule.QFileDialog.getSaveFileName(self, "Save file as", saveName, typeFilter)) else: (filename, filter) = QtModule.QFileDialog.getSaveFileName(self, "Save file as", saveName, typeFilter) if filename != "": if DEBUG_MODE: print "-> save file As %s" % filename (name, ext) = os.path.splitext(os.path.basename(filename)) self.workArea.nodeNet.fileName = normPath(filename) self.workArea.nodeNet.name = name self.ui.tabs.setTabText(self.ui.tabs.indexOf(self.workArea), name) self.workArea.nodeNet.save() self.addRecentNetwork(normPath(filename)) self.buildRecentNetworksMenu() self.ui.project_ctl.onReload() # # onHelpNode # def onHelpMode(self, showWhatsThis): # # if showWhatsThis : QtModule.QWhatsThis.enterWhatsThisMode() # else : # QtGui.QWhatsThis.leaveWhatsThisMode () # # onCompileShader # def onCompileShader(self): # if DEBUG_MODE: print ">> MainWindow.onCompileShader" pass
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.setWindowTitle("Demo13_4, Q3DSurface和QSurface3DSeries绘制三维地形图") self.__iniGraph3D() #创建图表 self.ui.sliderZoom.setRange(10, 500) #缺省缩放范围,100=原始大小 self.ui.sliderH.setRange(-180, 180) #水平旋转角度范围 self.ui.sliderV.setRange(-180, 180) #垂直旋转角度范围 splitter = QSplitter(Qt.Horizontal) splitter.addWidget(self.ui.frameSetup) #左侧控制面板 splitter.addWidget(self.__container) #右侧图表 self.setCentralWidget(splitter) #设置主窗口中心组建 ## ==============自定义功能函数======================== def __iniGraph3D(self): ##创建3D图表 self.graph3D = Q3DSurface() self.__container = QWidget.createWindowContainer( self.graph3D) #继承自QWindow,必须如此创建 self.graph3D.activeTheme().setLabelBackgroundEnabled(False) heightMapImage = QImage("mountain.png") #灰度图片 ## heightMapImage=QImage("sea.png") #彩色图片 ## heightMapImage=QImage("SET.png") #载入图片 self.dataProxy = QHeightMapSurfaceDataProxy( heightMapImage) #数据代理 QHeightMapSurfaceDataProxy self.dataProxy.setValueRanges(-5000, 5000, -5000, 5000) self.series = QSurface3DSeries(self.dataProxy) #创建序列 QSurface3DSeries self.series.setItemLabelFormat("(x,z,y)=(@xLabel,@zLabel,@yLabel)") self.series.setFlatShadingEnabled(False) #曲面更光滑 self.series.setMeshSmooth(True) self.series.setDrawMode(QSurface3DSeries.DrawSurface) #只画曲面 self.series.setMesh(QAbstract3DSeries.MeshSphere) #单点样式 self.graph3D.addSeries(self.series) ## 创建坐标轴 axisX = QValue3DAxis() # QValue3DAxis axisX.setTitle("AxisX:西--东") axisX.setTitleVisible(True) axisX.setLabelFormat("%.1f 米") axisX.setRange(-5000, 5000) ## axisX.setAutoAdjustRange(True) self.graph3D.setAxisX(axisX) axisY = QValue3DAxis() axisY.setTitle("AxisY:高度") #垂直方向的坐标轴 axisY.setTitleVisible(True) ## axisY.setRange(-10,10) axisY.setAutoAdjustRange(True) self.graph3D.setAxisY(axisY) axisZ = QValue3DAxis() axisZ.setTitle("AxisZ:南--北") axisZ.setTitleVisible(True) axisZ.setRange(-5000, 5000) ## axisZ.setAutoAdjustRange(True) self.graph3D.setAxisZ(axisZ) self.series.selectedPointChanged.connect(self.do_pointSelected) ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ ##===工具栏actions== @pyqtSlot() ## "曲面颜色" def on_actSurf_Color_triggered(self): color = self.series.baseColor() color = QColorDialog.getColor(color) if color.isValid(): self.series.setBaseColor(color) self.series.setColorStyle(Q3DTheme.ColorStyleUniform) @pyqtSlot() ## "渐变颜色1" def on_actSurf_GradColor1_triggered(self): gr = QLinearGradient() gr.setColorAt(0.0, Qt.black) gr.setColorAt(0.33, Qt.blue) gr.setColorAt(0.67, Qt.red) gr.setColorAt(1.0, Qt.yellow) self.series.setBaseGradient(gr) self.series.setColorStyle(Q3DTheme.ColorStyleRangeGradient) @pyqtSlot() ## "渐变颜色2" def on_actSurf_GradColor2_triggered(self): grGtoR = QLinearGradient() grGtoR.setColorAt(1.0, Qt.red) grGtoR.setColorAt(0.3, Qt.green) grGtoR.setColorAt(0.0, Qt.yellow) self.series.setBaseGradient(grGtoR) self.series.setColorStyle(Q3DTheme.ColorStyleRangeGradient) @pyqtSlot() ## "修改点坐标" def on_actPoint_Modify_triggered(self): position = self.series.selectedPoint() # QPoint if position.x() < 0 or position.y() < 0: return #必须加此判断 item = self.dataProxy.itemAt(position) # QSurfaceDataItem 对象 coord = "%.2f, %.2f, %.2f" % (item.x(), item.z(), item.y()) newText, OK = QInputDialog.getText(self, "修改散点坐标", "按格式输入点的坐标(x,z,y)", QLineEdit.Normal, coord) if not OK: return newText = newText.strip() xzy = newText.split(',') #按逗号分割 if len(xzy) != 3: QMessageBox.critical(self, "错误", "输入坐标数据格式错误") return item.setX(float(xzy[0])) item.setZ(float(xzy[1])) item.setY(float(xzy[2])) self.dataProxy.setItem(position, item) @pyqtSlot() ## "删除行" def on_actPoint_DeleteRow_triggered(self): position = self.series.selectedPoint() # QPoint if position.x() < 0 or position.y() < 0: return #必须加此判断 removeCount = 1 self.dataProxy.removeRows(position.x(), removeCount) ##===三维旋转=== @pyqtSlot(int) ## "预设视角" def on_comboCamera_currentIndexChanged(self, index): cameraPos = Q3DCamera.CameraPreset(index) self.graph3D.scene().activeCamera().setCameraPreset(cameraPos) @pyqtSlot(int) ## "水平旋转" def on_sliderH_valueChanged(self, value): xRot = self.ui.sliderH.value() #水平 self.graph3D.scene().activeCamera().setXRotation(xRot) @pyqtSlot(int) ## "垂直旋转" def on_sliderV_valueChanged(self, value): yRot = self.ui.sliderV.value() #垂直 self.graph3D.scene().activeCamera().setYRotation(yRot) @pyqtSlot(int) ## "缩放" def on_sliderZoom_valueChanged(self, value): zoom = self.ui.sliderZoom.value() #缩放 self.graph3D.scene().activeCamera().setZoomLevel(zoom) @pyqtSlot() ## "复位到FrontHigh视角" def on_btnResetCamera_clicked(self): cameraPos = Q3DCamera.CameraPresetFrontHigh self.graph3D.scene().activeCamera().setCameraPreset(cameraPos) @pyqtSlot() ## "左移" def on_btnMoveLeft_clicked(self): target3D = self.graph3D.scene().activeCamera().target() #QVector3D x = target3D.x() target3D.setX(x + 0.1) self.graph3D.scene().activeCamera().setTarget(target3D) @pyqtSlot() ## "右移" def on_btnMoveRight_clicked(self): target3D = self.graph3D.scene().activeCamera().target() #QVector3D x = target3D.x() target3D.setX(x - 0.1) self.graph3D.scene().activeCamera().setTarget(target3D) @pyqtSlot() ## "上移" def on_btnMoveUp_clicked(self): target3D = self.graph3D.scene().activeCamera().target() #QVector3D z = target3D.z() target3D.setZ(z - 0.1) self.graph3D.scene().activeCamera().setTarget(target3D) @pyqtSlot() ## "下移" def on_btnMoveDown_clicked(self): target3D = self.graph3D.scene().activeCamera().target() #QVector3D z = target3D.z() target3D.setZ(z + 0.1) self.graph3D.scene().activeCamera().setTarget(target3D) ##====图表总体 @pyqtSlot(int) ## "主题" def on_cBoxTheme_currentIndexChanged(self, index): currentTheme = self.graph3D.activeTheme() #Q3DTheme currentTheme.setType(Q3DTheme.Theme(index)) @pyqtSlot(int) ## "字体大小" def on_spinFontSize_valueChanged(self, arg1): font = self.graph3D.activeTheme().font() font.setPointSize(arg1) self.graph3D.activeTheme().setFont(font) @pyqtSlot(int) ## "选择模式" def on_cBoxSelectionMode_currentIndexChanged(self, index): if index <= 7: mode = QAbstract3DGraph.SelectionFlags(index) elif index == 8: # row slice mode = QAbstract3DGraph.SelectionItemAndRow | QAbstract3DGraph.SelectionSlice elif index == 9: # column slice mode = QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice self.graph3D.setSelectionMode(mode) @pyqtSlot(bool) ## "显示背景" def on_chkBoxBackground_clicked(self, checked): self.graph3D.activeTheme().setBackgroundEnabled(checked) @pyqtSlot(bool) ## "显示背景的网格" def on_chkBoxGrid_clicked(self, checked): self.graph3D.activeTheme().setGridEnabled(checked) @pyqtSlot(bool) ## "数值坐标轴反向" def on_chkBoxReverse_clicked(self, checked): self.graph3D.axisY().setReversed(checked) @pyqtSlot(bool) ## "显示阴影" def on_chkBoxShadow_clicked(self, checked): if checked: self.graph3D.setShadowQuality(QAbstract3DGraph.ShadowQualityMedium) else: self.graph3D.setShadowQuality(QAbstract3DGraph.ShadowQualityNone) @pyqtSlot(bool) ## "轴标题可见" def on_chkBoxAxisTitle_clicked(self, checked): self.graph3D.axisX().setTitleVisible(checked) self.graph3D.axisY().setTitleVisible(checked) self.graph3D.axisZ().setTitleVisible(checked) @pyqtSlot(bool) ## "轴标签背景可见" def on_chkBoxAxisBackground_clicked(self, checked): self.graph3D.activeTheme().setLabelBackgroundEnabled(checked) ##===曲面序列设置 @pyqtSlot(int) ## "曲面样式" def on_comboDrawMode_currentIndexChanged(self, index): if index == 0: self.series.setDrawMode(QSurface3DSeries.DrawWireframe) elif index == 1: self.series.setDrawMode(QSurface3DSeries.DrawSurface) else: self.series.setDrawMode(QSurface3DSeries.DrawSurfaceAndWireframe) @pyqtSlot(int) ## "单点形状" def on_cBoxBarStyle_currentIndexChanged(self, index): mesh = QAbstract3DSeries.Mesh(index + 1) # 0=MeshUserDefined self.series.setMesh(mesh) @pyqtSlot(bool) ## "光滑效果" def on_chkBoxSmooth_clicked(self, checked): self.series.setMeshSmooth(checked) @pyqtSlot(bool) ## "单点标签可见" def on_chkBoxItemLabel_clicked(self, checked): self.series.setItemLabelVisible(checked) @pyqtSlot(bool) ## "Flat Shading" def on_chkBoxFlatShading_clicked(self, checked): self.series.setFlatShadingEnabled(checked) ## =============自定义槽函数=============================== def do_pointSelected(self, position): ##选择一个点时触发 if position.x() < 0 or position.y() < 0: self.ui.statusBar.showMessage("没有选中点") return #必须加此判断 item = self.dataProxy.itemAt(position) # QSurfaceDataItem 对象 info = "选中点的坐标,(x,z,y)=(%.2f, %.2f, %.2f)" % (item.x(), item.z(), item.y()) self.ui.statusBar.showMessage(info)
class MainWindow(QMainWindow, Ui_MainWindow): # var initialization settings = QSettings("Mte90", "Plessc") settings.setFallbacksEnabled(False) history = QSettings("Mte90", "Plessc_History") history.setFallbacksEnabled(False) version = "v 1.1" input_less = "" output_css = "" mysize = "" history_field = {} history_field["input"] = [] history_field["output"] = [] option = {} proc = QProcess() less_version = QProcess() watcher = QFileSystemWatcher() def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle("PLessc - lessc not defined") # Connect the function with the signal self.ui.inputChoose.clicked.connect(self.openInputDialog) self.ui.outputChoose.clicked.connect(self.openOutputDialog) self.ui.setBoth.pressed.connect(self.setBoth) self.ui.setStandard.pressed.connect(self.setStandard) self.ui.optionIE.stateChanged.connect(self.setOptionIE) self.ui.optionSourceMap.stateChanged.connect(self.setOptionSourceMap) self.ui.setMinify.stateChanged.connect(self.setMinify) self.ui.inputEdit.pressed.connect(self.openEditor) self.ui.outputLog.clicked.connect(self.openLog) self.ui.lint.clicked.connect(self.lintLog) self.ui.compile.clicked.connect(self.compileIt) self.ui.menuInfo.triggered.connect(self.openInfo) self.ui.menuSetting.triggered.connect(self.openSetDialog) self.proc.finished.connect(self.checkLog) self.less_version.finished.connect(self.updateTitle) signal.signal(signal.SIGINT, signal.SIG_DFL) # hide log self.ui.log.hide() # check lessc version self.loadVersion() # Check the setting for load the path of the file if self.settings.value("input_file") != -1: self.input_less = self.settings.value("input_file") else: self.input_less = "/" if self.settings.value("output_file") != -1: self.output_css = self.settings.value("output_file") else: self.output_css = "/" self.ui.inputFile.setText(self.input_less) self.ui.outputFile.setText(self.output_css) # Check the setting for the minify mode for the css file if self.settings.value("min") == "False": self.option["minify"] = " " self.settings.setValue("min", "False") self.ui.setMinify.setChecked(False) else: self.option["minify"] = "-x" self.settings.setValue("min", "True") self.ui.setMinify.setChecked(True) # Check for the export of the file if self.settings.value("both_or_standard") == "False": self.settings.setValue("both_or_standard", "False") self.ui.setStandard.toggle() else: self.settings.setValue("both_or_standard", "True") self.ui.setBoth.toggle() # Auto compile option if self.settings.value("auto_compile") == "False": self.ui.autoCompile.setChecked(False) else: self.ui.autoCompile.setChecked(True) # Add the function for the autocompile after the load of the setting self.ui.autoCompile.stateChanged.connect(self.autoCompile) self.autoCompile() # Setting for export the css for old IE version if self.settings.value("option_IE") == "False": self.ui.optionIE.setChecked(False) self.option["ie"] = " " else: self.ui.optionIE.setChecked(True) self.option["ie"] = "--no-ie-compat" # Setting for enable Sourcemap if self.settings.value("option_SourceMap") == "False": self.ui.optionSourceMap.setChecked(False) self.option["sourcemap"] = " " else: self.ui.optionSourceMap.setChecked(True) self.option["sourcemap"] = "--source-map" # Resize the window for hide the space of log self.resize(505, 220) # Load History self.loadHistory() self.show() def loadHistory(self): # load history if str(self.history.value("input")) != "None": self.history_field["input"] = str(self.history.value("input")).split(";") if str(self.history.value("output")) != "None": self.history_field["output"] = str(self.history.value("output")).split(";") completer_input = QCompleter(self.history_field["input"], self.ui.inputFile) self.ui.inputFile.setCompleter(completer_input) completer_output = QCompleter(self.history_field["output"], self.ui.outputFile) self.ui.outputFile.setCompleter(completer_output) self.ui.inputFile.editingFinished.connect(self.setInputFile) self.ui.outputFile.editingFinished.connect(self.setOutputFile) def addHistory(self, field, text): # add the path in the history if not exist if text not in self.history_field[field]: self.history_field[field].append(text) self.history.setValue(field, ";".join(self.history_field[field])) # Function for open a dialog for choose the input less file def openInputDialog(self): self.input_less = QFileDialog.getOpenFileName( self, "Choose less file", self.ui.inputFile.text(), "LESS file (*.less)" ) if self.input_less != "": self.ui.inputFile.setText(self.input_less) # Function for open a dialog for choose the output css file def openOutputDialog(self): self.output_css = QFileDialog.getSaveFileName( self, "Set css file", self.ui.outputFile.text(), "CSS file (*.css)" ) if self.output_css != "": self.ui.outputFile.setText(self.output_css) # Save the input file in the setting def setInputFile(self): self.settings.setValue("input_file", self.ui.inputFile.text()) self.addHistory("input", self.ui.inputFile.text()) # Save the output file in the setting def setOutputFile(self): self.settings.setValue("output_file", self.ui.outputFile.text()) self.addHistory("output", self.ui.outputFile.text()) # Save the output export of the css def setBoth(self): self.settings.setValue("both_or_standard", "True") # Save the output export of the css def setStandard(self): self.settings.setValue("both_or_standard", "False") # Check autoCompile and enable the watching of the input less file def autoCompile(self): # If not checked if self.ui.autoCompile.isChecked() == False: self.settings.setValue("auto_compile", "False") # If previosuly was enabled the option this disable the watch of the file try: self.watcher.fileChanged.disconnect() except (RuntimeError, TypeError, NameError): pass else: self.settings.setValue("auto_compile", "True") # Clean the path added to file watching for fix a problem with Qt4 self.watcher.removePath(self.settings.value("input_file")) # Re add of the path self.watcher.addPath(self.settings.value("input_file")) self.watcher.fileChanged.connect(self.compileIt) # Save the Ie Setting def setOptionIE(self): if self.ui.optionIE.isChecked() == False: self.settings.setValue("option_IE", "False") self.option["ie"] = "" else: self.settings.setValue("option_IE", "True") self.option["ie"] = "--no-ie-compat" # Save the SourceMap def setOptionSourceMap(self): if self.ui.optionSourceMap.isChecked() == False: self.settings.setValue("option_SourceMap", "False") self.option["sourcemap"] = " " else: self.settings.setValue("option_SourceMap", "True") self.option["sourcemap"] = "--source-map" # Save the minify setting def setMinify(self): if self.ui.setMinify.isChecked() == False: self.option["minify"] = " " self.settings.setValue("min", "False") else: self.option["minify"] = "-x" self.settings.setValue("min", "True") # Compile the less file def compileIt(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if os.path.isfile(self.settings.value("input_file")): self.ui.log.setHtml("") self.ui.info.setText("Compiling...") if self.settings.value("both_or_standard") == "True": # if both save method True name = os.path.splitext(self.settings.value("output_file"))[0] name += ".min.css" complete = str( self.settings.value("less_path") + self.optionString() + '"' + self.settings.value("input_file") + '" "' + name + '"' ) command = str( self.settings.value("less_path") + self.optionString("minify") + ' --verbose "' + self.settings.value("input_file") + '" "' + self.settings.value("output_file") + '"' ) # Compile the min.css os.system(complete) self.proc.closeWriteChannel() # Compile a standard css self.proc.start(command) self.proc.waitForFinished() self.proc.closeWriteChannel() if os.path.isfile(name): self.ui.info.setText( "File Min Output: <b>" + self.sizeof_fmt(name) + "</b> | File Standard: <b>" + self.sizeof_fmt(self.settings.value("output_file")) + "</b> | " + datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S") ) else: QMessageBox.critical(self.window(), "Output File not exist", "The output file choosen not exist!") else: # if standard = 0 False command = str( self.settings.value("less_path") + self.optionString() + ' --verbose "' + self.settings.value("input_file") + '" "' + self.settings.value("output_file") + '"' ) self.proc.closeWriteChannel() self.proc.start(command) self.proc.waitForFinished() self.proc.closeWriteChannel() if os.path.isfile(self.settings.value("output_file")): self.ui.info.setText( "File Output: <b>" + self.sizeof_fmt(self.settings.value("output_file")) + "</b>" + " | " + datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S") ) else: QMessageBox.critical(self.window(), "Output File not exist", "The output file choosen not exist!") QApplication.restoreOverrideCursor() else: QMessageBox.critical(self.window(), "Input File not exist", "The input file choosen not exist!") print(command) # Clean the path added to file watching for fix a problem with Qt4 self.watcher.removePath(self.settings.value("input_file")) # Readd the path self.watcher.addPath(self.settings.value("input_file")) # Open all the less file in the folder onf the input file def openEditor(self): open_file = self.settings.value("input_file") # get all file less and open on the editor if this option are set if self.settings.value("less_folder") == "True": list_file = "" path_less = os.path.split(str(open_file))[0] for root, dirs, files in os.walk(path_less): files.sort() for name in files: filename = os.path.join(root, name) if filename.endswith(".less"): list_file = list_file + '"' + filename + '" ' open_file = list_file os.system(str(self.settings.value("editor_path") + " " + open_file)) # Show the log def openLog(self): if self.ui.log.isVisible() == True: self.resize(531, 239) self.ui.log.hide() else: self.resize(531, 459) self.ui.log.show() def openSetDialog(self): # i need to explain this?? window = QDialog() ui = SettingDialog() ui.setupUi(window) if ui.exec_() == 1: self.loadVersion() def openInfo(self): QMessageBox.about( self.window(), "About Plessc", "<p align='center'>Plessc " + self.version + " <br><br>By <a href='http://www.mte90.net'><b>Mte90</b></a><br><br>GUI in Python and Qt4 for compile less file<br><br>Tested with lessc 1.7.x of LESS.JS<br><br><small>If other compilers use the same parameters i think that works else some monkeys do it for you</small><br><br>License: GPL 3</p>", ) # http://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size def sizeof_fmt(self, file_): num = os.path.getsize(str(file_)) for x in ["bytes", "KB", "MB", "GB", "TB"]: if num < 1024.0: return str("%3.1f %s") % (num, x) num /= 1024.0 # Clean the output of lessc def replace_all(self, text): # remove the shellcode/ANSI of the color of the text text = text.replace("[39m", "<br>").replace("[31m", "").replace("[22m", "").replace("[0m", "").replace("1b", "") text = ( text.replace("[90m", "") .replace("[27m", "") .replace("[7m", "") .replace("[1m", "") .replace("b''", "") .replace("\n\n", "") .replace("b'", "") ) text = text.replace("\\x", "").replace("\\n\\n'", "").replace("\\n", "") return text.lstrip() # Execeute the lint and show it in the log area def lintLog(self): self.proc.closeWriteChannel() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.proc.start(str(self.settings.value("less_path") + ' --lint "' + self.settings.value("input_file") + '"')) self.openLog() self.proc.closeWriteChannel() QApplication.restoreOverrideCursor() # Check the content of log def checkLog(self): stdout = str(self.proc.readAllStandardOutput()) check = stdout.strip() # If the log not exmpty and length > of 3 print if check is not None and len(check) > 3: output = self.replace_all(stdout) if not output.startswith("lessc: wrote "): self.ui.log.setHtml(self.replace_all(stdout)) self.openLog() else: self.ui.log.setHtml("OK!") # Execute the load of lessc version def loadVersion(self): self.less_version.closeWriteChannel() self.setWindowTitle("PLessc - lessc not defined") self.less_version.start(self.settings.value("less_path"), ["--version"]) # Update the title with less version def updateTitle(self): stdout = str(self.less_version.readAllStandardOutput()) self.setWindowTitle("PLessc - " + self.replace_all(stdout.rstrip("'"))) # Concate all the settings for lessc for use it in the command def optionString(self, remove=[]): # remove the parameter if remove != []: del self.option[remove] string = " ".join("{}".format(val) for key, val in self.option.items()) return " " + string + " "