Esempio n. 1
0
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")
Esempio n. 2
0
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)
Esempio n. 3
0
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))
Esempio n. 4
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
Esempio n. 5
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.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
Esempio n. 6
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.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")
Esempio n. 8
0
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
Esempio n. 9
0
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('使用说明: 按顺序选择统计量')
Esempio n. 10
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.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
Esempio n. 11
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 __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)
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
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.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
Esempio n. 16
0
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
Esempio n. 17
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.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
Esempio n. 18
0
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
Esempio n. 19
0
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
Esempio n. 20
0
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
Esempio n. 21
0
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()
Esempio n. 22
0
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))
Esempio n. 23
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()
Esempio n. 24
0
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")
Esempio n. 25
0
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
Esempio n. 26
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.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
Esempio n. 27
0
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
Esempio n. 28
0
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)
Esempio n. 30
0
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 ()
Esempio n. 31
0
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
Esempio n. 32
0
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()
Esempio n. 33
0
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))
Esempio n. 34
0
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
Esempio n. 35
0
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)
Esempio n. 36
0
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 + " "