class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # Load the ui. self.ui = Ui_MainWindow() self.ui.setupUi(self) # Assign the actions. self.ui.ui_exec_btn.setDefaultAction(self.ui.ui_exec_act) self.ui.ui_show_btn.setDefaultAction(self.ui.ui_show_act) self.ui.ui_count_btn.setDefaultAction(self.ui.ui_count_act) # Create the connections. self.ui.ui_exec_act.triggered.connect(self.execDialog) self.ui.ui_show_act.triggered.connect(self.showDialog) self.ui.ui_count_act.triggered.connect(self.showCount) def execDialog(self): dlg = SampleDialog(self) dlg.exec_() def showDialog(self): dlg = SampleDialog(self) dlg.setAttribute(QtCore.Qt.WA_DeleteOnClose) dlg.show() def showCount(self): count = len(self.findChildren(QtGui.QDialog)) QtGui.QMessageBox.information(self, "Dialog Count", str(count))
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.nameLabel.setProperty("class", "mandatory QLabel") self.styleSheetEditor = StyleSheetEditor(self) self.statusBar().addWidget(QLabel("Ready")) self.ui.exitAction.triggered.connect(QApplication.instance().quit) self.ui.aboutQtAction.triggered.connect(QApplication.instance().aboutQt) def on_editStyleAction_triggered(self): self.styleSheetEditor.show() self.styleSheetEditor.activateWindow() def on_aboutAction_triggered(self): QMessageBox.about( self, "About Style sheet", "The <b>Style Sheet</b> example shows how widgets can be " "styled using " '<a href="http://doc.qt.digia.com/4.5/stylesheet.html">Qt ' "Style Sheets</a>. Click <b>File|Edit Style Sheet</b> to pop " "up the style editor, and either choose an existing style " "sheet or design your own.", )
def main(): app = QApplication(sys.argv) window = QDialog() mainmenu = QMainWindow() ui = Ui_MainWindow() ui.setupUi(mainmenu) mainmenu.show() sys.exit(app.exec_())
def setupUi(self, MainWindowBase): """setup the window. First, the method of the base class is called, and then all the functionality is installed (signal/slot connections mainly). """ Ui_MainWindow.setupUi(self, MainWindowBase) self.widget = MainWindowBase QObject.connect(self.actionAbout, SIGNAL("triggered()"), self.openAbout) QObject.connect(self.actionFileOpen, SIGNAL("triggered()"), self.openFile) self.statusBar().showMessage(self.tr("Ready"))
def setupUi(window): pkg_path = os.path.dirname(__file__) mainwindow_file = os.path.join(pkg_path, 'mainwindow.ui') if os.path.exists(mainwindow_file): from PyQt4 import uic ui = uic.loadUi(mainwindow_file, window) else: from ui_mainwindow import Ui_MainWindow ui = Ui_MainWindow() ui.setupUi(window) return ui
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.gl_widget = GLWidget() self.ui.gl_layout.addWidget(self.gl_widget) #singal slot connect # self.connect(self.ui.apk1_open, SIGNAL('clicked()'),self.apk1_open_onclicked) # @pyqtSlot() # def apk1_open_onclicked(self): # self.emit(SIGNAL('open_apk1'))
class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super().__init__(parent) # UI initialize self.ui = Ui_MainWindow() self.ui.setupUi(self) self.initModels() self.initProgress() self.connectProgress(self.jsonModel) def initModels(self): self.jsonModel = JsonTreeModel(self) self.ui.treeView.setModel(self.jsonModel) def initProgress(self): self.progress = QtWidgets.QProgressBar(self.ui.statusbar) self.progress.setVisible(False) def connectProgress(self, obj): obj.startProgress.connect(self.progress.setRange) obj.startProgress.connect(self.startProgress) obj.updateProgress.connect(self.progress.setValue) obj.finishProgress.connect(self.finishProgress) @QtCore.pyqtSlot() def startProgress(self): self.progress.setValue(0) self.progress.setVisible(True) @QtCore.pyqtSlot() def finishProgress(self): self.progress.setVisible(False) @QtCore.pyqtSlot() def on_actionOpen_triggered(self): filepath, ext_filter = QtWidgets.QFileDialog.getOpenFileName(self, '', '.', self.tr('Json (*.json)') ) if not filepath: return with BusyCursor(self): data = json.load(open(str(filepath))) self.jsonModel.setJsonDocument(data)
class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.resize(1024, 768) self.mostWatchedItems = MostWatchedItems() self.ui.tabWidget.addTab(self.mostWatchedItems, 'Most Watched Items') self.topSellingProducts = TopSellingProducts() self.ui.tabWidget.addTab(self.topSellingProducts, 'Top Selling Products') self.popularItems = PopularItems() self.ui.tabWidget.addTab(self.popularItems, 'Popular Items') self.popularSearches = PopularSearches() self.ui.tabWidget.addTab(self.popularSearches, 'Popular Searches')
class MainWindow(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.rerun_btn.clicked.connect(self.rerun) self.source = NI6009() self.timer = QtCore.QTimer() self.redraw_interval = 50 # (ms) self.timer.timeout.connect(self.replot) def replot(self): self.ui.plotter.replotWith(xs=np.arange(0,1000), ys=self.source.data()) self.timer.start() def rerun(self): self.timer.stop() self.source.reads_per_run = int(self.ui.num_reads.text()) self.source.sample_rate = int(self.ui.num_samples.text()) self.timer.start()
class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.nameLabel.setProperty('class', 'mandatory QLabel') self.styleSheetEditor = StyleSheetEditor(self) self.statusBar().addWidget(QtGui.QLabel("Ready")) self.ui.exitAction.triggered.connect(QtGui.qApp.quit) self.ui.aboutQtAction.triggered.connect(QtGui.qApp.aboutQt) def on_editStyleAction_triggered(self): self.styleSheetEditor.show() self.styleSheetEditor.activateWindow() def on_aboutAction_triggered(self): QtGui.QMessageBox.about(self, "About Style sheet", "The <b>Style Sheet</b> example shows how widgets can be " "styled using " "<a href=\"http://qt.nokia.com/doc/4.7/stylesheet.html\">Qt " "Style Sheets</a>. Click <b>File|Edit Style Sheet</b> to pop " "up the style editor, and either choose an existing style " "sheet or design your own.")
class MainWindow(QMainWindow): tempList = [] curTemp = 0 curPower = 0 curGear = 0 curDoorWindowState = 0 run = True timer = QTimer() ser = serial.Serial() def __init__(self): QMainWindow.__init__(self) self.ser.port = sys.argv[1] self.ser.baudrate = 115200 self.ser.timeout = 0.5 self.ser.write_timeout = 0.5 self.ser.open() if not self.ser.is_open: sys.exit(-1) self.setWindowTitle("Interface Technology") self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.curve.installEventFilter(self) self.timer.start(1000) self.connect(self.timer, SIGNAL("timeout()"), self.refresh) self.connect(self.timer, SIGNAL("timeout()"), self.update) self.ui.setTemp.valueChanged.connect(self.onSetTempChanged) self.ui.setWind.valueChanged.connect(self.onSetWindChanged) self.ui.checkBox_1.clicked.connect(self.onCheckBoxClicked) self.ui.checkBox_2.clicked.connect(self.onCheckBoxClicked) self.ui.checkBox_3.clicked.connect(self.onCheckBoxClicked) self.ui.checkBox_4.clicked.connect(self.onCheckBoxClicked) self.ui.checkBox_5.clicked.connect(self.onCheckBoxClicked) self.ui.checkBox_6.clicked.connect(self.onCheckBoxClicked) self.tempList = [0 for n in range(0, 61)] self.ui.power.setText('%.2f W' % self.curPower) self.ui.gear.setText('%d D' % self.curGear) #self.send(b'P%d\n' % self.curPower) #self.send(b'L%d\n' % self.curGear) thread = threading.Thread(target=self.recv, args=[]) thread.start() def onSetTempChanged(self, value_as_double): oldPower = self.curPower if self.curTemp > value_as_double: self.curPower = 0 elif self.curTemp < value_as_double: div = value_as_double - self.curTemp self.curPower = min(int(div / 0.5), 9) self.ui.power.setText('%.2f W' % self.curPower) if oldPower != self.curPower: print("SendPower") print(b'P%d\n' % self.curPower) self.send(b'P%d\n' % self.curPower) def onSetWindChanged(self, value_as_int): oldGear = self.curGear self.curGear = max(value_as_int - self.updateDoorWindowState(), 0) self.ui.gear.setText('%d D' % self.curGear) if oldGear != self.curGear: print("SendWind") print(b'L%d\n' % self.curGear) self.send(b'L%d\n' % self.curGear) def eventFilter(self, watched: QObject, event: QEvent) -> bool: if watched == self.ui.curve and event.type() == QEvent.Paint: self.drawCurve() return QWidget.eventFilter(self, watched, event) def refresh(self): self.tempList.append(self.curTemp) if (len(self.tempList) > 61): self.tempList.pop(0) def send(self, data): for item in data: self.ser.write(item) print('Send:' + str(item)) sleep(0.2) def recv(self): while self.run: command = self.ser.readline() if len(command): if command.startswith(b'T'): self.curTemp = float(command.decode('ascii')[1:-1]) self.ui.setTemp.emit(SIGNAL('valueChanged'), self.ui.setTemp.value()) # self.onSetTempChanged(self.ui.setTemp.value()) elif command.startswith(b'S'): self.curDoorWindowState = int( command.decode('ascii')[1:-1]) self.ui.setWind.emit(SIGNAL('valueChanged'), self.ui.setWind.value()) # self.onSetWindChanged(self.ui.setWind.value()) print("Debug:" + command.decode()) #else: # print("Debug:"+command.decode()) def updateDoorWindowState(self): self.ui.checkBox_1.setChecked(self.curDoorWindowState & 0x1) self.ui.checkBox_2.setChecked(self.curDoorWindowState & 0x2) self.ui.checkBox_3.setChecked(self.curDoorWindowState & 0x4) self.ui.checkBox_4.setChecked(self.curDoorWindowState & 0x8) self.ui.checkBox_5.setChecked(self.curDoorWindowState & 0x10) self.ui.checkBox_6.setChecked(self.curDoorWindowState & 0x20) rtn = 0 temp = self.curDoorWindowState for i in range(0, 5): if temp & 0x1: if i <= 1: rtn += 2 else: rtn += 1 temp = temp >> 1 return rtn def onCheckBoxClicked(self): self.updateDoorWindowState() def drawCurve(self): painter = QPainter(self.ui.curve) painter.setPen(QColor(114, 159, 207)) width = self.ui.curve.width() height = self.ui.curve.height() for i in range(0, height, 25): painter.drawLine(0, i, width, i) for i in range(0, width, 20): painter.drawLine(i, 0, i, height) pen = QPen() pen.setColor(QColor(114, 159, 207)) pen.setWidth(2) painter.setPen(pen) painter.setRenderHint(QPainter.Antialiasing, True) maxTemp = max(self.tempList) minTemp = min(self.tempList) stepTemp = max((maxTemp - minTemp) / 10, 0.01) midTemp = (maxTemp + minTemp) / 2.0 fromTemp = (midTemp - stepTemp * 5.5) toTemp = (midTemp + stepTemp * 5.5) gapTemp = 11 * stepTemp for i in range(0, 60): painter.drawLine( i * width / 60.0, height * ((toTemp - self.tempList[i]) / gapTemp), (i + 1) * width / 60.0, height * ((toTemp - self.tempList[i + 1]) / gapTemp)) temp = toTemp self.ui.tempLabel_1.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_2.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_3.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_4.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_5.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_6.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_7.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_8.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_9.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_10.setText("%.2f" % temp) temp -= stepTemp self.ui.tempLabel_11.setText("%.2f" % temp) # for i in range(1,11): # print("tempLabel_%d" % i) # qlabel = self.findChild(QLabel, ("tempLabel_%d" % i)) # print(qlabel) # print(temp) # qlabel.setText("%.2f"%temp) # temp -= stepTemp def closeEvent(self, event: QCloseEvent): self.run = False
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.gestor_particulas = Gestor_Particulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.agregar_final_pushButton.clicked.connect( self.click_agregar_final) self.ui.agregar_inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.orden_id_pushButton.clicked.connect(self.ordenar_por_id) self.ui.orden_velocidad_pushButton.clicked.connect( self.ordenar_por_velocidad) self.ui.orden_distancia_pushButton.clicked.connect( self.ordenar_por_distancia) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.mostrar_pushButton_2.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_tabla) self.ui.pushButton_orden_id_tabla.clicked.connect(self.ordenar_por_id) self.ui.pushButton_orden_velocidad_tabla.clicked.connect( self.ordenar_por_velocidad) self.ui.pushButton_orden_distancia_tabla.clicked.connect( self.ordenar_por_distancia) self.ui.dibujar.clicked.connect(self.dibujar) self.ui.limpiar.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) self.ui.profundidad_pushButton.clicked.connect( self.recorrido_profundidad) self.ui.amplitud_pushButton.clicked.connect(self.recorrido_amplitud) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) def grafo(self): grafo = {} for particula in self.gestor_particulas: A = (particula.origen_x, particula.origen_y) B = (particula.destino_x, particula.destino_y) C = round(particula.distancia, 2) if A in grafo: grafo[A].append((B, C)) else: grafo[A] = [(B, C)] if B in grafo: grafo[B].append((A, C)) else: grafo[B] = [(A, C)] return grafo @Slot() def recorrido_profundidad(self): grafo = self.grafo() origen = (self.ui.origen_x_bus.value(), self.ui.origen_y_bus.value()) rec = self.busqueda_profundidad(grafo, origen) pprint(rec, width=40, indent=1) self.ui.mostrar_aristas_plainText.clear() a = pformat(rec, width=40, indent=1) self.ui.mostrar_aristas_plainText.insertPlainText(a) @Slot() def recorrido_amplitud(self): grafo = self.grafo() origen = (self.ui.origen_x_bus.value(), self.ui.origen_y_bus.value()) rec = self.busqueda_amplitud(grafo, origen) pprint(rec, width=40, indent=1) self.ui.mostrar_aristas_plainText.clear() a = pformat(rec, width=40, indent=1) self.ui.mostrar_aristas_plainText.insertPlainText(a) def busqueda_profundidad(self, grafo: {}, origen): visitados = [] pila = [] recorrido = [] visitados.append(origen) pila.append(origen) while len(pila) > 0: vertice = pila[-1] pila.pop() recorrido.append(vertice) adyacencia = grafo[vertice] for ady in adyacencia: if not ady[0] in visitados: visitados.append(ady[0]) pila.append(ady[0]) return recorrido def busqueda_amplitud(self, grafo: {}, origen): visitados = [] cola = [] recorrido = [] visitados.append(origen) cola.append(origen) while len(cola) > 0: vertice = cola[0] cola.pop(0) recorrido.append(vertice) adyacencia = grafo[vertice] for ady in adyacencia: if not ady[0] in visitados: visitados.append(ady[0]) cola.append(ady[0]) return recorrido @Slot() def ordenar_por_id(self): self.gestor_particulas.orden_por_id() @Slot() def ordenar_por_velocidad(self): self.gestor_particulas.orden_por_velocidad() @Slot() def ordenar_por_distancia(self): self.gestor_particulas.orden_por_distancia() @Slot() def dibujar(self): pen = QPen() pen.setWidth(2) grafo = {} for particula in self.gestor_particulas: A = (particula.origen_x, particula.origen_y) B = (particula.destino_x, particula.destino_y) C = round(particula.distancia, 2) if A in grafo: grafo[A].append((B, C)) else: grafo[A] = [(B, C)] if B in grafo: grafo[B].append((A, C)) else: grafo[B] = [(A, C)] r = particula.red g = particula.green b = particula.blue color = QColor(r, g, b) pen.setColor(color) origen_x = particula.origen_x origen_y = particula.origen_y destino_x = particula.destino_x destino_y = particula.destino_y self.scene.addEllipse(origen_x, origen_y, 3, 3, pen) self.scene.addEllipse(destino_x, destino_y, 3, 3, pen) self.scene.addLine(origen_x, origen_y, destino_x, destino_y, pen) self.ui.mostrar_aristas_plainText.clear() a = pformat(grafo, width=40, indent=1) self.ui.mostrar_aristas_plainText.insertPlainText(a) pprint(grafo, width=40, indent=1) @Slot() def limpiar(self): self.scene.clear() @Slot() def buscar_tabla(self): id = self.ui.buscar_lineEdit.text() encontrado = False for particula in self.gestor_particulas: if id == particula.id: self.ui.tabla_tableWidget.clear() self.ui.tabla_tableWidget.setColumnCount(10) headers = [ "Id", "Origen en x", "Origen en y", "Destino en x", "Destino en y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla_tableWidget.setHorizontalHeaderLabels(headers) self.ui.tabla_tableWidget.setRowCount(1) id_widget = QTableWidgetItem(particula.id) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(particula.velocidad) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla_tableWidget.setItem(0, 0, id_widget) self.ui.tabla_tableWidget.setItem(0, 1, origen_x_widget) self.ui.tabla_tableWidget.setItem(0, 2, origen_y_widget) self.ui.tabla_tableWidget.setItem(0, 3, destino_x_widget) self.ui.tabla_tableWidget.setItem(0, 4, destino_y_widget) self.ui.tabla_tableWidget.setItem(0, 5, velocidad_widget) self.ui.tabla_tableWidget.setItem(0, 6, red_widget) self.ui.tabla_tableWidget.setItem(0, 7, green_widget) self.ui.tabla_tableWidget.setItem(0, 8, blue_widget) self.ui.tabla_tableWidget.setItem(0, 9, distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Advertencia", f'La particula con id "{id}" no fue encontrada') @Slot() def mostrar_tabla(self): self.ui.tabla_tableWidget.setColumnCount(10) headers = [ "Id", "Origen en x", "Origen en y", "Destino en x", "Destino en y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla_tableWidget.setHorizontalHeaderLabels(headers) self.ui.tabla_tableWidget.setRowCount(len(self.gestor_particulas)) row = 0 for particula in self.gestor_particulas: id_widget = QTableWidgetItem(particula.id) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(particula.velocidad) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla_tableWidget.setItem(row, 0, id_widget) self.ui.tabla_tableWidget.setItem(row, 1, origen_x_widget) self.ui.tabla_tableWidget.setItem(row, 2, origen_y_widget) self.ui.tabla_tableWidget.setItem(row, 3, destino_x_widget) self.ui.tabla_tableWidget.setItem(row, 4, destino_y_widget) self.ui.tabla_tableWidget.setItem(row, 5, velocidad_widget) self.ui.tabla_tableWidget.setItem(row, 6, red_widget) self.ui.tabla_tableWidget.setItem(row, 7, green_widget) self.ui.tabla_tableWidget.setItem(row, 8, blue_widget) self.ui.tabla_tableWidget.setItem(row, 9, distancia_widget) row += 1 @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.', 'JSON (*.json)')[0] if self.gestor_particulas.abrir(ubicacion): QMessageBox.information( self, "Exito", "Se abrio con exito el archivo" + ubicacion) else: QMessageBox.critical( self, "Error", "No se pudo abrir con exito el archivo" + ubicacion) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName(self, 'Guardar archivo', '.', 'JSON (*.json)')[0] print(ubicacion) if self.gestor_particulas.guardar(ubicacion): QMessageBox.information( self, "Guardado", "Se guardo con éxito el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo almacenar el archivo" + ubicacion) @Slot() def click_mostrar(self): self.ui.salida.clear() self.ui.salida.insertPlainText(str(self.gestor_particulas)) @Slot() def click_agregar_final(self): ID = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_lineEdit.text() red = self.ui.RGB_red_spinBox.value() green = self.ui.RGB_green_spinBox.value() blue = self.ui.RGB_blue_spinBox.value() particula = Particula(ID, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.gestor_particulas.agregar_final(particula) @Slot() def click_agregar_inicio(self): ID = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_lineEdit.text() red = self.ui.RGB_red_spinBox.value() green = self.ui.RGB_green_spinBox.value() blue = self.ui.RGB_blue_spinBox.value() particula = Particula(ID, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.gestor_particulas.agregar_inicio(particula)
class MainWindow(QMainWindow): def __init__(self, parent=None): """ init UI """ QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionSaveSession.setEnabled(False) self.distributedObjects = DistributedObjects() self.act = self.distributedObjects.actions self.debugController = self.distributedObjects.debugController self.settings = self.debugController.settings self.signalproxy = self.distributedObjects.signalProxy self.pluginloader = PluginLoader(self.distributedObjects) self.editorController = self.distributedObjects.editorController self.act = self.distributedObjects.actions # init RecentFileHandler self.recentFileHandler = RecentFileHandler(self, self.ui.menuRecentlyUsedFiles, self.distributedObjects) self.debugController.executableOpened.connect(self.recentFileHandler.addToRecentFiles) self.debugController.executableOpened.connect(self.__observeWorkingBinary) self.debugController.executableOpened.connect(self.showExecutableName) self.debugController.executableOpened.connect(self.disableButtons) # signal proxy self.signalproxy.inferiorIsRunning.connect(self.targetStartedRunning, Qt.QueuedConnection) self.signalproxy.inferiorStoppedNormally.connect(self.targetStopped, Qt.QueuedConnection) self.signalproxy.inferiorReceivedSignal.connect(self.targetStopped, Qt.QueuedConnection) self.signalproxy.inferiorHasExited.connect(self.targetExited, Qt.QueuedConnection) self.signalproxy.addDockWidget.connect(self.addPluginDockWidget) self.signalproxy.removeDockWidget.connect(self.removeDockWidget) # Plugin Loader self.pluginloader.insertPluginAction.connect(self.addPluginAction) self.ui.actionSavePlugins.triggered.connect(self.showSavePluginsDialog) self.ui.actionLoadPlugins.triggered.connect(self.showLoadPluginsDialog) # Add editor to main window. self.ui.gridLayout.addWidget(self.distributedObjects.editorController.editor_view, 0, 0, 1, 1) self.pluginloader.addAvailablePlugins() # Tell everyone to insert their dock widgets into the main window self.signalproxy.emitInsertDockWidgets() # get filelist dockwidget self.filelist_dockwidget = self.findChild(QDockWidget, "FileListView") self.setWindowFilePath("<none>") self.setupUi() self.createInitialWindowPlacement() self.readSettings() self.quickwatch = QuickWatch(self, self.distributedObjects) self.binaryName = None self.fileWatcher = QFileSystemWatcher() self.fileWatcher.fileChanged.connect(self.__binaryChanged) def setupUi(self): self.__initActions() self.ui.statusLabel = QLabel() self.ui.statusLabel.setText("Not running") self.ui.statusbar.addPermanentWidget(self.ui.statusLabel) self.ui.statusIcon = QLabel() self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_not_running.png")) self.ui.statusbar.addPermanentWidget(self.ui.statusIcon) def __initActions(self): self.disableButtons() self.act.Record.setCheckable(True) self.act.ReverseNext.setEnabled(False) self.act.ReverseStep.setEnabled(False) self.act.SaveFile.setEnabled(False) # debug actions self.ui.menuDebug.addAction(self.act.Run) self.ui.menuDebug.addAction(self.act.Continue) self.ui.menuDebug.addAction(self.act.Interrupt) self.ui.menuDebug.addAction(self.act.Next) self.ui.menuDebug.addAction(self.act.Step) self.ui.menuDebug.addAction(self.act.Finish) self.ui.menuDebug.addAction(self.act.RunToCursor) self.ui.menuDebug.addAction(self.act.Record) self.ui.menuDebug.addAction(self.act.ReverseNext) self.ui.menuDebug.addAction(self.act.ReverseStep) # file actions self.ui.menuFile.insertAction(self.ui.actionSaveSession, self.act.OpenMenu) self.ui.menuFile.addAction(self.act.SaveFile) self.ui.menuFile.addAction(self.act.Exit) # add them to menubar and also menuView to respect order self.ui.menubar.addAction(self.ui.menuFile.menuAction()) self.ui.menubar.addAction(self.ui.menuView.menuAction()) self.ui.menubar.addAction(self.ui.menuDebug.menuAction()) self.ui.menubar.addAction(self.ui.menuHelp.menuAction()) # now make toolbar actions self.act.Open.setMenu(self.ui.menuRecentlyUsedFiles) self.ui.Main.addAction(self.act.Open) self.ui.Main.addAction(self.act.SaveFile) self.ui.Main.addSeparator() self.ui.Main.addAction(self.act.Run) self.ui.Main.addAction(self.act.Continue) self.ui.Main.addAction(self.act.Interrupt) self.ui.Main.addAction(self.act.Next) self.ui.Main.addAction(self.act.Step) self.ui.Main.addAction(self.act.Record) self.ui.Main.addAction(self.act.ReverseNext) self.ui.Main.addAction(self.act.ReverseStep) self.ui.Main.addAction(self.act.Finish) self.ui.Main.addAction(self.act.RunToCursor) self.ui.Main.addSeparator() self.ui.Main.addAction(self.act.Exit) # connect actions self.__connectActions() def __connectActions(self): # file menu self.act.Open.triggered.connect(self.showOpenExecutableDialog) self.act.OpenMenu.triggered.connect(self.showOpenExecutableDialog) self.act.Exit.triggered.connect(self.close) self.act.SaveFile.triggered.connect(self.signalproxy.emitSaveCurrentFile) # debug menu self.act.Run.triggered.connect(self.debugController.run) self.act.Next.triggered.connect(self.debugController.next_) self.act.Step.triggered.connect(self.debugController.step) self.act.Continue.triggered.connect(self.debugController.cont) self.act.Record.triggered.connect(self.toggleRecord) self.act.ReverseStep.triggered.connect(self.debugController.reverse_step) self.act.ReverseNext.triggered.connect(self.debugController.reverse_next) self.act.Interrupt.triggered.connect(self.debugController.interrupt) self.act.Finish.triggered.connect(self.debugController.finish) self.act.RunToCursor.triggered.connect(self.debugController.inferiorUntil) self.ui.actionRestoreSession.triggered.connect(self.distributedObjects.sessionManager.showRestoreSessionDialog) self.ui.actionSaveSession.triggered.connect(self.distributedObjects.sessionManager.showSaveSessionDialog) def addPluginDockWidget(self, area, widget, addToggleViewAction): self.addDockWidget(area, widget) if addToggleViewAction: self.ui.menuShow_View.addAction(widget.toggleViewAction()) def addPluginAction(self, Action): """ show plugin as menu entry """ self.ui.menuPlugins.addAction(Action) def createInitialWindowPlacement(self): """ Saves the window and widget placement after first start of program. """ # check if settings do not exist initExists = self.settings.contains("InitialWindowPlacement/geometry") if not initExists: self.breakpointWidget = self.findChild(QDockWidget, "BreakpointView") self.fileListWidget = self.findChild(QDockWidget, "FileListView") self.dataGraphWidget = self.findChild(QDockWidget, "DataGraphView") self.watchWidget = self.findChild(QDockWidget, "WatchView") self.localsWidget = self.findChild(QDockWidget, "LocalsView") self.stackWidget = self.findChild(QDockWidget, "StackView") self.tracepointWidget = self.findChild(QDockWidget, "TracepointView") self.gdbIoWidget = self.findChild(QDockWidget, "GdbIoView") self.pyIoWidget = self.findChild(QDockWidget, "PyIoView") self.inferiorIoWidget = self.findChild(QDockWidget, "InferiorIoView") # tabify widgets to initial state and save settings self.tabifyDockWidget(self.fileListWidget, self.dataGraphWidget) self.tabifyDockWidget(self.watchWidget, self.localsWidget) self.tabifyDockWidget(self.localsWidget, self.stackWidget) self.tabifyDockWidget(self.stackWidget, self.breakpointWidget) self.tabifyDockWidget(self.breakpointWidget, self.tracepointWidget) self.tabifyDockWidget(self.gdbIoWidget, self.pyIoWidget) self.tabifyDockWidget(self.pyIoWidget, self.inferiorIoWidget) self.settings.setValue("InitialWindowPlacement/geometry", self.saveGeometry()) self.settings.setValue("InitialWindowPlacement/windowState", self.saveState()) def restoreInitialWindowPlacement(self): """ Restores the window placement created by createInitialWindowPlacement(). """ self.restoreGeometry(self.settings.value("InitialWindowPlacement/geometry").toByteArray()) self.restoreState(self.settings.value("InitialWindowPlacement/windowState").toByteArray()) def showOpenExecutableDialog(self): filename = str(QFileDialog.getOpenFileName(self, "Open Executable", self.recentFileHandler.getDirOfLastFile())) if filename != "": self.debugController.openExecutable(filename) def showLoadPluginsDialog(self): dialog = QFileDialog() dialog.setNameFilter("*.xml") filename = str(dialog.getOpenFileName(self, "Load plugin configuration")) if filename != "": self.pluginloader.getActivePlugins(filename) def showSavePluginsDialog(self): dialog = QFileDialog() dialog.setNameFilter("*.xml") filename = str(dialog.getSaveFileName(self, "Save plugin configuration")) if filename != "": self.pluginloader.savePluginInfo(filename) def showExecutableName(self, filename): self.ui.actionSaveSession.setEnabled(True) # enable saving session self.setWindowFilePath(filename) def targetStartedRunning(self): self.ui.statusLabel.setText("Running") self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_running.png")) self.enableButtons() def targetStopped(self, rec): self.ui.statusLabel.setText("Stopped") self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_stopped.png")) def targetExited(self): self.ui.statusLabel.setText("Not running") self.disableButtons() self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_not_running.png")) def closeEvent(self, event): if not self.distributedObjects.editorController.closeOpenedFiles(): event.ignore() # closing source files may be canceled by user else: self.settings.setValue("geometry", self.saveGeometry()) self.settings.setValue("windowState", self.saveState()) QMainWindow.closeEvent(self, event) self.pluginloader.savePluginInfo() def readSettings(self): self.restoreGeometry(self.settings.value("geometry").toByteArray()) self.restoreState(self.settings.value("windowState").toByteArray()) def toggleRecord(self, check): if check: self.debugController.record_start() self.act.ReverseNext.setEnabled(True) self.act.ReverseStep.setEnabled(True) else: self.debugController.record_stop() self.act.ReverseNext.setEnabled(False) self.act.ReverseStep.setEnabled(False) def enableButtons(self): self.act.Continue.setEnabled(True) self.act.Interrupt.setEnabled(True) self.act.Next.setEnabled(True) self.act.Step.setEnabled(True) self.act.Finish.setEnabled(True) self.act.RunToCursor.setEnabled(True) self.act.Record.setEnabled(True) def disableButtons(self): self.act.Continue.setEnabled(False) self.act.Interrupt.setEnabled(False) self.act.Next.setEnabled(False) self.act.Step.setEnabled(False) self.act.Finish.setEnabled(False) self.act.RunToCursor.setEnabled(False) self.act.Record.setChecked(False) self.act.Record.setEnabled(False) def __observeWorkingBinary(self, filename): """ Private Method to Observe Debugged Binary """ if self.binaryName != None: self.fileWatcher.removePath(self.binaryName) self.fileWatcher.addPath(filename) self.binaryName = filename def __binaryChanged(self): """ Slot for FileWatcher - Using QtMessagebox for interaction""" box = QtGui.QMessageBox() if ( box.question(self, "Binary Changed!", "Reload File?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) == QtGui.QMessageBox.Yes ): self.debugController.openExecutable(self.binaryName) else: self.fileWatcher.removePath(self.binaryName) self.fileWatcher.addPath(self.binaryName)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.particulas = Particulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.agregar_inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.agregar_final_pushButton.clicked.connect( self.click_agregar_final) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName(self, "Abrir archivo", ".", "JSON (*.json)")[0] if self.particulas.abrir(ubicacion): QMessageBox.information(self, "Éxito", "Se abrió el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "Error al abrir el archivo" + ubicacion) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName(self, "Guardar archivo", ".", "JSON (*.json)")[0] print(ubicacion) if self.particulas.guardar(ubicacion): QMessageBox.information(self, "Éxito", "Se pudo crear el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo" + ubicacion) @Slot() def click_agregar_inicio(self): id = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_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, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.particulas.agregar_inicio(particula) @Slot() def click_agregar_final(self): id = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_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, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.particulas.agregar_final(particula) @Slot() def click_mostrar(self): self.ui.cuadro.clear() self.ui.cuadro.insertPlainText(str(self.particulas))
def __init__(self): super(MainWindow, self).__init__() ui = Ui_MainWindow() ui.setupUi(self)
class MainWindow(QWidget): """The main window of the program""" def __init__(self, testing=False): # Initialize object using ui_mainwindow super(MainWindow, self).__init__() self.window = QMainWindow() self.ui = Ui_MainWindow() self.ui.setupUi(self.window) self.connectSlots() self.testing = testing self.scheduler = Scheduler() def connectSlots(self): """connect the various ui signals to their slots""" self.ui.addSoloParticipantBtn.clicked.connect(self.addSoloParticipantBtn_clicked) self.ui.addGroupParticipantBtn.clicked.connect(self.addGroupParticipantBtn_clicked) self.ui.addTeacherBtn.clicked.connect(self.addTeacherBtn_clicked) self.ui.addEntryBtn.clicked.connect(self.addEntryBtn_clicked) self.ui.makeScheduleBtn.clicked.connect(self.makeScheduleBtn_clicked) self.ui.loadScheduleBtn.clicked.connect(self.loadScheduleBtn_clicked) self.ui.editParticipantBtn.clicked.connect(self.editParticipantBtn_clicked) self.ui.editTeacherBtn.clicked.connect(self.editTeacherBtn_clicked) self.ui.editEntryBtn.clicked.connect(self.editEntryBtn_clicked) self.ui.deleteParticipantBtn.clicked.connect(self.deleteParticipantBtn_clicked) self.ui.deleteTeacherBtn.clicked.connect(self.deleteTeacherBtn_clicked) self.ui.deleteEntryBtn.clicked.connect(self.deleteEntryBtn_clicked) self.ui.backupDbBtn.clicked.connect(self.backupDbBtn_clicked) self.ui.restoreDbBtn.clicked.connect(self.restoreDbBtn_clicked) self.ui.createNewDbBtn.clicked.connect(self.createNewDbBtn_clicked) self.ui.entriesByDisciplineBtn.clicked.connect(self.entriesByDisciplineBtn_clicked) self.ui.entriesByTeacherBtn.clicked.connect(self.entriesByTeacherBtn_clicked) # self.ui.entriesByGroupBtn.clicked.connect(self.entriesByGroupBtn_clicked) self.ui.dumpBtn.clicked.connect(self.dumpBtn_clicked) ###### Slots ###### def addSoloParticipantBtn_clicked(self): dialog = AddSoloParticipantDialog(testing=self.testing) # For Modal dialog dialog.exec_() def addGroupParticipantBtn_clicked(self): dialog = AddGroupParticipantDialog(testing=self.testing) # For Modal dialog dialog.exec_() def addTeacherBtn_clicked(self): dialog = AddTeacherDialog(testing=self.testing) # For Modal dialog dialog.exec_() def addEntryBtn_clicked(self): dialog = AddEntryDialog(testing=self.testing) # For Modal dialog dialog.exec_() def makeScheduleBtn_clicked(self): ### Test Code ### # s1Start = datetime.datetime(2014, 4, 7, 9) # s1End = datetime.datetime(2014, 4, 7, 12) # s2Start = datetime.datetime(2014, 4, 7, 13) # s2End = datetime.datetime(2014, 4, 7, 17) # s3Start = datetime.datetime(2014, 4, 7, 18) # s3End = datetime.datetime(2014, 4, 7, 21) # sessionDatetimes = [(s1Start, s1End), (s2Start, s2End), (s3Start, s3End)] #### scheduleOptionsDialog = ScheduleOptionsDialog() result = scheduleOptionsDialog.exec_() if result == True: entries = dbInteractionInstance.getAllEntriesInDiscipline(settingsInteractionInstance.loadDiscipline()) solution = self.scheduler.process(entries, settingsInteractionInstance.loadSessionDatetimes()) print solution if solution is None: QMessageBox.warning(self, 'No schedule found', 'No schedule was found for the specified parameters. Try increasing tolerance for overtime or making the sessions longer.', QMessageBox.Ok) return dialog = ScheduleDialog(schedule=solution) result = dialog.exec_() if result == True: pass def loadScheduleBtn_clicked(self): """Loads a schedule from file""" schedule = Schedule() filename = QFileDialog.getOpenFileName(self, "Load Schedule", exportsPath, "Schedule Files (*.sched)") if filename is not None and filename != "": try: schedule.load(filename) dialog = ScheduleDialog(schedule=schedule) result = dialog.exec_() if result == True: pass except Exception: QMessageBox.critical(self, "Error", "Failed to load schedule.", QMessageBox.Ok) def editParticipantBtn_clicked(self): """Opens chooseParticipantDialog then dialog for editing""" dialog = ChooseParticipantDialog() # For Modal dialog result = dialog.exec_() if result == True: participantId = dialog.getParticipantId() # Open appropriate edit dialog with participant if participantId[0] == 's': dialog = EditSoloParticipantDialog(participantId=participantId) dialog.exec_() elif participantId[0] == 'g': dialog = EditGroupParticipantDialog(participantId=participantId) dialog.exec_() else: QMessageBox.critical(self, "Error", "Unrecognized Participant", QMessageBox.Ok) def editTeacherBtn_clicked(self): """Opens chooseTeacherDialog then dialog for editing""" dialog = ChooseTeacherDialog() # For Modal dialog result = dialog.exec_() if result == True: teacherId = dialog.getTeacherId() # Open edit dialog with teacher dialog = EditTeacherDialog(teacherId=teacherId) dialog.exec_() def editEntryBtn_clicked(self): """Opens chooseEntryDialog then dialog for editing""" dialog = ChooseEntryDialog() # For Modal dialog result = dialog.exec_() if result == True: entryId = dialog.entryId # Open edit dialog with entry dialog = EditEntryDialog(entryId=entryId) dialog.exec_() def editParticipantBtn_clicked(self): """Opens chooseParticipantDialog then dialog for editing""" dialog = ChooseParticipantDialog() # For Modal dialog result = dialog.exec_() if result == True: participantId = dialog.getParticipantId() # Open appropriate edit dialog with participant if participantId[0] == 's': dialog = EditSoloParticipantDialog(participantId=participantId) dialog.exec_() elif participantId[0] == 'g': dialog = EditGroupParticipantDialog(participantId=participantId) dialog.exec_() else: QMessageBox.critical(self, "Error", "Unrecognized Participant", QMessageBox.Ok) def deleteTeacherBtn_clicked(self): """Opens chooseTeacherDialog for deleting""" dialog = ChooseTeacherDialog() # For Modal dialog result = dialog.exec_() if result == True: teacherId = dialog.getTeacherId() if QMessageBox.question(self, "Cannot be undone!", "Warning! This action cannot be undone. \nAre you sure you want to delete this teacher/contact?", QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes: # Delete the teacher dbInteractionInstance.deleteTeacherFromId(teacherId) def deleteEntryBtn_clicked(self): """Opens chooseEntryDialog for deleting""" dialog = ChooseEntryDialog() # For Modal dialog result = dialog.exec_() if result == True: entryId = dialog.entryId if QMessageBox.question(self, "Cannot be undone!", "Warning! This action cannot be undone. \nAre you sure you want to delete this entry?", QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes: # Delete the entry dbInteractionInstance.deleteEntryFromId(entryId) def deleteParticipantBtn_clicked(self): """Opens chooseParticipantDialog for deleting""" dialog = ChooseParticipantDialog() # For Modal dialog result = dialog.exec_() if result == True: participantId = dialog.getParticipantId() if QMessageBox.question(self, "Cannot be undone!", "Warning! This action cannot be undone. \nAre you sure you want to delete this participant?", QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes: # Call appropriate delete if participantId[0] == 's': dbInteractionInstance.deleteSoloParticipantFromId(participantId[1:]) elif participantId[0] == 'g': dbInteractionInstance.deleteGroupParticipantFromId(participantId[1:]) else: QMessageBox.critical(self, "Error", "Unrecognized Participant", QMessageBox.Ok) def backupDbBtn_clicked(self): """Copies the current db file to AFS-YYYY-MM-DD-HH-MM-SS.bak""" result = dbInteractionInstance.backupDb() if result == "": QMessageBox.information(self, "Success", "Database successfully backed up.", QMessageBox.Ok) else: QMessageBox.critical(self, "Failed", "Could not create backup. Aborted with error:\n{0}".format(result)) def restoreDbBtn_clicked(self): """Grabs the most recent backup, backs up the current db, copies recent backup to current db""" result = dbInteractionInstance.restoreDb() if result == "": QMessageBox.information(self, "Success", "Database successfully restored.", QMessageBox.Ok) else: QMessageBox.critical(self, "Failed", "Could not restore from backup. Aborted with error:\n{0}".format(result)) def createNewDbBtn_clicked(self): """Backs up current db, then drops and recreates all the tables""" # TODO low priority, probably don't need it until after the festival pass def entriesByDisciplineBtn_clicked(self): """Saves a csv of all the entries sorted by Discipline""" filename = QFileDialog.getSaveFileName(self, "Report Entries by Discipline", exportsPath, "CSV Files (*.csv)") if filename is not None and filename != "": if filename[-4:] != ".csv": filename += ".csv" entries = dbInteractionInstance.getAllEntries() # Get participant and teacher names for entries # Note super bad hack where I replace the ID with a name for entry in entries: participant = dbInteractionInstance.getParticipantFromId(entry.participantID) try: entry.participantID = "{last}, {first}".format(last=participant.last, first=participant.first) except Exception: entry.participantID = "{groupName}".format(groupName=participant.groupName) if entry.teacherID != "": teacher = dbInteractionInstance.getTeacherFromId(entry.teacherID) entry.teacherID = "{last}, {first}".format(last=teacher.last, first=teacher.first) entries.sort(key=lambda x: (x.discipline, x.classNumber, x.participantID)) fout = open(filename, 'w') fout.write(Entry.reportByDisciplineHeader()) for entry in entries: entry.reportByDiscipline(fout) fout.close() QMessageBox.information(self, 'Report Entries by Discipline', 'Report saved to ' + filename, QMessageBox.Ok) def entriesByTeacherBtn_clicked(self): """Saves a csv of all the entries sorted by Teacher""" filename = QFileDialog.getSaveFileName(self, "Report Entries by Teacher", exportsPath, "CSV Files (*.csv)") if filename is not None and filename != "": if filename[-4:] != ".csv": filename += ".csv" entries = dbInteractionInstance.getAllEntries() # Get participant and teacher names for entries # Note super bad hack where I replace the ID with a name for entry in entries: participant = dbInteractionInstance.getParticipantFromId(entry.participantID) try: entry.participantID = "{last}, {first}".format(last=participant.last, first=participant.first) except Exception: entry.participantID = "{groupName}".format(groupName=participant.groupName) if entry.teacherID != "": teacher = dbInteractionInstance.getTeacherFromId(entry.teacherID) entry.teacherID = "{last}, {first}".format(last=teacher.last, first=teacher.first) entries.sort(key=lambda x: (x.teacherID, x.participantID, x.discipline, x.classNumber)) fout = open(filename, 'w') fout.write(Entry.reportByTeacherHeader()) for entry in entries: entry.reportByTeacher(fout) fout.close() QMessageBox.information(self, 'Report Entries by Teacher', 'Report saved to ' + filename, QMessageBox.Ok) def entriesByGroupBtn_clicked(self): """Saves a csv of all the entries sorted by Group""" filename = QFileDialog.getSaveFileName(self, "Report Entries by School/Group", exportsPath, "CSV Files (*.csv)") if filename is not None and filename != "": if filename[-4:] != ".csv": filename += ".csv" entries = dbInteractionInstance.getAllEntries() # TODO sort by school then group name (for group participants only) # entries.sort(key=lambda x: (x.discipline, x.classNumber)) for entry in entries: print entry # TODO write csv QMessageBox.information(self, 'Report Entries by School/Group', 'Report saved to ' + filename, QMessageBox.Ok) def dumpBtn_clicked(self): """Saves a csv of all the data so they can do what they want with it""" filename = QFileDialog.getSaveFileName(self, "Database Dump", exportsPath, "CSV Files (*.csv)") if filename is not None and filename != "": if filename[-4:] != ".csv": filename += ".csv" entries = dbInteractionInstance.getAllEntries() fout = open(filename, 'w') fout.write(Entry.dumpHeader()) for entry in entries: entry.dump(fout) fout.close() QMessageBox.information(self, 'Database Dump', 'Data saved to ' + filename, QMessageBox.Ok) ########## def run(self): # Show the form self.window.show() # Run the application app.exec_()
class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) defaultFile1 = "proj_test.txt"; defaultFile2 = "merNativne_test.txt"; self.set1 = set() self.set2 = set() self.vstup1 = list() self.vstup2 = list() self.row2ID = list() self.presnost = 20 self.currentDir = str(os.path.dirname(os.path.abspath(__file__))+"\\") self.allowedFiles = (".txt",".py", ".TXT") i=0 self.allowedRegExpFiles = "" self.allowedOpenFiles = "" for fileType in self.allowedFiles: if i > 0: self.allowedRegExpFiles = self.allowedRegExpFiles+"|" self.allowedOpenFiles = self.allowedOpenFiles+" " self.allowedRegExpFiles = self.allowedRegExpFiles+"\\"+fileType self.allowedOpenFiles = self.allowedOpenFiles+"*"+fileType i=i+1 self.ui = Ui_MainWindow() self.ui.setupUi(self) # comes in future release icoWindow = QPixmap("icon.png") icoCount = QPixmap("count.png") self.setWindowIcon(QIcon(icoWindow)) self.ui.pushButtonPrepocitat.setIcon(QIcon(icoCount)) self.ui.pushButtonUkazka.setVisible(False) self.ui.labelPresnost.setVisible(False) self.ui.spinBoxPresnost.setVisible(False) self.initTable() self.openAndReadPredloha(self.currentDir+defaultFile1) self.openAndReadMeranie(self.currentDir+defaultFile2) self.ui.lineEditSubor1.setText(self.currentDir+defaultFile1) self.ui.lineEditSubor2.setText(self.currentDir+defaultFile2) #self.on_pushButtonSubor1_released() #self.on_pushButtonSubor2_released() self.bod1 = False self.bod2 = False self.bod3 = False def on_tableWidgetZachytne_cellPressed(self, row, col): if self.ui.radioButton1bod.isChecked(): self.ui.lineEdit1bod.setText(self.readRow(row)) self.bod1 = True if self.ui.radioButton2bod.isChecked(): self.ui.lineEdit2bod.setText(self.readRow(row)) self.bod2 = True if self.ui.radioButton3bod.isChecked(): self.ui.lineEdit3bod.setText(self.readRow(row)) self.bod3 = True def read3points(self): bod1text = re.findall(r'[\w.-]+', self.ui.lineEdit1bod.text()) bod2text = re.findall(r'[\w.-]+', self.ui.lineEdit2bod.text()) bod3text = re.findall(r'[\w.-]+', self.ui.lineEdit3bod.text()) return {'ids':(bod1text[0],bod2text[0],bod3text[0]), 'bod1':(float64(bod1text[1]),float64(bod1text[2]),float64(bod1text[3])), 'bod2':(float64(bod2text[1]),float64(bod2text[2]),float64(bod2text[3])), 'bod3':(float64(bod3text[1]),float64(bod3text[2]),float64(bod3text[3]))} def on_spinBoxPresnost_editingFinished(self): self.presnost = self.spinBoxPresnost.value() def on_lineEditSubor1_editingFinished(self): self.openAndReadPredloha(self.ui.lineEditSubor1.text()) def on_lineEditSubor2_editingFinished(self): self.openAndReadMeranie(self.ui.lineEditSubor2.text()) def on_pushButtonObnovit_released(self): self.initTable() def on_pushButtonVsetky_released(self): rows = self.ui.tableWidgetZachytne.rowCount() cols = self.ui.tableWidgetZachytne.columnCount() selection_model = self.ui.tableWidgetZachytne.selectionModel() zero = self.ui.tableWidgetZachytne.model().index(0, 0); bottomRight = self.ui.tableWidgetZachytne.model().index(rows - 1, cols - 1); selection = QItemSelection(zero, bottomRight) #selection.merge(QItemSelection(zero, bottomRight),QItemSelectionModel.Select) self.ui.tableWidgetZachytne.selectionModel().select(selection, QItemSelectionModel.Select) # open input files from dialog browsers def on_pushButtonSubor1_released(self): fileName, _ = QFileDialog.getOpenFileName(self, "Otvor Subor - Body Predlohy", self.currentDir, "Podporovane Subory ("+self.allowedOpenFiles+")") if fileName: self.openAndReadPredloha(fileName) def on_pushButtonSubor2_released(self): fileName, _ = QFileDialog.getOpenFileName(self, "Otvor Subor - Body z Merania", self.currentDir, "Podporovane Subory ("+self.allowedOpenFiles+")") if fileName: self.openAndReadMeranie(fileName) # drag and drop of input files def findFilePath(self, text): rx = QRegExp("((file:///).*("+self.allowedRegExpFiles+"))") rx.setPatternSyntax(QRegExp.RegExp2) index = rx.indexIn(text) if -1 != index: return (index, rx.cap(0)[8:]) return (-1, "") def on_plainTextEditPredloha_textChanged(self): text = self.ui.plainTextEditPredloha.document().toPlainText() possibleFile = self.findFilePath(text) if possibleFile[0] != -1: self.openAndReadPredloha(possibleFile[1]) else: di = self.parseTableTxt(text) self.set1 = di['set'] self.initTable() def openAndReadPredloha(self, fileName): file = QFile(fileName) if not file.open(QFile.ReadOnly | QFile.Text): QMessageBox.warning(self, "Transformacia Bodov", "Chyba pri otvarani suboru %s:\n%s." % (fileName, file.errorString())) else: di = self.parseTableTxt(self.readTextFile(file)) self.ui.plainTextEditPredloha.setPlainText(di['text']) self.set1 = di['set'] self.initTable() def parseTableTxt(self, text ): rows = text.split("\n") rows.sort() outText = "" setPts = set() prevRow = list() for row in rows: if len(row) > 6 and row != prevRow : prevRow = row outText = outText+row+"\n" cols = re.findall(r'[\w.-]+', row) # replaced row.split(" ") - working for multiple delimiters #print(cols) if len(cols) > 3: setPts.add((cols[0],cols[1],cols[2],cols[3])) return {'text':outText,'set':setPts} def readRow(self, row): tmpList = list() for col in range(0,self.ui.tableWidgetZachytne.columnCount()): item = self.ui.tableWidgetZachytne.item(row, col) for i in range(0,3): if not self.is_number(item.text()): QMessageBox.warning(self, "Chyba vstupu", "Medzi zachytnymi bodmi v tabulke je neciselny vstup!\nRiadok: %s" % self.row2ID[row]) return False if i == item.column(): tmpList.append(float64(item.text())) if len(tmpList) == 3: return str(self.row2ID[row])+" "+str(tmpList[0])+" "+str(tmpList[1])+" "+str(tmpList[2]) def initTable(self): commonIDs = set() set1IDs = set() set2IDs = set() for a in self.set1: set1IDs.add(a[0]) for a in self.set2: set2IDs.add(a[0]) commonIDs = set1IDs.intersection(set2IDs) commonRows = list() listSet2 = list(self.set2) for a in self.sorted_nicely( commonIDs ): for b in listSet2: if a == b[0]: commonRows.append(b) # see dependent vector dependentVectors = dict() for a in commonRows: for b in commonRows: try: if self.is_number(a[1]) and self.is_number(b[1]) and self.is_number(a[2]) and self.is_number(b[2]) and self.is_number(a[3]) and self.is_number(b[3]): kx = float(a[1]) / float(b[1]) ky = float(a[2]) / float(b[2]) kz = float(a[3]) / float(b[3]) if kx == ky and kx == kz and a != b: randColor = QColor.fromHsv(qrand() % 256, 230, 220) dependentVectors[a[0]]=randColor dependentVectors[b[0]]=randColor except ZeroDivisionError: xxx = 0 #print("division by zero") self.ui.tableWidgetZachytne.setRowCount(len(commonIDs)) self.ui.tableWidgetZachytne.setColumnCount(3) rowIDs = list() colIDs = list(["X","Y","Z"]) self.ui.tableWidgetZachytne.setHorizontalHeaderLabels(colIDs) self.ui.tableWidgetZachytne.setSelectionBehavior(QTableWidget.SelectRows) row = 0 for curRow in commonRows: xItem = QTableWidgetItem(curRow[1]) yItem = QTableWidgetItem(curRow[2]) zItem = QTableWidgetItem(curRow[3]) # if dependent : rows will be filled with same color if curRow[0] in dependentVectors: xItem.setBackground(dependentVectors[curRow[0]]) yItem.setBackground(dependentVectors[curRow[0]]) zItem.setBackground(dependentVectors[curRow[0]]) # bg color with red if not a number if not self.is_number(curRow[1]): xItem.setBackground(Qt.red) # bg color with red if not a number if not self.is_number(curRow[2]): yItem.setBackground(Qt.red) # bg color with red if not a number if not self.is_number(curRow[3]): zItem.setBackground(Qt.red) self.ui.tableWidgetZachytne.setItem(row, 0, xItem) self.ui.tableWidgetZachytne.setItem(row, 1, yItem) self.ui.tableWidgetZachytne.setItem(row, 2, zItem) rowIDs.append(str(curRow[0])) row=row+1 self.ui.tableWidgetZachytne.setVerticalHeaderLabels(rowIDs) self.row2ID = rowIDs def sorted_nicely(self, l ): """ Sort the given iterable in the way that humans expect.""" convert = lambda text: int(text) if text.isdigit() else text alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] return sorted(l, key = alphanum_key) def is_number(self, s): try: float(s) return True except ValueError: return False def on_plainTextEditMeranie_textChanged(self): text = self.ui.plainTextEditMeranie.document().toPlainText() possibleFile = self.findFilePath(text) if possibleFile[0] != -1: self.openAndReadMeranie(possibleFile[1]) else: di = self.parseTableTxt(text) self.set2 = di['set'] self.initTable() def openAndReadMeranie(self, fileName): file = QFile(fileName) if not file.open(QFile.ReadOnly | QFile.Text): QMessageBox.warning(self, "Transformacia Bodov", "Chyba pri otvarani suboru %s:\n%s." % (fileName, file.errorString())) else: di = self.parseTableTxt(self.readTextFile(file)) self.ui.plainTextEditMeranie.setPlainText(di['text']) self.set2 = di['set'] self.initTable() def readTextFile(self, file): inf = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) text = inf.readAll() QApplication.restoreOverrideCursor() return text # saving of outputs def on_pushButtonUlozit_released(self): self.ui.plainTextEditTransformovane.appendPlainText("ulozit") if self.ui.plainTextEditTransformovane.document().isModified(): self.saveAs() self.ui.plainTextEditTransformovane.document().setModified(False) def saveAs(self): fileName, _ = QFileDialog.getSaveFileName(self) if fileName: return self.saveFile(fileName) return False def saveFile(self, fileName): file = QFile(fileName) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, "Transformacia Bodov", "Nemozno zapisat do suboru %s:\n%s." % (fileName, file.errorString())) return False outf = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) outf << self.ui.plainTextEditTransformovane.toPlainText() QApplication.restoreOverrideCursor() return True # future projects def on_pushButtonUkazka_released(self): QMessageBox.information(self, "Not Implemented Yet", "This should show all three datasets in opengl for visualization") # the big thing : MATH JOB def on_pushButtonPrepocitat_released(self): self.vstup1 = list() self.vstup2 = list() self.vstup2all = list() self.pts3id = list() tmpList = list() selectionIDs = list() counter = 0; for item in self.ui.tableWidgetZachytne.selectedItems(): #print("row %s" % item.row()) for i in range(0,3): if not self.is_number(item.text()): QMessageBox.warning(self, "Chyba vstupu", "Medzi zachytnymi bodmi v tabulke je neciselny vstup!\nRiadok: %s" % item.row()) return False if i == item.column(): print(float64(item.text())) tmpList.append(float64(item.text())) #print("tmpList %s" % tmpList) if len(tmpList) == 3: self.vstup2.append(tmpList) selectionIDs.append(self.row2ID[item.row()]) counter = counter + 1 tmpList = list() for rowIn1 in self.set1: if rowIn1[0] == self.row2ID[item.row()]: self.vstup1.append( (float64(rowIn1[1]),float64(rowIn1[2]),float64(rowIn1[3])) ) break tmpList = list() for row in range(0,self.ui.tableWidgetZachytne.rowCount()): for col in range(0,self.ui.tableWidgetZachytne.columnCount()): item = self.ui.tableWidgetZachytne.item(row, col) for i in range(0,3): if not self.is_number(item.text()): QMessageBox.warning(self, "Chyba vstupu", "Medzi zachytnymi bodmi v tabulke je neciselny vstup!\nRiadok: %s" % item.row()) return False if i == item.column(): tmpList.append(float64(item.text())) if len(tmpList) == 3: self.pts3id.append(self.row2ID[row]) self.vstup2all.append(tmpList) tmpList = list() pts1 = array(self.vstup1).reshape(counter,3) #print("fixne body z predlohy") #print(pts1) pts2 = array(self.vstup2).reshape(counter,3) #print("fixne body z merania") #print(pts2) pts2all = array(self.vstup2all).reshape(self.ui.tableWidgetZachytne.rowCount(),3) #print("toto vsetko pretransformujeme") #print(pts2all) # try: # be aware of transformation direction : from 1 to 2 # in our case we want the other way so the points need to be swapped transformation = self.t_svd(pts2, pts1) pts3 = self.transformPoints(pts2all, transformation['rot'], transformation['trl']) #print("vysledok") #print(pts3) self.ui.lineEditChyba.setText(str(transformation['err'])) cnt = 0 for x in pts3: self.ui.plainTextEditTransformovane.appendPlainText(str(self.pts3id[cnt])+" "+str(x[0])+" "+str(x[1])+" "+str(x[2])) cnt = cnt +1 if self.bod1 and self.bod2 and self.bod3: triBody = self.read3points() vstup1 = list() vstup2 = (triBody['bod1'],triBody['bod2'],triBody['bod3']) for bod in range(0,3): for rowIn1 in self.set1: if rowIn1[0] == triBody['ids'][bod]: vstup1.append( (float64(rowIn1[1]),float64(rowIn1[2]),float64(rowIn1[3])) ) break print("vstup1 pred alg 3 points :") print(vstup1) print("vstup2 pred alg 3 points :") print(vstup2) transform3points = self.alg_3_pts(vstup2, vstup1) pts3 = self.transformPoints2(pts2all, transform3points['rot1'],transform3points['rot2'], transform3points['trl']) self.ui.lineEditChyba_2.setText(str(transform3points['err'])) cnt = 0 for x in pts3: self.ui.plainTextEditTransformovane_2.appendPlainText(str(self.pts3id[cnt])+" "+str(x[0])+" "+str(x[1])+" "+str(x[2])) cnt = cnt +1 def alg_3_pts(self, A, B): print("A") print(A) print("B") print(B) a1 = array(A[0]) a2 = array(A[1]) a3 = array(A[2]) a_12 = a2 - a1 print("a_12 = ") print(a_12) a_13 = a3 - a1 print("a_13 = ") print(a_13) b1 = array(B[0]) b2 = array(B[1]) b3 = array(B[2]) b_12 = b2 - b1 b_13 = b3 - b1 print("a1") print(a1) print("b1") print(b1) print ("translation, tl = b1 - a1") tl = b1 - a1 print (tl) print("verify A + l, a1+l == b1") a1_ = a1 + tl a2_ = a2 + tl a3_ = a3 + tl print(a1_) print(a2_) print(a3_) print("\n----\nR = rot_calc(a_12,b_12)") R = self.rot_calc(a2_,b2) R = self.rot_calc(a_12,b_12) print("verify R.(A-tl) , dot(R,a@) == b@") a1__ = dot(R,a1_) a2__ = dot(R,a2_) a3__ = dot(R,a3_) print(a1__) print(a2__) print(a3__) print("\n----\nR2 = rot_calc(dot(R,a_13),dot(R,b_13))") R2 = self.rot2_calc( ( dot(R,a_13) - b_12),( b_13 - b_12 ) ) print("verify R2+R.(A-tl) , dot(R,a@) == b@") a1___ = dot(R2,dot(R,a1_)) a2___ = dot(R2,dot(R,a2_)) a3___ = dot(R2,dot(R,a3_)) print(a1___) print(a2___) print(a3___) mserr = 0.0 dist = 0.0 i =0 for bod in (b1 - a1___, b2 - a2___, b3 - a3___): for i in range(0,3): print(i) x = bod[i] print(x) dist = dist + power(x,2) print(dist) mserr = sqrt(dist) / 3 print("mserr === ") print(mserr) return {'trl':tl,'rot1':R,'rot2':R2, 'err':mserr} def rot_calc(self, a, b): print("vector a :") print(a) print("vector b :") print(b) print("unit vector au :") au = a/linalg.norm(a) print(au) print("unit vector bu :") bu = b/linalg.norm(b) print(bu) print("c = dot ( au, bu )") c = dot( au, bu ) print (c) print ("v = cross ( a, b )") v = cross(au,bu,axis=0) print(v) print("s = ||v|| = norm ( v )") s = linalg.norm(v) print(s) print ("vx = skew symmetric cross product of vector v") vx = [[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]] print(vx) print("R = (1-c)/power(s,2) * linalg.matrix_power(vx,2) + vx + eye(3,3)") R = (1-c)/power(s,2) * linalg.matrix_power(vx,2) + vx + eye(3,3) print(R) print("verify R*au == bu") print(dot(R,au)) print("verify R*a =aprox= b") print(dot(R,a)) return R def rot2_calc(self, a, b): print("vector a :") print(a) print("vector b :") print(b) print("unit vector au :") au = a/linalg.norm(a) print(au) print("unit vector bu :") bu = b/linalg.norm(b) print(bu) print("c = dot ( au, bu )") c = dot( au, bu ) print (c) print ("v = cross ( a, b )") v = cross(au,bu,axis=0) print(v) print("s = ||v|| = norm ( v )") s = linalg.norm(v) print(s) print ("vx = skew symmetric cross product of vector v") vx = [[0,-v[2],v[1]],[v[2],0,-v[0]],[-v[1],v[0],0]] print(vx) print("R = (1-c)/power(s,2) * linalg.matrix_power(vx,2) + vx + eye(3,3)") R = (1-c)/power(s,2) * linalg.matrix_power(vx,2) + vx + eye(3,3) print(R) print("verify R*au == bu") print(dot(R,au)) print("verify R*a =aprox= b") print(dot(R,a)) return R def t_svd(self, A, B): # function from : http://nbviewer.ipython.org/github/demotu/BMC/blob/master/notebooks/SVDalgorithm.ipynb # Ideally, three non-colinear markers placed on a moving rigid body is everything we need to describe # its movement (translation and rotation) in relation to a fixed coordinate system. However, in pratical # situations of human motion analysis, markers are placed on the soft tissue of a deformable body and this # generates artifacts caused by muscle contraction, skin deformation, marker wobbling, etc. In this situation, # the use of only three markers can produce unreliable results. It has been shown that four or more markers # on the segment followed by a mathematical procedure to calculate the 'best' rigid-body transformation taking # into account all these markers produces more robust results # (Söderkvist & Wedin 1993; Challis 1995; Cappozzo et al. 1997). Am = mean(A, axis=0) # centroid of m1 Bm = mean(B, axis=0) # centroid of m2 #print("Am") #print(Am) #print("Bm") #print(Bm) M = dot((B - Bm).T, (A - Am)) # considering only rotation #print("M") #print(M) # singular value decomposition - decomposes system of at least 3 lineary independent rows to orthonormal matrices U, S, Vt = linalg.svd(M) #print("U") #print(U) #print("Vt") #print(Vt) #print("S") #print(S) # rotation matrix R = dot(U, dot(diag([1, 1, linalg.det(dot(U, Vt))]), Vt)) # translation vector L = B.mean(0) - dot(R, A.mean(0)) # RMSE from fixed points err = 0 for i in range(A.shape[0]): Bp = dot(R, A[i, :]) + L err += sum((Bp - B[i, :])**2) RMSE = sqrt(err/A.shape[0]/3) #print("R") #print(R) #print ("L") #print (L) #print ("RMSE") #print (RMSE) return {'rot':R, 'trl':L, 'err':RMSE} def transformPoints(self, ptsIn, rotation, translation): count = ptsIn.shape[0] #print("count") #print(count) #print("( ---------= \n vystupne bodiky") ptsOutList = list() for i in range(ptsIn.shape[0]): ptsOut = dot(rotation, ptsIn[i, :]) + translation ptsOutList.append(ptsOut) #print (ptsOutList) return ptsOutList def transformPoints2(self, ptsIn, R, R2, translation): count = ptsIn.shape[0] #print("count") #print(count) #print("( ---------= \n vystupne bodiky") ptsOutList = list() for i in range(ptsIn.shape[0]): ptsOut = dot(R2, dot(R, ptsIn[i, :] + translation)) ptsOutList.append(ptsOut) #print (ptsOutList) return ptsOutList
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.administrador_particulas = Administrador() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.pushButton.clicked.connect(self.click_agregar) self.ui.pushButton_3.clicked.connect(self.click_agregar_inicio) self.ui.pushButton_4.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.mostrar_tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_id) self.ui.dibujar.clicked.connect(self.dibujar) self.ui.limpiar.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) self.ui.ordenar_id_pushButton.clicked.connect(self.ordenar_id) self.ui.ordenar_distancia_pushButton.clicked.connect( self.ordenar_distancia) self.ui.ordenar_velocidad_pushButton.clicked.connect( self.ordenar_velocidad) @Slot() def click_mostrar(self): self.ui.plainTextEdit.clear() self.ui.plainTextEdit.insertPlainText( str(self.administrador_particulas)) @Slot() def click_agregar(self): id = self.ui.lineEdit_2.text() origenx = self.ui.spinBox_13.value() origeny = self.ui.spinBox_16.value() destinox = self.ui.spinBox_15.value() destinoy = self.ui.spinBox_11.value() velocidad = self.ui.lineEdit.text() red = self.ui.spinBox_9.value() green = self.ui.spinBox_10.value() blue = self.ui.spinBox_14.value() particula = Particula(id, origenx, origeny, destinox, destinoy, velocidad, red, green, blue) self.administrador_particulas.agregar_final(particula) @Slot() def click_agregar_inicio(self): id = self.ui.lineEdit_2.text() origenx = self.ui.spinBox_13.value() origeny = self.ui.spinBox_16.value() destinox = self.ui.spinBox_15.value() destinoy = self.ui.spinBox_11.value() velocidad = self.ui.lineEdit.text() red = self.ui.spinBox_9.value() green = self.ui.spinBox_10.value() blue = self.ui.spinBox_14.value() @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName(self, 'Abrir Archivo', '.', 'JSON (*.json)')[0] if self.administrador_particulas.abrir(ubicacion): QMessageBox.information(self, "Éxito", "Se abrió el archivo " + ubicacion) else: QMessageBox.critical(self, "Error", "Error al abrir el archivo " + ubicacion) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName(self, 'Guardar Archivo', '.', 'JSON (*.json)')[0] print(ubicacion) if self.administrador_particulas.guardar(ubicacion): QMessageBox.information(self, "Éxito", "Se pudo crear el archivo " + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo " + ubicacion) @Slot() def buscar_id(self): id = self.ui.buscar_lineEdit.text() encontrado = False for particula in self.administrador_particulas: if id == particula.id: self.ui.tabla.clear() self.ui.tabla.setColumnCount(10) headers = [ "ID", "Origen_x", "Origen_y", "Destino_x", "Destino_y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(1) id_widget = QTableWidgetItem(str(particula.id)) origenx_widget = QTableWidgetItem(str(particula.origenx)) origeny_widget = QTableWidgetItem(str(particula.origeny)) destinox_widget = QTableWidgetItem(str(particula.destinox)) destinoy_widget = QTableWidgetItem(str(particula.destinoy)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(0, 0, id_widget) self.ui.tabla.setItem(0, 1, origenx_widget) self.ui.tabla.setItem(0, 2, origeny_widget) self.ui.tabla.setItem(0, 3, destinox_widget) self.ui.tabla.setItem(0, 4, destinoy_widget) self.ui.tabla.setItem(0, 5, velocidad_widget) self.ui.tabla.setItem(0, 6, red_widget) self.ui.tabla.setItem(0, 7, green_widget) self.ui.tabla.setItem(0, 8, blue_widget) self.ui.tabla.setItem(0, 9, distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atención!", f'La particula con id "{id}" no fue encontrada') @Slot() def mostrar_tabla(self): self.ui.tabla.setColumnCount(10) headers = [ "ID", "Origen_x", "Origen_y", "Destino_x", "Destino_y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.administrador_particulas)) row = 0 for particula in self.administrador_particulas: id_widget = QTableWidgetItem(str(particula.id)) origenx_widget = QTableWidgetItem(str(particula.origenx)) origeny_widget = QTableWidgetItem(str(particula.origeny)) destinox_widget = QTableWidgetItem(str(particula.destinox)) destinoy_widget = QTableWidgetItem(str(particula.destinoy)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, id_widget) self.ui.tabla.setItem(row, 1, origenx_widget) self.ui.tabla.setItem(row, 2, origeny_widget) self.ui.tabla.setItem(row, 3, destinox_widget) self.ui.tabla.setItem(row, 4, destinoy_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 def wheelEvent(self, event): print(event.delta()) if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def dibujar(self): pen = QPen() pen.setWidth(2) for particula in self.administrador_particulas: r = particula.red g = particula.green b = particula.blue color = QColor(r, g, b) pen.setColor(color) origenx = particula.origenx origeny = particula.origeny destinox = particula.destinox destinoy = particula.destinoy self.scene.addEllipse(origenx, origeny, 3, 3, pen) self.scene.addEllipse(destinox, destinoy, 3, 3, pen) self.scene.addLine(origenx + 3, origeny + 3, destinox, destinoy, pen) @Slot() def limpiar(self): self.scene.clear() @Slot() def ordenar_id(self): self.administrador_particulas.sort_by_id() @Slot() def ordenar_distancia(self): self.administrador_particulas.sort_by_distancia() @Slot() def ordenar_velocidad(self): self.administrador_particulas.sort_by_velocidad()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.cancelButton.setText('Hey')
class MainWindow(QMainWindow): # Signals cellValueChanged = pyqtSignal(int, int) def __init__(self): QMainWindow.__init__(self) """Inicializador de la clase MainWindow.""" self.ui = Ui_MainWindow() self.ui.setupUi(self) """Inicializacion del tablero.""" self.initBoard() """Coneccion de senales.""" self.ui.actionJUEGO_NUEVO.triggered.connect(self.onActionJuegoNuevoTriggered) self.ui.actionSALIR.triggered.connect(self.onActionSalirTriggered) self.ui.actionATRAS.triggered.connect(self.onActionAtrasTriggered) self.loadGamesWindow = LoadGames(self) def initTimer(self, elapsedSeconds): """Funcion que permite inicializar el timer que se utilizara al inicio del juego.""" self.timer = QTimer() self.timer.setInterval(1000) self.timer.start() self.h = elapsedSeconds / 3600 self.m = (elapsedSeconds - 3600*self.h) / 60 self.s = (elapsedSeconds - 3600*self.h) % 60 """Coneccion de senales.""" self.timer.timeout.connect(self.timerTimeout) def stopTimer(self): """Detiene el timer.""" self.timer.stop() def timerTimeout(self): """Funcion que permite tener actualizado el timer mientras el jugador tenga activo el juego.""" self.s = self.s + 1 if self.s > 59: self.s = 0 self.m=self.m + 1 elif self.m > 59: self.m = 0 self.h= self.h + 1 elif self.h > 23: self.h = 0 # Write time in a pushButton self.ui.btnTiempo.setText(QString ("%1:%2:%3") .arg (self.h) .arg (self.m) .arg (self.s) ) def initBoard(self): """Funcion que permite inicializar el tablero con 81 celdas que el jugador tendra le quellar segun el nuevel de dificultad seleccionado al inicio del juego""" self.board = [] self.keyboard = Keyboard(self) for i in range(9*9): x = i % 9 y = i / 9 c = Cell() self.board.append(c) self.ui.board.addWidget(c, y, x) c.setKeyboard(self.keyboard) c.valueChanged.connect(self.setCellValueFromView) def newGame(self, name, elapsedSeconds = 0, sudoku = None): """Se genera un nuevo juego de sudoku con el nombre del jugador y el nivel.""" if sudoku == None: self.sudoku = Sudoku() self.sudoku.shuffle(self.difficulty*9 + 3*9) else: self.sudoku = sudoku self.sudoku.cellValueChanged.connect(self.setCellValue) self.sudoku.triggerChanges() self.sudoku.cellValueChanged.disconnect(self.setCellValue) """Actualiza el modelo cuando la vista es cambiada.""" self.cellValueChanged.connect(self.sudoku.setCellValue) self.initTimer(elapsedSeconds) self.ui.btnJugador.setText(name) def endGame(self): """Finaliza el juego.""" self.stopTimer() userName = str(self.ui.btnJugador.text()) seconds = int(self.s) + int(self.m) * 60 + int(self.h) * 60 * 60 difficulty = ['Easy', 'Medium', 'Hard'][self.difficulty - 1] ''' Check if current score is a high scores''' highscores = HighScore.loadFromFile() highscores.reverse() if seconds < highscores[0].seconds: msj = QMessageBox() msj.setText( "Puntaje alto" ) msj.exec_() '''Put score in highscore''' highscores.append( HighScore(userName, seconds, difficulty) ) highscores.sort() highscores.pop() HighScore.saveToFile(highscores) def setCellValue(self, index, value): self.board[index].setValue(value) '''TODO change color to indicate that it's precalculated''' def setCellValueFromView(self, value): c = self.sender() self.cellValueChanged.emit( self.board.index(c), value ) def onActionSalirTriggered(self): self.close() def setHomeWindow(self, homeWindow): """Metodo que obtiene una referencia de la ventana home. :param self: Referencia a la clase. :param value: Referencia a la ventana home""" self.homeWindow = homeWindow def setDifficulty(self,value): """Se agrega la dificultad a la clase.""" self.difficulty = value def onActionJuegoNuevoTriggered(self): name = self.ui.btnJugador.text() self.newGame(name) def onActionAtrasTriggered(self): self.hide() self.homeWindow.show() def on_endGameButton_triggered(self): msj = QMessageBox() valid = self.sudoku.validate() msj.setText( "Valido" if valid else "No valido" ) msj.exec_() if valid: self.endGame() def on_actionGUARDAR_triggered(self): userName = str(self.ui.btnJugador.text()) seconds = int(self.s) + int(self.m) * 60 + int(self.h) * 60 * 60 games = Game.loadFromFile() games.append( Game(userName, seconds, self.sudoku) ) Game.saveToFile(games) def on_actionCARGAR_triggered(self): self.loadGamesWindow.loadData() self.loadGamesWindow.show() # Signals cellValueChanged = pyqtSignal(int, int) def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.initBoard() self.ui.actionJUEGO_NUEVO.triggered.connect(self.onActionJuegoNuevoTriggered) self.ui.actionSALIR.triggered.connect(self.onActionSalirTriggered) self.ui.actionATRAS.triggered.connect(self.onActionAtrasTriggered) self.loadGamesWindow = LoadGames(self) def initTimer(self, elapsedSeconds): self.timer = QTimer() self.timer.setInterval(1000) self.timer.start() self.h = elapsedSeconds / 3600 self.m = (elapsedSeconds - 3600*self.h) / 60 self.s = (elapsedSeconds - 3600*self.h) % 60 self.timer.timeout.connect(self.timerTimeout) def stopTimer(self): self.timer.stop() def timerTimeout(self): self.s = self.s + 1 if self.s > 59: self.s = 0 self.m=self.m + 1 elif self.m > 59: self.m = 0 self.h= self.h + 1 elif self.h > 23: self.h = 0 # Write time in a pushButton self.ui.btnTiempo.setText(QString ("%1:%2:%3") .arg (self.h) .arg (self.m) .arg (self.s) ) def initBoard(self): self.board = [] self.keyboard = Keyboard(self) for i in range(9*9): x = i % 9 y = i / 9 c = Cell() self.board.append(c) self.ui.board.addWidget(c, y, x) c.setKeyboard(self.keyboard) #self.setStyleSheet("font: italic 13pt Courier 50 Pitch; background-color: rgb(82, 163, 53);"#) # Change cell value when user change cell value c.valueChanged.connect(self.setCellValueFromView) def newGame(self, name, elapsedSeconds = 0, sudoku = None): if sudoku == None: # Generate new sudoku board self.sudoku = Sudoku() self.sudoku.shuffle(self.difficulty*9 + 3*9) else: self.sudoku = sudoku self.sudoku.cellValueChanged.connect(self.setCellValue) self.sudoku.triggerChanges() self.sudoku.cellValueChanged.disconnect(self.setCellValue) # Update the model when the view is changed self.cellValueChanged.connect(self.sudoku.setCellValue) self.initTimer(elapsedSeconds) self.ui.btnJugador.setText(name) def endGame(self): self.stopTimer() userName = str(self.ui.btnJugador.text()) seconds = int(self.s) + int(self.m) * 60 + int(self.h) * 60 * 60 difficulty = ['Easy', 'Medium', 'Hard'][self.difficulty - 1] # Check if current score is a high scores highscores = HighScore.loadFromFile() highscores.reverse() if seconds < highscores[0].seconds: msj = QMessageBox() msj.setText( "Puntaje alto" ) msj.exec_() # Put score in highscore highscores.append( HighScore(userName, seconds, difficulty) ) highscores.sort() highscores.pop() HighScore.saveToFile(highscores) def setCellValue(self, index, value): self.board[index].setValue(value) # TODO change color to indicate that it's precalculated def setCellValueFromView(self, value): c = self.sender() self.cellValueChanged.emit( self.board.index(c), value ) def onActionSalirTriggered(self): self.close() def setHomeWindow(self, homeWindow): self.homeWindow = homeWindow def setDifficulty(self,value): self.difficulty = value def onActionJuegoNuevoTriggered(self): name = self.ui.btnJugador.text() self.newGame(name) def onActionAtrasTriggered(self): self.hide() self.homeWindow.show() def on_endGameButton_triggered(self): msj = QMessageBox() valid = self.sudoku.validate() msj.setText( "Valido" if valid else "No valido" ) msj.exec_() if valid: self.endGame() def on_actionGUARDAR_triggered(self): userName = str(self.ui.btnJugador.text()) seconds = int(self.s) + int(self.m) * 60 + int(self.h) * 60 * 60 games = Game.loadFromFile() games.append( Game(userName, seconds, self.sudoku) ) Game.saveToFile(games) def on_actionCARGAR_triggered(self): self.loadGamesWindow.loadData() self.loadGamesWindow.show()
class ApplicationWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.directorySelect.clicked.connect(self.changeCurrentDirectory) self.listFiles('.') self.loaded_signal = None self.loaded_signal_header = None self.ui.fileList.itemClicked.connect(self.chooseFile) self.ui.channelsDropdown.currentIndexChanged.connect(self.plotSignal) self.ui.refreshSignal.clicked.connect(self.plotSignal) def listFiles(self, dirname): self.cur_dir = dirname self.ui.fileList.clear() for f in os.listdir(dirname): fullfile = os.path.join(dirname, f) # Не выводим каталоги if os.path.isfile(fullfile): # Выводим только .hea файлы file_re = re.compile(r'.*\.hea$') if file_re.match(f) is not None: self.ui.fileList.addItem(f) # Отображение имени текущего каталога на ярлычке max_len = 50 if len(dirname) > max_len: dirname = '.../' + dirname.split(os.sep)[-1] self.ui.directoryLabel.setText(dirname) # Реакция на выбор файла def chooseFile(self, lwi): if lwi is not None: # Полное имя выбранного файла full_file_name = os.path.join(self.cur_dir, lwi.text()) # Отрезаем расширение для чтения с помощью wfdb recordname = '.'.join(full_file_name.split('.')[:-1]) # Чтение сигнала sig, fields = wfdb.rdsamp(recordname) # Не очень понятна обработка ошибок чтения self.loaded_signal = sig self.loaded_signal_header = fields self.updateChannelCombo(sig) self.plotSignal() # Реакция на выбор каталога def changeCurrentDirectory(self): dirname = QFileDialog.getExistingDirectory() if dirname and dirname is not None: self.listFiles(dirname) def updateChannelCombo(self, sig): numch = sig.shape[1] if self.ui.channelsDropdown.count() != numch: self.ui.channelsDropdown.clear() self.ui.channelsDropdown.addItems([str(x+1) for x in range(numch)]) def plotSignal(self): chan = self.ui.channelsDropdown.currentIndex() fs = self.loaded_signal_header.get("fs", 360) self.ui.samplingFreq.setText(str(fs) + " Hz") dur = np.ceil(len(self.loaded_signal[:, chan]) / fs) self.ui.signalDuration.setText(str(dur) + " s") self.ui.signalUnits.setText(self.loaded_signal_header["units"][chan]) samples = int(self.config_data["display"]["defaultTimeSpan"] * fs) # Если samples больше, чем размер файла - ошибки не будет if self.ui.autoProcessing.isChecked(): # Считывание параметров привязки unbias_wnd = 0 if self.ui.zeroBaseline.isChecked(): try: unbias_wnd = int(self.ui.biasWindowLen.text()) except: print("Unable to convert value") try: pk_interval = int(self.ui.minRinterval.text()) except: pk_interval = self.config_data["rDetect"]["peakIntervalMs"] print("Unable to convert value") pk_len = self.config_data["rDetect"]["peakLengthMs"] pks, bks, hfs, lfs = extract_short_peaks( self.loaded_signal[0:samples, chan], fs, unbias_wnd, pk_len, pk_interval ) if unbias_wnd: self.ui.plotArea.plot_signal_with_markup( lfs, pks, fs ) else: self.ui.plotArea.plot_signal_with_markup( self.loaded_signal[0:samples, chan], pks, fs ) else: self.ui.plotArea.plot_signal(self.loaded_signal[0:samples, chan], fs) def loadConfig(self, filename): self.config_data = {} with open(filename, "r") as fp: try: self.config_data = json.load(fp) except: print("Unable to load config") if self.config_data: self.ui.biasWindowLen.setText( str(self.config_data["preProcessing"]["biasWindowMs"]) ) self.ui.minRinterval.setText( str(self.config_data["rDetect"]["peakIntervalMs"]) )
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.particulas = Particulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.agregar_inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.agregar_final_pushButton.clicked.connect( self.click_agregar_final) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.mostrar_tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_id) self.ui.dibujar.clicked.connect(self.dibujar) self.ui.limpiar.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) self.ui.actionOrdenar.triggered.connect( self.action_ordenar_id) # Método sort self.ui.actionOrdenar.triggered.connect(self.action_ordenar_distancia) self.ui.actionOrdenar.triggered.connect(self.action_ordenar_velocidad) @Slot() def action_ordenar_id(self): self.ui.cuadro.clear() self.ui.tabla.clear() headers = [ "Id", "Origen_x", "Origen_y", "Destino_x", "Destino_y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.particulas)) particulas = [] for particula in self.particulas: particulas.append(particula) particulas.sort(key=lambda particula: particula.id, reverse=False) row = 0 for particula in particulas: id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, id_widget) self.ui.tabla.setItem(row, 1, origen_x_widget) self.ui.tabla.setItem(row, 2, origen_y_widget) self.ui.tabla.setItem(row, 3, destino_x_widget) self.ui.tabla.setItem(row, 4, destino_y_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 for particula in particulas: self.ui.cuadro.insertPlainText(str(particula)) @Slot() def action_ordenar_distancia(self): self.ui.cuadro.clear() self.ui.tabla.clear() headers = [ "Id", "Origen_x", "Origen_y", "Destino_x", "Destino_y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.particulas)) particulas = [] for particula in self.particulas: particulas.append(particula) particulas.sort(key=lambda particula: particula.distancia, reverse=True) row = 0 for particula in particulas: id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, id_widget) self.ui.tabla.setItem(row, 1, origen_x_widget) self.ui.tabla.setItem(row, 2, origen_y_widget) self.ui.tabla.setItem(row, 3, destino_x_widget) self.ui.tabla.setItem(row, 4, destino_y_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 for particula in particulas: self.ui.cuadro.insertPlainText(str(particula)) @Slot() def action_ordenar_velocidad(self): self.ui.cuadro.clear() self.ui.tabla.clear() headers = [ "Id", "Origen_x", "Origen_y", "Destino_x", "Destino_y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.particulas)) particulas = [] for particula in self.particulas: particulas.append(particula) particulas.sort(key=lambda particula: particula.velocidad, reverse=False) row = 0 for particula in particulas: id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, id_widget) self.ui.tabla.setItem(row, 1, origen_x_widget) self.ui.tabla.setItem(row, 2, origen_y_widget) self.ui.tabla.setItem(row, 3, destino_x_widget) self.ui.tabla.setItem(row, 4, destino_y_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 for particula in particulas: self.ui.cuadro.insertPlainText(str(particula)) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def dibujar(self): pen = QPen() pen.setWidth(2) for particula in self.particulas: r = particula.red g = particula.green b = particula.blue color = QColor(r, g, b) pen.setColor(color) self.scene.addEllipse(particula.origen_x, particula.origen_y, 4, 4, pen) self.scene.addEllipse(particula.destino_x, particula.destino_y, 4, 4, pen) self.scene.addLine(particula.origen_x, particula.origen_y, particula.destino_x, particula.destino_y, pen) @Slot() def limpiar(self): self.scene.clear() @Slot() def mostrar_tabla(self): self.ui.tabla.setColumnCount(10) headers = [ "Id", "Origen en x", "Origen en y", "Destino en x", "Destino en y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.particulas)) row = 0 for particula in self.particulas: id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, id_widget) self.ui.tabla.setItem(row, 1, origen_x_widget) self.ui.tabla.setItem(row, 2, origen_y_widget) self.ui.tabla.setItem(row, 3, destino_x_widget) self.ui.tabla.setItem(row, 4, destino_y_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 @Slot() def buscar_id(self): ID = self.ui.buscar_lineEdit.text() encontrado = False for particula in self.particulas: if ID == particula.id: self.ui.tabla.clear() self.ui.tabla.setRowCount(1) id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(0, 0, id_widget) self.ui.tabla.setItem(0, 1, origen_x_widget) self.ui.tabla.setItem(0, 2, origen_y_widget) self.ui.tabla.setItem(0, 3, destino_x_widget) self.ui.tabla.setItem(0, 4, destino_y_widget) self.ui.tabla.setItem(0, 5, velocidad_widget) self.ui.tabla.setItem(0, 6, red_widget) self.ui.tabla.setItem(0, 7, green_widget) self.ui.tabla.setItem(0, 8, blue_widget) self.ui.tabla.setItem(0, 9, distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atención", f'La particula con la id "{ID}" no fue encontrada') @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName(self, "Abrir archivo", ".", "JSON (*.json)")[0] if self.particulas.abrir(ubicacion): QMessageBox.information(self, "Éxito", "Se abrió el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "Error al abrir el archivo" + ubicacion) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName(self, "Guardar como", ".", "JSON (*.json)")[0] print(ubicacion) if self.particulas.guardar(ubicacion): QMessageBox.information(self, "Éxito", "Se pudo crear el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo" + ubicacion) @Slot() def click_agregar_inicio(self): id = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_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, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.particulas.agregar_inicio(particula) @Slot() def click_agregar_final(self): id = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_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, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.particulas.agregar_final(particula) @Slot() def click_mostrar(self): self.ui.cuadro.clear() self.ui.cuadro.insertPlainText(str(self.particulas))
class MainWindow(QMainWindow): particula = Particula() particulas = Particulas() #administra particulas #al declarar el objeto de manera globar ya podemos crear particulas def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.Inicio_pushButton.clicked.connect(self.agregar_Particula_Inicio) self.ui.Final_pushButton.clicked.connect(self.agregar_Particula_Final) self.ui.pushButton_2.clicked.connect(self.mostrar_Particula) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.mostrar_tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_titulo) self.ui.dibujar.clicked.connect(self.dibujar) self.ui.limpiar.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) self.ui.idOrdenar_pushButton.clicked.connect(self.Ordenarid) self.ui.distanciaOrdenar_pushButton.clicked.connect(self.Ordenardistancia) self.ui.velocidadOrdenar_pushButton.clicked.connect(self.Ordenarvelocidad) self.ui.grafos_pushButton.clicked.connect(self.grafo) @Slot() def grafo(self): self.ui.salida.clear() grafo = dict() for p in self.particulas.contenedor: origen = (p.origenX, p.origenY) destino = (p.destinoX, p.destinoY) distancia = (p.distancia) arista_origen = (origen,distancia) arista_destino = (destino,distancia) if origen in grafo: grafo[origen].append(arista_destino) else: grafo[origen] = [arista_destino] if destino in grafo: grafo[destino].append(arista_origen) else: grafo[destino] = [arista_origen] impresion = pprint.pformat(grafo, width=40) impresion+= '\n' self.ui.salida.insertPlainText(impresion) @Slot() def Ordenarid(self): self.particulas.contenedor.sort(key=sort_by_id) @Slot() def Ordenardistancia(self): self.particulas.contenedor.sort(key=lambda Particula: Particula.distancia, reverse=True) @Slot() def Ordenarvelocidad(self): self.particulas.contenedor.sort(key=lambda Particula: Particula.velocidad) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def dibujar(self): pen = QPen() pen.setWidth(2) for particula in self.particulas: R = particula.colorR G = particula.colorG B = particula.colorB color = QColor (R,G,B) pen.setColor(color) self.scene.addEllipse(particula.origenX, particula.origenY,3,3,pen) self.scene.addEllipse(particula.destinoX, particula.destinoY,3,3,pen) self.scene.addLine(particula.origenX+3, particula.origenY+3, particula.destinoX, particula.destinoY, pen) print(color) @Slot() def limpiar(self): self.scene.clear() @Slot() def buscar_titulo(self): id = self.ui.buscar_lineEdit.text() encontrado = False for particula in self.particulas: if id == particula.id: self.ui.tabla.clear() #vacia la filas para poner el libro self.ui.tabla.setRowCount(1) #nada mas tendra una fila id_widget = QTableWidgetItem(particula.id) origenX_widget = QTableWidgetItem(str(particula.origenX)) origenY_widget = QTableWidgetItem(str(particula.origenY)) destinoX_widget = QTableWidgetItem(str(particula.destinoX)) destinoY_widget = QTableWidgetItem(str(particula.destinoY)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) colorR_widget = QTableWidgetItem(str(particula.colorR)) colorG_widget = QTableWidgetItem(str(particula.colorG)) colorB_widget = QTableWidgetItem(str(particula.colorB)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(0, 0,id_widget) self.ui.tabla.setItem(0, 1,origenX_widget) self.ui.tabla.setItem(0, 2,origenY_widget) self.ui.tabla.setItem(0, 3,destinoX_widget) self.ui.tabla.setItem(0, 4,destinoY_widget) self.ui.tabla.setItem(0, 5,velocidad_widget) self.ui.tabla.setItem(0, 6,colorR_widget) self.ui.tabla.setItem(0, 7,colorG_widget) self.ui.tabla.setItem(0, 8,colorB_widget) self.ui.tabla.setItem(0, 9,distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atencion", f'ERROR -> La Particula con el ID: "{id}" no se encontro' ) @Slot() def mostrar_tabla(self): self.ui.tabla.setColumnCount(10) headers = ["ID","Origen X","Origen Y","Destino X", "Destino Y","Velocidad","Color R","Color G","Color B","Distancia"] self.ui.tabla.setHorizontalHeaderLabels(headers) # en la cabecera imprime los nombres self.ui.tabla.setRowCount(len(self.particulas)) # crea la cantidad de lineas dependiendo de las particulas que hemmos insertado row = 0 for particula in self.particulas: id_widget = QTableWidgetItem(particula.id) origenX_widget = QTableWidgetItem(str(particula.origenX)) origenY_widget = QTableWidgetItem(str(particula.origenY)) destinoX_widget = QTableWidgetItem(str(particula.destinoX)) destinoY_widget = QTableWidgetItem(str(particula.destinoY)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) colorR_widget = QTableWidgetItem(str(particula.colorR)) colorG_widget = QTableWidgetItem(str(particula.colorG)) colorB_widget = QTableWidgetItem(str(particula.colorB)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0,id_widget) self.ui.tabla.setItem(row, 1,origenX_widget) self.ui.tabla.setItem(row, 2,origenY_widget) self.ui.tabla.setItem(row, 3,destinoX_widget) self.ui.tabla.setItem(row, 4,destinoY_widget) self.ui.tabla.setItem(row, 5,velocidad_widget) self.ui.tabla.setItem(row, 6,colorR_widget) self.ui.tabla.setItem(row, 7,colorG_widget) self.ui.tabla.setItem(row, 8,colorB_widget) self.ui.tabla.setItem(row, 9,distancia_widget) row += 1 # incrementamos el contador de fila para que no se escriban encima @Slot() def action_abrir_archivo(self): #print('Abrir_archivo') ubicacion = QFileDialog.getOpenFileName( self, 'Abrir Archivo', #el nombre del archivo '.', #donde lo va a guardar, en este caso en la carpeta del proyecto 'JSON (*.json)' #Tipo de formato )[0] if self.particulas.abrir(ubicacion): QMessageBox.information( self, "Éxito", "Se abrió el archivo " + ubicacion ) else: QMessageBox.information( self, "Error", "Error al abrir el archivo " + ubicacion ) @Slot() def action_guardar_archivo(self): #print('Guardar_archivo') ubicacion = QFileDialog.getSaveFileName( self, 'Guardar Archivo', #el nombre del archivo '.', #donde lo va a guardar, en este caso en la carpeta del proyecto 'JSON (*.json)' #Tipo de formato )[0] print(ubicacion) if self.particulas.guardar(ubicacion): QMessageBox.information( self, #desde donde se manda "Éxito", #nombre de la ventana "Se pudo crear el archivo " + ubicacion #mensaje ) else: QMessageBox.critical( self, "Error", "No se pudo crear el archivo " + ubicacion ) @Slot() def agregar_Particula_Inicio(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() colorR = self.ui.R_spinBox.value() colorG = self.ui.G_spinBox.value() colorB = self.ui.B_spinBox.value() particula = Particula(id, origenX, origenY, destinoX, destinoY, velocidad, colorR, colorG, colorB) self.particulas.agregar_inicio(particula) @Slot() def agregar_Particula_Final(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() colorR = self.ui.R_spinBox.value() colorG = self.ui.G_spinBox.value() colorB = self.ui.B_spinBox.value() particula = Particula(id, origenX, origenY, destinoX, destinoY, velocidad, colorR, colorG, colorB) self.particulas.agregar_final(particula) @Slot() def mostrar_Particula(self): #self.particulas.mostrar() self.ui.salida.clear( ) self.ui.salida.insertPlainText(str(self.particulas))
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) for i in range(0, self.ui.tableWidget_PacketsQueue.columnCount()): self.ui.tableWidget_PacketsQueue.horizontalHeader( ).setSectionResizeMode(i, QHeaderView.ResizeToContents) for i in range(0, self.ui.tableWidget_optionsTCP.columnCount()): self.ui.tableWidget_optionsTCP.horizontalHeader( ).setSectionResizeMode(i, QHeaderView.ResizeToContents) self.backend = backendClass() self.dialogInterface = DialogWindow(self.backend) self.packetIndex = -1 # index of current chosen packet which's fields are shown on the right side self.ui.actionSetInterface.triggered.connect(self.showInterfaceDialog) self.ui.pushButton_addPacket.clicked.connect(self.addPacket) self.ui.tableWidget_PacketsQueue.cellDoubleClicked.connect( self.selectPacket) self.ui.pushButton_deleteOptionTCP.clicked.connect( self.removeOptionRowTCP) self.ui.pushButton_addOptionTCP.clicked.connect(self.addOptionRowTCP) #TCP self.ui.pushButton_saveTCP.clicked.connect(self.saveTCP) #UDP self.ui.pushButton_saveUDP.clicked.connect(self.saveUDP) #ICMP self.ui.pushButton_saveICMP.clicked.connect(self.saveICMP) #IP self.ui.pushButton_saveIP.clicked.connect(self.saveIP) #Ether self.ui.pushButton_saveEthernet.clicked.connect(self.saveEthernet) self.ui.pushButton_sendAll.clicked.connect(self.sendAllPackets) # ^^^ __init__ ^^^ def addPacket(self): self.ui.tableWidget_PacketsQueue.insertRow( self.backend.getNumberOfPackets()) # ^^^ addPacket ^^^ def addOptionRowIP(self): self.ui.tableWidget_optionsIP.insertRow(0) # ^^^ addOptionRowIP ^^^ def addOptionRowTCP(self): self.ui.tableWidget_optionsTCP.insertRow(0) # ^^^ addOptionRowTCP ^^^ def removeOptionRowIP(self): self.ui.tableWidget_optionsIP.removeRow(0) # ^^^ deleteOptionRowIP ^^^ def removeOptionRowTCP(self): self.ui.tableWidget_optionsTCP.removeRow(0) # ^^^ deleteOptionRowTCP ^^^ def getOptionsFromTable(self, tableWidget): options = [] for i in range(0, tableWidget.rowCount()): elt0 = tableWidget.item(i, 0).text() if tableWidget.item( i, 0) else None elt1 = tableWidget.item(i, 1).text() if tableWidget.item( i, 1) else None elt2 = tableWidget.item(i, 2).text() if tableWidget.item( i, 2) else None options.append((elt0, elt1, elt2)) print(options) return options # ^^^ getOptionsFromTable ^^^ def saveTCP(self): options = self.getOptionsFromTable(self.ui.tableWidget_optionsTCP) if self.ui.checkBox_autoDataOffsetTCP.isChecked(): offset = None else: offset = self.ui.lineEdit_dataOffsetTCP.text() if self.ui.checkBox_autoReservedTCP.isChecked(): reserved = '0' else: reserved = self.ui.lineEdit_reservedTCP.text() if self.ui.checkBox_autoChecksumTCP.isChecked(): checksum = None else: checksum = self.ui.lineEdit_checksumTCP.text() try: newPacket = self.backend.createTCP( self.ui.lineEdit_srcPortTCP.text(), self.ui.lineEdit_dstPortTCP.text(), self.ui.lineEdit_seqTCP.text(), self.ui.lineEdit_ackTCP.text(), offset, reserved, self.ui.checkBox_urgTCP.isChecked(), self.ui.checkBox_ackTCP.isChecked(), self.ui.checkBox_pshTCP.isChecked(), self.ui.checkBox_rstTCP.isChecked(), self.ui.checkBox_synTCP.isChecked(), self.ui.checkBox_finTCP.isChecked(), self.ui.lineEdit_windowSizeTCP.text(), checksum, self.ui.lineEdit_urgentPointerTCP.text(), options, self.ui.plainTextEdit_dataTCP.toPlainText(), None if self.ui.tableWidget_PacketsQueue.currentRow() == self.backend.getNumberOfPackets() else self.ui.tableWidget_PacketsQueue.currentRow()) self.drawPacketInQueue() except MyPacketError as e: self.ui.statusbar.showMessage('Внимание! ' + e.message + ' Пакет не был сохранен.') # ^^^ saveTCP ^^^ def saveUDP(self): if self.ui.checkBox_autoLengthUDP.isChecked(): datagramLength = '' else: datagramLength = self.ui.lineEdit_lengthUDP.text() if self.ui.checkBox_autoChecksumUDP.isChecked(): checksum = '' else: checksum = self.ui.lineEdit_checksumUDP.text() try: newPacket = self.backend.createUDP( self.ui.lineEdit_srcPortUDP.text(), self.ui.lineEdit_dstPortUDP.text(), datagramLength, checksum, self.ui.plainTextEdit_dataUDP.toPlainText(), self.ui.tableWidget_PacketsQueue.currentRow()) self.drawPacketInQueue() except MyPacketError as e: self.ui.statusbar.showMessage('Внимание! ' + e.message + ' Пакет не был сохранен.') # ^^^ saveUDP ^^^ def saveICMP(self): if self.ui.checkBox_autoChecksumICMP.isChecked(): checksum = '' else: checksum = self.ui.lineEdit_checksumICMP.text() if self.ui.checkBox_autoCodeICMP.isChecked(): code = '0' else: code = self.ui.lineEdit_codeICMP.text() try: if self.ui.comboBox_typeICMP.currentIndex() == 0: # manual type = self.ui.lineEdit_typeICMP.text() elif self.ui.comboBox_typeICMP.currentIndex() == 1: # echo-request type = '8' elif self.ui.comboBox_typeICMP.currentIndex() == 2: # echo-reply type = '0' else: raise MyPacketError('Ошибка.') newPacket = self.backend.createICMP( type, code, checksum, self.ui.lineEdit_identifierICMP.text(), self.ui.lineEdit_seqICMP.text(), self.ui.plainTextEdit_dataICMP.toPlainText(), self.ui.tableWidget_PacketsQueue.currentRow()) self.drawPacketInQueue() except MyPacketError as e: self.ui.statusbar.showMessage('Внимание! ' + e.message + ' Пакет не был сохранен.') # ^^^ saveICMP ^^^ def saveIP(self): if self.ui.checkBox_autoChecksumIP.isChecked(): checksum = '' else: checksum = self.ui.lineEdit_checksumIP.text() if self.ui.checkBox_autoIHL.isChecked(): IHL = '' else: IHL = self.ui.lineEdit_IHL.text() if self.ui.checkBox_autoTotalLengthIP.isChecked(): length = '' else: length = self.ui.lineEdit_totalLengthIP.text() if self.ui.checkBox_autoOffsetIP.isChecked(): offset = '' else: offset = self.ui.lineEdit_fragmentOffsetIP.text() if self.ui.checkBox_autoIDataP.isChecked(): payload = '' else: payload = self.ui.plainTextEdit_dataIP.toPlainText() try: if self.ui.comboBox_versionIP.currentIndex() == 0: # manual version = self.ui.lineEdit_typeICMP.text() elif self.ui.comboBox_versionIP.currentIndex() == 1: # IPv4 version = 4 else: raise MyPacketError('Ошибка.') if self.ui.comboBox_protocolIP.currentIndex() == 0: # manual protocol = self.ui.lineEdit_protocolIP.text() elif self.ui.comboBox_protocolIP.currentIndex() == 1: # TCP protocol = 6 elif self.ui.comboBox_protocolIP.currentIndex() == 2: # UDP protocol = 17 elif self.ui.comboBox_protocolIP.currentIndex() == 3: # ICMP protocol = 1 else: raise MyPacketError('Ошибка.') newPacket = self.backend.createIP( version, IHL, self.ui.lineEdit_DSCP.text(), length, self.ui.lineEdit_identificationIP.text(), self.ui.checkBox_reservedFlagIP.isChecked(), self.ui.checkBox_dontFragmentFlagIP.isChecked(), self.ui.checkBox_moreFragmentsFlagIP.isChecked(), offset, self.ui.lineEdit_timeToLiveIP.text(), protocol, checksum, self.ui.lineEdit_srcAddrIP.text(), self.ui.lineEdit_dstAddrIP.text(), self.ui.plainTextEdit_optionsIP.toPlainText(), payload, self.ui.tableWidget_PacketsQueue.currentRow()) self.drawPacketInQueue() except MyPacketError as e: self.ui.statusbar.showMessage('Внимание! ' + e.message + ' Пакет не был сохранен.') # ^^^ saveIP ^^^ def saveEthernet(self): try: if self.ui.comboBox_etherType.currentIndex() == 0: # manual etherType = self.ui.lineEdit_etherType.text() elif self.ui.comboBox_etherType.currentIndex() == 1: # IPv4 etherType = '0800' else: raise MyPacketError('Ошибка.') newPacket = self.backend.createEthernet( etherType, self.ui.tableWidget_PacketsQueue.currentRow() #None if self.ui.tableWidget_PacketsQueue.currentRow() == self.backend.getNumberOfPackets() # else self.ui.tableWidget_PacketsQueue.currentRow() ) self.drawPacketInQueue() except MyPacketError as e: self.ui.statusbar.showMessage('Внимание! ' + e.message + ' Пакет не был сохранен.') # ^^^ saveEthernet ^^^ def showInterfaceDialog(self): self.dialogInterface.exec_() # ^^^ showInterfaceDialog ^^^ def sendAllPackets(self): ret = self.backend.sendAll(self.ui.statusbar, self.ui.radioButton_ifDeleteAll.isChecked()) if ret == 0 and self.ui.radioButton_ifDeleteAll.isChecked(): self.ui.tableWidget_PacketsQueue.setRowCount(0) # ^^^ sendAllPackets ^^^ def drawPacketInQueue(self): index = self.ui.tableWidget_PacketsQueue.currentRow() packet = self.backend.listPackets[index] print('draw ind: ' + str(index)) #print(str(packet)) self.ui.tableWidget_PacketsQueue.setItem( index, 0, QTableWidgetItem(str(self.backend.getType(packet)))) # type self.ui.tableWidget_PacketsQueue.setItem( index, 1, QTableWidgetItem(str( self.backend.getSrcAddr(packet)))) # source address self.ui.tableWidget_PacketsQueue.setItem( index, 2, QTableWidgetItem(str( self.backend.getDstAddr(packet)))) # remote address self.ui.tableWidget_PacketsQueue.setItem( index, 3, QTableWidgetItem(str( self.backend.getSrcPort(packet)))) # source port self.ui.tableWidget_PacketsQueue.setItem( index, 4, QTableWidgetItem(str( self.backend.getDstPort(packet)))) # remote port self.ui.tableWidget_PacketsQueue.setItem( index, 5, QTableWidgetItem( str(self.backend.getEtherType( self.backend.listPackets[index])))) # EtherType # ^^^ drawPacketInQueue ^^^ def selectPacket(self, row, column): self.packetIndex = row self.ui.tabWidget_setPacket.setEnabled(True)
class myMainWindow(QtGui.QMainWindow): _soundcontainer = None _profilecontainer = None def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) # TODO: add profiles self.ui = Ui_MainWindow() self._soundcontainer = soundContainer() self._profilecontainer = profileContainer(self._soundcontainer) self.ui.setupUi(self) appconf = appconfig(appname, appver) appconf.readconfig() config = appconf.config self.dict_loadConfig(config) #self.dict_updateActiveProfileUi() self.dict_initSlots() def dict_wipeOutConfig(self): """Cleanly destroys all existent sounds, profiles and sound controls""" self._soundcontainer.wipeOutSounds() self._profilecontainer._currentprofilename = None self._profilecontainer.dict_wipeOutProfiles() def dict_loadConfig(self, config): """ Loads into the interface the configuration defined by 'config'. 'config' must be a dictionary in the format provided by appconfig. """ self.dict_wipeOutConfig() self._soundcontainer.loadSounds(config['sounds']) self._profilecontainer.dict_loadProfiles(config['profiles']) self._profilecontainer.activeprofile = config['active_profile'] def dict_updateActiveProfileUi(self): raise NotImplementedError("updating the profile UI is not implemented") def uiAddSound2profile(self, soundName=None, soundFile=None, active=False, profile=None): """ Adds soundName with soundFile to profile via UI interaction. The sound control is also created through this operation. """ if profile is None: profile = self._profilecontainer.activeprofile handler = self._profilecontainer.addSound2Profile(soundName, soundFile, active, profile) uiProfileScrollArea = self.ui.soundsScrollArea uiProfileVerticalLayout = self.ui.verticalLayout_profile ctl = soundControl(self._soundcontainer, handler, uiProfileScrollArea, active) self._profilecontainer.linkSoundCtlInProfile(profile, handler, ctl) # TODO: delete spacer add again later uiProfileVerticalLayout.addWidget(ctl) def dict_initSlots(self): QtCore.QObject.connect(self.ui.soundAddButton, QtCore.SIGNAL("clicked()"), self.uiAddSound2profile )
class KylinDisplaySwitch(QWidget): key_service = None display_service = None switchers_service = None settings = None current_button = 0 key_dbus_service = None mediakey_service = None def __init__(self, parent = None): super(KylinDisplaySwitch, self).__init__(parent) self.check_singleton() self.init_ui() self.display_service = DisplayService() self.switchers_service = SwitchersService() self.mediakey_service = MediakeyService() self.settings = QSettings("kylinos.cn", "KylinDisplaySwitch") self.start_listen() self.start_listen_dbus() # singleton def check_singleton(self): homepath = os.path.expanduser('~') lockpath = "/tmp/instance_kds_" + homepath[homepath.rfind('/')+1:] + ".lock" if(os.path.exists(lockpath) == False): new_instance_file = open(lockpath, 'w') new_instance_file.close() os.chmod(lockpath, stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO) self.instance_file = open(lockpath, 'w') try: fcntl.lockf(self.instance_file, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: print("only allow one instance...") sys.exit() def switch_window_type(self, big): qtVersion = int(QT_VERSION_STR.split('.')[1]) if big: # main window radius rect = self.rect() rectf = QRectF(rect) blurPath = QPainterPath() blurPath.addRoundedRect(rectf, 24, 24) if qtVersion < 11: qtsf = QTransform() self.setProperty("blurRegion", QRegion(blurPath.toFillPolygon(qtsf).toPolygon())) else: self.setProperty("blurRegion", QRegion(blurPath.toFillPolygon().toPolygon())) self.setWindowOpacity(0.7) else: # main window radius rect = self.rect() rectf = QRectF(rect) blurPath = QPainterPath() blurPath.addRoundedRect(rectf, 4, 4) if qtVersion < 11: qtsf = QTransform() self.setProperty("blurRegion", QRegion(blurPath.toFillPolygon(qtsf).toPolygon())) else: self.setProperty("blurRegion", QRegion(blurPath.toFillPolygon().toPolygon())) self.setWindowOpacity(0.95) def init_ui(self): self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.FramelessWindowHint | Qt.ToolTip) self.ui.centralWidget.setAutoFillBackground(True) self.ui.centralWidget.setStyleSheet("#centralWidget{background-color: rgba(0,0,0,1); border-radius: 24px;}") self.switch_window_type(True) self.ui.lb_title.setText(_("Display Switch")) self.ui.lb_title.setStyleSheet("#lb_title{color:white; font-size: 22px;}") self.ui.lb_title.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.ui.lb_phone.setText(_("Control cellphone")) self.ui.lb_mode_1.setText(_("Computer")) self.ui.lb_mode_2.setText(_("Clone")) self.ui.lb_mode_3.setText(_("Extend")) self.ui.lb_mode_4.setText(_("Output")) self.ui.lb_mode_1.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.ui.lb_mode_2.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.ui.lb_mode_3.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.ui.lb_mode_4.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) # self.ui.lb_caps_on.setText(_("Caps on")) # self.ui.lb_caps_off.setText(_("Caps off")) # self.ui.lb_num_on.setText(_("Num on")) # self.ui.lb_num_off.setText(_("Num off")) self.ui.caps_on_bg.setStyleSheet("QWidget{border-image:url(res/capslockOn.png); border: none; border-radius: 8px;}") self.ui.caps_off_bg.setStyleSheet("QWidget{border-image:url(res/capslockOff.png); border: none; border-radius: 8px;}") self.ui.num_on_bg.setStyleSheet("QWidget{border-image:url(res/numlockOn.png); border:0px; border-radius: 8px;}") self.ui.num_off_bg.setStyleSheet("QWidget{border-image:url(res/numlockOff.png); border:0px; border-radius: 8px;}") self.ui.tp_on_bg.setStyleSheet("QWidget{border-image:url(res/touchpadOn.png); border:0px; border-radius: 8px;}") self.ui.tp_off_bg.setStyleSheet("QWidget{border-image:url(res/touchpadOff.png); border:0px; border-radius: 8px;}") self.ui.wlan_on_bg.setStyleSheet("QWidget{border-image:url(res/wlanOn.png); border:0px; border-radius: 8px;}") self.ui.wlan_off_bg.setStyleSheet("QWidget{border-image:url(res/wlanOff.png); border:0px; border-radius: 8px;}") self.ui.bluetooth_on_bg.setStyleSheet("QWidget{border-image:url(res/bluetoothOn.png); border:0px; border-radius: 8px;}") self.ui.bluetooth_off_bg.setStyleSheet("QWidget{border-image:url(res/bluetoothOff.png); border:0px; border-radius: 8px;}") # self.ui.lb_caps_on.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_caps_off.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_num_on.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_num_off.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_tp_on.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_tp_off.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_wlan_on.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_wlan_off.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_bluetooth_on.setStyleSheet("QLabel{color:white;font-size:19px;}") # self.ui.lb_bluetooth_off.setStyleSheet("QLabel{color:white;font-size:19px;}") self.ui.widget_1.setStyleSheet("#widget_1{background-color: rgba(255,255,255,0.05);}") self.ui.widget_3.setStyleSheet("#widget_3{background-color: rgba(255,255,255,0.05);}") self.ui.bg_mode_1.setStyleSheet("QWidget{border-image:url(res/btn1.png); border:0px;}") self.ui.bg_mode_2.setStyleSheet("QWidget{border-image:url(res/btn2.png); border:0px;}") self.ui.bg_mode_3.setStyleSheet("QWidget{border-image:url(res/btn3.png); border:0px;}") self.ui.bg_mode_4.setStyleSheet("QWidget{border-image:url(res/btn4.png); border:0px;}") self.ui.s_mode_1.setStyleSheet("QWidget{background-image:url(res/selected.png); border:0px;}") self.ui.s_mode_2.setStyleSheet("QWidget{background-image:url(res/selected.png); border:0px;}") self.ui.s_mode_3.setStyleSheet("QWidget{background-image:url(res/selected.png); border:0px;}") self.ui.s_mode_4.setStyleSheet("QWidget{background-image:url(res/selected.png); border:0px;}") self.ui.lb_mode_1.setStyleSheet("QLabel{color: white; font-size: 18px;}") self.ui.lb_mode_2.setStyleSheet("QLabel{color: white; font-size: 18px;}") self.ui.lb_mode_3.setStyleSheet("QLabel{color: white; font-size: 18px;}") self.ui.lb_mode_4.setStyleSheet("QLabel{color: white; font-size: 18px;}") self.ui.mode_1.setStyleSheet("QPushButton{background-color: rgba(255,255,255,0.12); border:0px;}") self.ui.mode_2.setStyleSheet("QPushButton{background-color: rgba(255,255,255,0.12); border:0px;}") self.ui.mode_3.setStyleSheet("QPushButton{background-color: rgba(255,255,255,0.12); border:0px;}") self.ui.mode_4.setStyleSheet("QPushButton{background-color: rgba(255,255,255,0.12); border:0px;}") self.ui.mode_1.setFocusPolicy(Qt.NoFocus) self.ui.mode_2.setFocusPolicy(Qt.NoFocus) self.ui.mode_3.setFocusPolicy(Qt.NoFocus) self.ui.mode_4.setFocusPolicy(Qt.NoFocus) self.ui.bmode_1.setStyleSheet("QPushButton{border:0px;} QPushButton:Hover{background-color: rgba(255,255,255,0.08);} QPushButton:Pressed{background-color: rgba(255,255,255,0.04);}") self.ui.bmode_2.setStyleSheet("QPushButton{border:0px;} QPushButton:Hover{background-color: rgba(255,255,255,0.12);} QPushButton:Pressed{background-color: rgba(255,255,255,0.08);}") self.ui.bmode_3.setStyleSheet("QPushButton{border:0px;} QPushButton:Hover{background-color: rgba(255,255,255,0.08);} QPushButton:Pressed{background-color: rgba(255,255,255,0.04);}") self.ui.bmode_4.setStyleSheet("QPushButton{border:0px;} QPushButton:Hover{background-color: rgba(255,255,255,0.12);} QPushButton:Pressed{background-color: rgba(255,255,255,0.08);}") self.ui.bmode_1.setFocusPolicy(Qt.NoFocus) self.ui.bmode_2.setFocusPolicy(Qt.NoFocus) self.ui.bmode_3.setFocusPolicy(Qt.NoFocus) self.ui.bmode_4.setFocusPolicy(Qt.NoFocus) self.ui.split_1.setStyleSheet("QLabel{background-color: rgba(255,255,255,0.2); border:0px;}") self.ui.bg_phone.setStyleSheet("#bg_phone{border-image:url(res/phone.png); border:0px;}") self.ui.lb_phone.setStyleSheet("#lb_phone{color: rgba(220,220,220,0.8); font-size: 16px;}") self.ui.lb_phone.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.timer_tip = QTimer() self.timer_tip.timeout.connect(self.slot_hide_tip) self.ui.tipWidget.hide() self.ui.bmode_1.clicked.connect(self.slot_switch_confirm_push_1) self.ui.bmode_2.clicked.connect(self.slot_switch_confirm_push_2) self.ui.bmode_3.clicked.connect(self.slot_switch_confirm_push_3) self.ui.bmode_4.clicked.connect(self.slot_switch_confirm_push_4) # self.ui.s_mode_1.hide() self.ui.s_mode_2.hide() self.ui.s_mode_3.hide() self.ui.s_mode_4.hide() self.resize(400, 500) self.ui.centralWidget.resize(400, 500) def start_listen(self): self.key_service = KeyServiceXlib(self) self.key_service.start() def start_listen_dbus(self): self.key_dbus_service = KeyServiceDbus(self) self.key_dbus_service.start() def switch_button(self, direction=3): self.ui.mode_1.hide() self.ui.mode_2.hide() self.ui.mode_3.hide() self.ui.mode_4.hide() if direction == 1: self.current_button += 1 else: self.current_button -= 1 if self.current_button > 4: self.current_button = 1 if self.current_button < 1: self.current_button = 4 if self.current_button == 1: self.ui.mode_1.show() if self.current_button == 2: self.ui.mode_2.show() if self.current_button == 3: self.ui.mode_3.show() if self.current_button == 4: self.ui.mode_4.show() def switch_show_selected(self): self.ui.s_mode_1.hide() self.ui.s_mode_2.hide() self.ui.s_mode_3.hide() self.ui.s_mode_4.hide() print(self.current_button) if self.current_button == 0: self.ui.s_mode_1.show() if self.current_button == 1: self.ui.s_mode_2.show() if self.current_button == 2: self.ui.s_mode_3.show() if self.current_button == 3: self.ui.s_mode_4.show() # switch select mode def slot_switch_select(self, direction=1): self.timer_tip.stop() self.switch_window_type(True) self.resize(400, 500) self.ui.tipWidget.hide() self.ui.centralWidget.resize(400, 500) self.ui.centralWidget.show() self.show() desktop = QApplication.desktop() if(desktop.screenCount() > 1): desktop = desktop.screenGeometry(0) self.move((desktop.width() - self.width()) / 2, (desktop.height() - self.height()) *10 / 21) self.switch_button(direction) # confirm current selected mode def slot_switch_confirm_push_1(self): self.hide() (current_mode, flag) = self.display_service.switch_display(1) # keep select mode when next active self.current_button = current_mode - 1 self.key_service.is_active = False self.key_service.is_shown = False self.switch_show_selected() def slot_switch_confirm_push_2(self): self.hide() (current_mode, flag) = self.display_service.switch_display(2) # keep select mode when next active self.current_button = current_mode - 1 self.key_service.is_active = False self.key_service.is_shown = False self.switch_show_selected() def slot_switch_confirm_push_3(self): self.hide() (current_mode, flag) = self.display_service.switch_display(3) # keep select mode when next active self.current_button = current_mode - 1 self.key_service.is_active = False self.key_service.is_shown = False self.switch_show_selected() def slot_switch_confirm_push_4(self): self.hide() (current_mode, flag) = self.display_service.switch_display(4) # keep select mode when next active self.current_button = current_mode - 1 self.key_service.is_active = False self.key_service.is_shown = False self.switch_show_selected() # confirm current selected mode def slot_switch_confirm(self): self.hide() (current_mode, flag) = self.display_service.switch_display(self.current_button) # keep select mode when next active self.current_button = current_mode - 1 self.switch_show_selected() # esc by any key pressed def slot_switch_esc(self): self.hide() # esc by any clicked def slot_switch_esc2(self, x, y): if self.key_service.is_active and self.key_service.is_shown and not self.geometry().contains(x, y): self.key_service.is_active = False self.key_service.is_shown = False self.hide() # CapsLock tip def slot_tip_capslock(self): if not get_lock_tip_show(): return self.switch_window_type(False) self.key_service.is_active = False self.key_service.is_shown = False self.timer_tip.stop() self.timer_tip.start(2500) # self.resize(190, 190) # self.ui.centralWidget.hide() # self.ui.caps_on_widget.hide() # self.ui.caps_off_widget.hide() # self.ui.num_on_widget.hide() # self.ui.num_off_widget.hide() # self.ui.tp_on_widget.hide() # self.ui.tp_off_widget.hide() # self.ui.wlan_on_widget.hide() # self.ui.wlan_off_widget.hide() # self.ui.bluetooth_on_widget.hide() # self.ui.bluetooth_off_widget.hide() # 隐藏显示切换界面 self.ui.centralWidget.hide() if(self.switchers_service.get_capslock_status() == True): self.ui.tipWidget.setCurrentIndex(Tips.CAPS_ON) else: self.ui.tipWidget.setCurrentIndex(Tips.CAPS_OFF) desktop = QApplication.desktop() if (desktop.screenCount() > 1): desktop = desktop.screenGeometry(0) self.move(desktop.width() * 3 / 4, (desktop.height() - posBottom - self.ui.tipWidget.width())) self.ui.tipWidget.show() self.show() # NumLock tip def slot_tip_numlock(self): if not get_lock_tip_show(): return self.switch_window_type(False) self.key_service.is_active = False self.key_service.is_shown = False self.timer_tip.stop() self.timer_tip.start(2500) self.ui.centralWidget.hide() if(self.switchers_service.get_numlock_status() == True): self.ui.tipWidget.setCurrentIndex(Tips.NUM_ON) else: self.ui.tipWidget.setCurrentIndex(Tips.NUM_OFF) desktop = QApplication.desktop() if (desktop.screenCount() > 1): desktop = desktop.screenGeometry(0) self.move(desktop.width() * 3 / 4, (desktop.height() - posBottom - self.ui.tipWidget.width())) self.ui.tipWidget.show() self.show() # MediaKey listen def slot_mediakey_trigger(self, keyCode = -1, keyValue = -1): """keyCode: Which key is it keyValue: The key is pressed or released""" print("the", keyCode, "is trigger") def showOsdOnDesktop(): desktop = QApplication.desktop() if (desktop.screenCount() > 1): desktop = desktop.screenGeometry(0) self.move(desktop.width() * 3 / 4, (desktop.height() - posBottom - self.ui.tipWidget.width())) self.ui.centralWidget.hide() # self.ui.tipWidget.show() self.show() def touchpadOnMethod(): # self.mediakey_service.touchpadToggle(True) self.ui.tipWidget.setCurrentIndex(Tips.TP_ON) showOsdOnDesktop() def touchpadOffMethod(): # self.mediakey_service.touchpadToggle(False) self.ui.tipWidget.setCurrentIndex(Tips.TP_OFF) showOsdOnDesktop() def bluetoothOnOffMethod(): # switch bluetooth status self.mediakey_service.bluetoothToggle() # show osd icon if self.mediakey_service.bluetoothStatus: self.ui.tipWidget.setCurrentIndex(Tips.BLUETOOTH_ON) else: self.ui.tipWidget.setCurrentIndex(Tips.BLUETOOTH_OFF) showOsdOnDesktop() def default(): pass mediakeysMethod = { 113 : muteOnOffMethod, \ 114 : volumeDownMethod, \ 115 : volumeUpMethod, \ # 152 : screenlockMethod, \ 66 : cameraOnOffMethod, \ 224 : brightnessDownMethod, \ 225 : brightnessUpMethod, \ 227 : videoModeSwitchMethod, \ 237 : bluetoothOnOffMethod, \ 238 : flightModeOnOffMethod, \ 248 : microphoneOnOffMethod, \ 431 : screenOnOffMethod, \ 530 : touchpadOnOffMethod, \ 531 : touchpadOnMethod, \ 532 : touchpadOffMethod, \ } self.timer_tip.stop() self.timer_tip.start(2500) mediakeysMethod.get(keyCode, default)() def slot_hide_tip(self): self.timer_tip.stop() self.ui.tipWidget.hide() self.hide()
class FLLInstaller(object): def __init__(self, CONF_FILE): #print 'class FLLInstaller __init__' self.CONF_FILE = CONF_FILE ''' read config file and write values to widgets ''' self.cfile = ConfigObj(self.CONF_FILE) def default_text(self): ''' default text to label widgets. you can find the text in src/translations.py ''' ''' label_start ''' self.wg = Write_to_gui(self.ui, "label_start") self.wg.text_to_singleline(str(self.t.label_start())) def read_config(self): ''' comboBox ''' for self.c in self.cfile['text_to_comboBox']: ''' name in config file must be the same in ui file ''' self.objectName = self.c[:] print self.objectName self.objectValue = self.cfile['text_to_comboBox'][self.objectName] self.wg = Write_to_gui(self.ui, self.objectName) self.wg.text_to_combobox(self.objectValue.split()) ''' lineEdit ''' for self.c in self.cfile['text_to_lineEdit']: ''' name in config file must be the same in ui file ''' self.objectName = self.c[:] self.objectValue = self.cfile['text_to_lineEdit'][self.objectName] self.wg = Write_to_gui(self.ui, self.objectName) self.wg.text_to_singleline(self.objectValue) def partition_start(self): ''' comboBox_partition and tableWidget_mountpoints ''' self.row = Diskinfo().partition_count() self.column = 6 self.place_x = 0 self.place = [] self.mp = [] self.wg = Write_to_gui(self.ui, 'tableWidget_mountpoints') ''' add Row and Column to table ''' self.wg.cells_to_table(self.row, self.column) ''' setHorizontalHeader in tableWidget''' self.wg.setHorizontalHeader() self.place = [ -1, 1 ] for self.dev in Diskinfo().partitions(): if Diskinfo().udevinfo(self.dev).get('TYP') == 'disk': ''' disks ( /dev/sda, /dev/sdb, ...) ''' ''' comboBox_partition (gparted, fdisk, cfdisk start) ''' self.wg = Write_to_gui(self.ui, 'comboBox_partition') self.wg.text_to_combobox(self.dev.split()) ''' comboBox_installtarget ( mbr, partition, /dev/sda, ... [wihtout usb partitions] ''' if Diskinfo().udevinfo(self.dev).get('ID_BUS') != "usb": self.wg = Write_to_gui(self.ui, 'comboBox_installtarget') self.wg.text_to_combobox(self.dev.split()) else: ''' partitions ( /dev/sda1, /dev/sda2, ...) ''' ''' fdisk -l ''' self.cmd = ['fdisk', '-l', self.dev] self.c = Popen(self.cmd, stdout = PIPE, stderr = STDOUT, close_fds = True) self.fdisk_l = self.c.communicate()[0] if not self.c.returncode == 0: print 'Error: %s' % ( ' '.join(self.cmd) ) ''' if fdisk -l empty, goto next ''' if len(self.fdisk_l) < 2: # if partition is extended do noting continue ''' partitions to table tableWidget_mountpoints ''' self.wg = Write_to_gui(self.ui, 'tableWidget_mountpoints') ''' 1. column in tableWidget = name of partition ''' self.place = [ self.place[0] + 1, 0] self.wg.labeltext_to_table(self.place, str(self.dev.split()[0])) ''' 2. column in tableWidget = partition typ ''' self.id_fs_type = Diskinfo().udevinfo(self.dev).get('ID_FS_TYPE') self.place = [ self.place[0], 1] if self.id_fs_type != None: self.wg.labeltext_to_table(self.place, str(self.id_fs_type.split()[0])) else: self.wg.labeltext_to_table(self.place, "") ''' 3. column in tableWidget = checkbox format=0|1 ''' self.place = [ self.place[0], 2 ] self.wg.checkbox_to_table(self.place) ''' 4. column in tableWidget = Format_with ''' self.place = [ self.place[0], 3] self.wg.combobox_to_table(self.place, self.cfile['filesystem']['supported'].split()) ''' 5. column in tableWidget = mountpoint ''' self.place = [ self.place[0], 4] self.mp = [ "" ] self.mp += self.cfile['filesystem']['mountpoints'].split() self.wg.combobox_to_table(self.place, self.mp) ''' 6. column in tableWidget = partition typ ''' self.id_fs_uuid = Diskinfo().udevinfo(self.dev).get('ID_FS_UUID') self.place = [ self.place[0], 5] if self.id_fs_uuid != None: self.wg.labeltext_to_table(self.place, str(self.id_fs_uuid.split()[0])) else: self.wg.labeltext_to_table(self.place, "") def main(self): ''' set ui ''' self.app = QtGui.QApplication(sys.argv) self.MainWindow = QtGui.QMainWindow() self.ui = Ui_MainWindow() self.ui.setupUi(self.MainWindow) ''' show MainWindow ''' self.MainWindow.show() ''' start translation ''' self.t = Gettxt() self.ts = Gettxt_gui(self.ui, self.MainWindow, self.app) self.ts.gettxt_gui_run() ''' values to ui at start ''' self.default_text() self.read_config() self.partition_start() ''' Timezone to label ''' self.timezone = Timezone(self.ui, self.CONF_FILE) self.timezone.label_timezone() ''' callbacks from ui ''' self.cb = Callback(self.ui, self.timezone, self) sys.exit(self.app.exec_())
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.particulas = Admin_particulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.Agregar_Inicio_pushButton.clicked.connect(self.click_agregar_inicio) self.ui.Agregar_Final_pushButton.clicked.connect(self.click_agregar_final) self.ui.Mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.Ordenar_ID_pushButton.clicked.connect(self.ordenar_ID) self.ui.Ordenar_Distancia_pushButton.clicked.connect(self.ordenar_Distancia) self.ui.Ordenar_Velocidad_pushButton.clicked.connect(self.ordenar_Velocidad) self.ui.Ordenar_ID_pushButton_2.clicked.connect(self.ordenar_ID_Tabla) self.ui.Ordenar_Distancia_pushButton_2.clicked.connect(self.ordenar_Distancia_Tabla) self.ui.Ordenar_Velocidad_pushButton_2.clicked.connect(self.ordenar_Velocidad_Tabla) self.ui.actionAbrir_Archivo.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar_Archivo.triggered.connect(self.action_guardar_archivo) self.ui.Mostrar_Tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.Buscar_pushButton.clicked.connect(self.buscar_ID) self.ui.Dibujar_pushButton.clicked.connect(self.dibujar_particulas) self.ui.Limpiar_pushButton.clicked.connect(self.limpiar_pantalla) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def ordenar_ID(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.particulas.sort(1) self.click_mostrar() @Slot() def ordenar_Distancia(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.particulas.sort(2) self.click_mostrar() @Slot() def ordenar_Velocidad(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.particulas.sort(3) self.click_mostrar() @Slot() def ordenar_ID_Tabla(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: self.particulas.sort(1) self.mostrar_tabla() @Slot() def ordenar_Distancia_Tabla(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: self.particulas.sort(2) self.mostrar_tabla() @Slot() def ordenar_Velocidad_Tabla(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: self.particulas.sort(3) self.mostrar_tabla() @Slot() def dibujar_particulas(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: for particula in self.particulas: pen = QPen() color = QColor(particula.red, particula.green, particula.blue) pen.setColor(color) pen.setWidth(2) self.scene.addEllipse(particula.origen_x, particula.origen_y, 3, 3, pen) self.scene.addEllipse(particula.destino_x, particula.destino_y, 3, 3, pen) self.scene.addLine(particula.origen_x, particula.origen_y, particula.destino_x, particula.destino_y, pen) @Slot() def limpiar_pantalla(self): self.scene.clear() @Slot() def buscar_ID(self): id = self.ui.Buscar_lineEdit.text() encontrado = False for particula in self.particulas: if id == str(particula.id): self.ui.Table.clear() self.ui.Table.setRowCount(1) ID_widget = QTableWidgetItem(str(particula.id)) Origen_X_widget = QTableWidgetItem(str(particula.origen_x)) Origen_Y_widget = QTableWidgetItem(str(particula.origen_y)) Destino_X_widget = QTableWidgetItem(str(particula.destino_x)) Destino_Y_widget = QTableWidgetItem(str(particula.destino_y)) Velocidad_widget = QTableWidgetItem(str(particula.velocidad)) Red_widget = QTableWidgetItem(str(particula.red)) Green_widget = QTableWidgetItem(str(particula.green)) Blue_widget = QTableWidgetItem(str(particula.blue)) Distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.Table.setItem(0, 0, ID_widget) self.ui.Table.setItem(0, 1, Origen_X_widget) self.ui.Table.setItem(0, 2, Origen_Y_widget) self.ui.Table.setItem(0, 3, Destino_X_widget) self.ui.Table.setItem(0, 4, Destino_Y_widget) self.ui.Table.setItem(0, 5, Velocidad_widget) self.ui.Table.setItem(0, 6, Red_widget) self.ui.Table.setItem(0, 7, Green_widget) self.ui.Table.setItem(0, 8, Blue_widget) self.ui.Table.setItem(0, 9, Distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atención", f'La particula con el ID "{id}" no fue encontrada' ) @Slot() def mostrar_tabla(self): self.ui.Table.setColumnCount(10) headers = ["ID", "Origen en X", "Origen en Y", "Destino en X", "Destino en Y", "Velocidad", "Red", "Green", "Blue", "Distancia"] self.ui.Table.setHorizontalHeaderLabels(headers) self.ui.Table.setRowCount(len(self.particulas)) row = 0 for particula in self.particulas: ID_widget = QTableWidgetItem(str(particula.id)) Origen_X_widget = QTableWidgetItem(str(particula.origen_x)) Origen_Y_widget = QTableWidgetItem(str(particula.origen_y)) Destino_X_widget = QTableWidgetItem(str(particula.destino_x)) Destino_Y_widget = QTableWidgetItem(str(particula.destino_y)) Velocidad_widget = QTableWidgetItem(str(particula.velocidad)) Red_widget = QTableWidgetItem(str(particula.red)) Green_widget = QTableWidgetItem(str(particula.green)) Blue_widget = QTableWidgetItem(str(particula.blue)) Distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.Table.setItem(row, 0, ID_widget) self.ui.Table.setItem(row, 1, Origen_X_widget) self.ui.Table.setItem(row, 2, Origen_Y_widget) self.ui.Table.setItem(row, 3, Destino_X_widget) self.ui.Table.setItem(row, 4, Destino_Y_widget) self.ui.Table.setItem(row, 5, Velocidad_widget) self.ui.Table.setItem(row, 6, Red_widget) self.ui.Table.setItem(row, 7, Green_widget) self.ui.Table.setItem(row, 8, Blue_widget) self.ui.Table.setItem(row, 9, Distancia_widget) row +=1 @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName( self, 'Abrir Archivo', '.', 'JSON (*.json)' )[0] if self.particulas.abrir(ubicacion): QMessageBox.information( self, "Éxito", "Apertura exitosa del archivo en " + ubicacion ) else: QMessageBox.critical( self, "Error", "Fallo al intentar abir el archivo en " + ubicacion ) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName( self, 'Guardar Archivo', '.', 'JSON (*.json)' )[0] if self.particulas.guardar(ubicacion): QMessageBox.information( self, "Éxito", "Archivo creado correctamente en " + ubicacion ) else: QMessageBox.critical( self, "Error", "No se pudo crear el archivo en " + ubicacion ) @Slot() def click_agregar_inicio(self): Id = self.ui.ID_spinBox.value() Origen_X = self.ui.Origen_X_spinBox.value() Origen_Y = self.ui.Origen_Y_spinBox.value() Destino_X = self.ui.Destino_X_spinBox.value() Destino_Y = self.ui.Destino_Y_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, Origen_X, Origen_Y, Destino_X, Destino_Y, Velocidad, Red, Green, Blue) self.particulas.agregar_inicio(particula) @Slot() def click_agregar_final(self): Id = self.ui.ID_spinBox.value() Origen_X = self.ui.Origen_X_spinBox.value() Origen_Y = self.ui.Origen_Y_spinBox.value() Destino_X = self.ui.Destino_X_spinBox.value() Destino_Y = self.ui.Destino_Y_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, Origen_X, Origen_Y, Destino_X, Destino_Y, Velocidad, Red, Green, Blue) self.particulas.agregar_final(particula) @Slot() def click_mostrar(self): self.ui.Salida.clear() self.ui.Salida.insertPlainText(str(self.particulas))
class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): # Initialise the UI self.display = None super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Current file self._filename = None self._filetype = None self._last_file_handler = None # Importers / Exporters self._file_handlers = [] # Update our window caption self._caption = "Zoxel" # Our global state + user plugins if platform.system() == "Windows": appdata = os.path.expandvars("%APPDATA%") elif platform.system() == "Darwin": appdata = os.path.expanduser("~/Library/Application Support") else: appdata = os.path.expanduser("~/.local/share") self.user_plugins_path = os.path.join(appdata, "Zoxel", "plugins") if not os.path.isdir(self.user_plugins_path): os.makedirs(self.user_plugins_path, 16877) QtCore.QCoreApplication.setOrganizationName("Zoxel") QtCore.QCoreApplication.setApplicationName("Zoxel") QtCore.QSettings.setDefaultFormat(QtCore.QSettings.IniFormat) QtCore.QSettings.setPath(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, appdata) self.settings = QtCore.QSettings() self.state = {} # Our animation timer self._timer = QtCore.QTimer(self) self.connect(self._timer, QtCore.SIGNAL("timeout()"), self.on_animation_tick) self._anim_speed = 200 # Load our state if possible self.load_state() # Create our GL Widget try: glw = GLWidget(self.ui.glparent) self.ui.glparent.layout().addWidget(glw) self.display = glw except Exception as E: QtWidgets.QMessageBox.warning(self, "Initialisation Failed", str(E)) exit(1) # Load default model dimensions width = self.get_setting("default_model_width") height = self.get_setting("default_model_height") depth = self.get_setting("default_model_depth") if width: self.resize_voxels(width, height, depth) # Resize is detected as a change, discard changes self.display.voxels.saved() # Create our palette widget voxels = PaletteWidget(self.ui.palette, RGBvalue=self.ui.paletteRGBvalue) self.ui.palette.layout().addWidget(voxels) self.color_palette = voxels # More UI state value = self.get_setting("display_axis_grids") if value is not None: self.ui.action_axis_grids.setChecked(value) self.display.axis_grids = value value = self.get_setting("background_color") if value is not None: self.display.background = QtGui.QColor.fromRgb(*value) value = self.get_setting("voxel_edges") if value is not None: self.display.voxel_edges = value self.ui.action_voxel_edges.setChecked(value) else: self.ui.action_voxel_edges.setChecked(self.display.voxel_edges) value = self.get_setting("occlusion") if value is None: value = True self.display.voxels.occlusion = value self.ui.action_occlusion.setChecked(value) # Connect some signals if self.display: self.display.voxels.notify = self.on_data_changed self.display.mouse_click_event.connect(self.on_tool_mouse_click) self.display.start_drag_event.connect(self.on_tool_drag_start) self.display.end_drag_event.connect(self.on_tool_drag_end) self.display.drag_event.connect(self.on_tool_drag) if self.color_palette: self.color_palette.changed.connect(self.on_color_changed) # Initialise our tools self._tool_group = QtWidgets.QActionGroup(self.ui.toolbar_drawing) self._tools = [] self._tools_priorities = {} # Setup window self.update_caption() self.refresh_actions() self.display.ready = True # Update Check try: latest_tag = urllib.urlopen( "https://github.com/chrmoritz/zoxel/releases/latest").geturl() if not latest_tag.endswith(ZOXEL_TAG): responce = QtWidgets.QMessageBox.question( self, "Outdated Zoxel version", "A new version of Zoxel is available! Do you want to update now?", buttons=(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No), defaultButton=QtWidgets.QMessageBox.Yes) if responce == QtWidgets.QMessageBox.Yes: webbrowser.open(latest_tag, 2) sys.exit(0) except IOError: pass def on_animation_tick(self): self.on_action_anim_next_triggered() @QtCore.Slot() def on_action_about_triggered(self): dialog = AboutDialog(self) if dialog.exec_(): pass @QtCore.Slot() def on_action_axis_grids_triggered(self): self.display.axis_grids = self.ui.action_axis_grids.isChecked() self.set_setting("display_axis_grids", self.display.axis_grids) @QtCore.Slot() def on_action_voxel_edges_triggered(self): self.display.voxel_edges = self.ui.action_voxel_edges.isChecked() self.set_setting("voxel_edges", self.display.voxel_edges) @QtCore.Slot() def on_action_zoom_in_triggered(self): self.display.zoom_in() @QtCore.Slot() def on_action_zoom_out_triggered(self): self.display.zoom_out() @QtCore.Slot() def on_action_new_triggered(self): if self.display.voxels.changed: if not self.confirm_save(): return # Clear our data self._filename = None self._filetype = None self.display.clear() self.display.voxels.saved() self.update_caption() self.refresh_actions() @QtCore.Slot() def on_action_wireframe_triggered(self): self.display.wireframe = self.ui.action_wireframe.isChecked() self.set_setting("display_wireframe", self.display.wireframe) @QtCore.Slot() def on_action_save_triggered(self): # Save self.save() @QtCore.Slot() def on_action_saveas_triggered(self): # Save self.save(True) @QtCore.Slot() def on_action_open_triggered(self): # Load self.load() @QtCore.Slot() def on_action_undo_triggered(self): # Undo self.display.voxels.undo() self.display.refresh() @QtCore.Slot() def on_action_redo_triggered(self): # Redo self.display.voxels.redo() self.display.refresh() @QtCore.Slot() def on_action_resize_triggered(self): # Resize model dimensions dialog = ResizeDialog(self) dialog.ui.width.setValue(self.display.voxels.width) dialog.ui.height.setValue(self.display.voxels.height) dialog.ui.depth.setValue(self.display.voxels.depth) if dialog.exec_(): width = dialog.ui.width.value() height = dialog.ui.height.value() depth = dialog.ui.depth.value() self.resize_voxels(width, height, depth) def resize_voxels(self, width, height, depth): new_width_scale = float(width) / self.display.voxels.width new_height_scale = float(height) / self.display.voxels.height new_depth_scale = float(depth) / self.display.voxels.depth self.display.voxels.resize(width, height, depth) self.display.grids.scale_offsets(new_width_scale, new_height_scale, new_depth_scale) self.display.refresh() # Remember these dimensions self.set_setting("default_model_width", width) self.set_setting("default_model_height", height) self.set_setting("default_model_depth", depth) @QtCore.Slot() def on_action_reset_camera_triggered(self): self.display.reset_camera() @QtCore.Slot() def on_action_occlusion_triggered(self): self.display.voxels.occlusion = self.ui.action_occlusion.isChecked() self.set_setting("occlusion", self.display.voxels.occlusion) self.display.refresh() @QtCore.Slot() def on_action_background_triggered(self): # Choose a background color color = QtGui.QColorDialog.getColor() if color.isValid(): self.display.background = color color = (color.red(), color.green(), color.blue()) self.set_setting("background_color", color) @QtCore.Slot() def on_action_anim_add_triggered(self): value, res = QtGui.QInputDialog.getInt( self, "Add frame", "Add new frame after:", self.display.voxels.get_frame_number() + 1, 1, self.display.voxels.get_frame_count()) if res: self.display.voxels.insert_frame(value, True) self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_add_empty_triggered(self): value, res = QtGui.QInputDialog.getInt( self, "Add frame", "Add new frame after:", self.display.voxels.get_frame_number() + 1, 1, self.display.voxels.get_frame_count()) if res: self.display.voxels.insert_frame(value, False) self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_copy_triggered(self): value, res = QtGui.QInputDialog.getInt( self, "Copy frame", "Replace current frame with:", 1, 1, self.display.voxels.get_frame_count()) if res: self.display.voxels.copy_to_current(value) self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_delete_triggered(self): ret = QtGui.QMessageBox.question( self, "Zoxel", "Do you really want to delete this frame?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if ret == QtGui.QMessageBox.Yes: self.display.voxels.delete_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_play_triggered(self): self._timer.start(self._anim_speed) self.refresh_actions() @QtCore.Slot() def on_action_anim_stop_triggered(self): self._timer.stop() self.refresh_actions() @QtCore.Slot() def on_action_anim_next_triggered(self): self.display.voxels.select_next_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_previous_triggered(self): self.display.voxels.select_previous_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_settings_triggered(self): pass @QtCore.Slot() def on_action_rotate_x_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.X_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_y_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Y_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_z_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Z_AXIS) self.display.refresh() @QtCore.Slot() def on_action_mirror_x_triggered(self): self.display.voxels.mirror_in_axis(self.display.voxels.X_AXIS) self.display.refresh() @QtCore.Slot() def on_action_mirror_y_triggered(self): self.display.voxels.mirror_in_axis(self.display.voxels.Y_AXIS) self.display.refresh() @QtCore.Slot() def on_action_mirror_z_triggered(self): self.display.voxels.mirror_in_axis(self.display.voxels.Z_AXIS) self.display.refresh() @QtCore.Slot() def on_action_voxel_color_triggered(self): # Choose a voxel color color = QtGui.QColorDialog.getColor() if color.isValid(): self.color_palette.color = color @QtCore.Slot() def on_paletteRGBvalue_editingFinished(self): s = self.ui.paletteRGBvalue.text() i = s.find('rgb(') if i >= 0: c = map(int, s[i + 4:s.find(')')].split(',')) color = QtGui.QColor(c[0], c[1], c[2]) else: color = QtGui.QColor() color.setNamedColor(s) if color.isValid(): self.color_palette.color = color @QtCore.Slot() def on_action_export_image_triggered(self): self.display.paintGL() png = QtGui.QPixmap(self.display.grabFrameBuffer()) choices = "PNG Image (*.png);;JPEG Image (*.jpg)" # Grab our default location directory = self.get_setting("default_directory") # grab a filename filename, filetype = QtGui.QFileDialog.getSaveFileName( self, caption="Export Image As", filter=choices, dir=directory) if not filename: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Save the PNG png.save(filename, filetype.split()[0]) @QtCore.Slot() def on_action_export_troxel_triggered(self): from base64 import b64encode from struct import pack data = [ self.display.voxels.width, self.display.voxels.height, self.display.voxels.depth, 0, 85, 0, 0 ] vox = [] for z in xrange(self.display.voxels.depth - 1, -1, -1): for y in xrange(self.display.voxels.height): for x in xrange(self.display.voxels.width - 1, -1, -1): v = self.display.voxels.get(x, y, z) if v: vox.append(((v & 0xff000000) >> 24, (v & 0xff0000) >> 16, (v & 0xff00) >> 8)) else: vox.append(None) rcolors = {} for v in vox: if v: hex = v[2] + 256 * v[1] + 65536 * v[0] data.extend((0, v[0], v[1], v[2], 255)) rcolors[hex] = (len(data) - 7) // 5 data[5] = (len(data) - 7) // 1280 short = data[5] == 0 data[6] = (len(data) - 7) // 5 % 256 i = 0 length = len(vox) while i < length: r = 1 while r < 129: if (i + r < length) and (vox[i + r - 1] == vox[i + r]): r += 1 else: break if r > 1: data.append(126 + r) if vox[i]: index = rcolors[vox[i][2] + 256 * vox[i][1] + 65536 * vox[i][0]] if short: data.append(index) else: data.extend((index // 256, index % 256)) else: if short: data.append(0) else: data.extend((0, 0)) i += r webbrowser.open( "https://chrmoritz.github.io/Troxel/#m=" + b64encode(pack('B' * len(data), *data)), 2) @QtCore.Slot() def on_action_copy_selection_to_frame_triggered(self): target_frame, res = QtWidgets.QInputDialog.getInt( self, "Copy selection", "Copy selection to frame:", 1, 1, self.display.voxels.get_frame_count()) if res: target_frame -= 1 original_frame = self.display.voxels.get_frame_number() original_selection = copy.deepcopy(self.display.voxels._selection) if target_frame != original_frame: stamp = [] for x, y, z in self.display.voxels._selection: col = self.display.voxels.get(x, y, z) stamp.append((x, y, z, col)) self.display.voxels.select_frame(target_frame) btns = QtWidgets.QMessageBox.StandardButton.Abort | QtWidgets.QMessageBox.StandardButton.Ignore if (self.display.voxels.is_free( stamp ) or QtWidgets.QMessageBox.question( self, "Copy selection", "This would override voxel data in the targeted frame!", btns) == QtWidgets.QMessageBox.Ignore): for x, y, z, col in stamp: self.display.voxels.set(x, y, z, col) self.display.voxels.select_frame(original_frame) self.display.voxels._selection = original_selection self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_reload_plugins_triggered(self): # reset plugin state self.ui.toolbar_drawing.clear() for a in self._tool_group.actions(): self._tool_group.removeAction(a) self._tools = [] self._tools_priorities.clear() self._file_handlers = [] self._last_file_handler = None # reload default plugins from plugins import __all__ as plugins from sys import modules for p in plugins: reload(modules["plugins." + p]) # reload user plugins from imp import load_source for p in os.listdir(self.user_plugins_path): if p.endswith(".py"): load_source( os.path.splitext(p)[0], os.path.join(self.user_plugins_path, p)) @QtCore.Slot() def on_action_manage_plugins_triggered(self): webbrowser.open('file://' + self.user_plugins_path) def on_tool_mouse_click(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_mouse_click(data) def on_tool_drag_start(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_drag_start(data) def on_tool_drag(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_drag(data) def on_tool_drag_end(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_drag_end(data) # Confirm if user wants to save before doing something drastic. # returns True if we should continue def confirm_save(self): responce = QtWidgets.QMessageBox.question( self, "Save changes?", "Save changes before discarding?", buttons=(QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.No)) if responce == QtWidgets.QMessageBox.StandardButton.Save: if not self.save(): return False elif responce == QtWidgets.QMessageBox.StandardButton.Cancel: return False return True # Voxel data changed signal handler def on_data_changed(self): self.update_caption() self.refresh_actions() # Color selection changed handler def on_color_changed(self): self.display.voxel_color = self.color_palette.color # Return a section of our internal config def get_setting(self, name): if name in self.state: return self.state[name] return None # Set some config. Value should be a serialisable type def set_setting(self, name, value): self.state[name] = value def closeEvent(self, event): # Save state self.save_state() if self.display.voxels.changed: if not self.confirm_save(): event.ignore() return event.accept() # Save our state def save_state(self): try: state = json.dumps(self.state) self.settings.setValue("system/state", state) except Exception as E: # XXX Fail. Never displays because we're on our way out error = QtWidgets.QErrorMessage(self) error.showMessage(str(E)) # Load our state def load_state(self): try: state = self.settings.value("system/state") if state: self.state = json.loads(state) except Exception as E: error = QtWidgets.QErrorMessage(self) error.showMessage(str(E)) # Update the window caption to reflect the current state def update_caption(self): caption = "Zoxel" if self._filename: caption += " - [%s]" % self._filename else: caption += " - [Unsaved model]" if self.display and self.display.voxels.changed: caption += " *" numframes = self.display.voxels.get_frame_count() frame = self.display.voxels.get_frame_number() + 1 if numframes > 1: caption += " - Frame {0} of {1}".format(frame, numframes) if caption != self._caption: self.setWindowTitle(caption) self._caption = caption # Save the current data def save(self, newfile=False): # Find the handlers that support saving handlers = [x for x in self._file_handlers if hasattr(x, 'save')] saved = False filename = self._filename filetype = self._filetype handler = self._last_file_handler # Build list of available types choices = [] for exporter in handlers: choices.append("%s (%s)" % (exporter.description, exporter.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename if we need one if newfile or not filename: filename, filetype = QtWidgets.QFileDialog.getSaveFileName( self, caption="Save As", filter=choices, dir=directory, selectedFilter="Zoxel Files (*.zox)") if not filename: return handler = None # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler if we need to if not handler: for exporter in handlers: ourtype = "%s (%s)" % (exporter.description, exporter.filetype) if filetype == ourtype: handler = exporter # Call the save handler try: handler.save(filename) saved = True except Exception as Ex: QtWidgets.QMessageBox.warning(self, "Save Failed", str(Ex)) # If we saved, clear edited state if saved: self._filename = filename self._filetype = filetype self._last_file_handler = handler self.display.voxels.saved() self.update_caption() self.refresh_actions() return saved # Registers an file handler (importer/exporter) with the system def register_file_handler(self, handler): self._file_handlers.append(handler) # load a file def load(self): # If we have changes, perhaps we should save? if self.display.voxels.changed: if not self.confirm_save(): return # Find the handlers that support loading handler = None handlers = [x for x in self._file_handlers if hasattr(x, 'load')] # Build list of types we can load choices = ["All Files (*)"] for importer in handlers: choices.append("%s (%s)" % (importer.description, importer.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename filename, filetype = QtWidgets.QFileDialog.getOpenFileName( self, caption="Open file", filter=choices, dir=directory, selectedFilter="All Files (*)") if not filename: return if filetype == "All Files (*)": filetype = None for importer in handlers: if filename.endswith(importer.filetype[1:]): filetype = "%s (%s)" % (importer.description, importer.filetype) break if filetype is None: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler for importer in handlers: ourtype = "%s (%s)" % (importer.description, importer.filetype) if filetype == ourtype: handler = importer self._last_file_handler = handler # Load the file self.display.clear() self.display.voxels.disable_undo() self._filename = None try: handler.load(filename) self._filename = filename self._filetype = filetype except Exception as Ex: self.display.voxels.enable_undo() QtWidgets.QMessageBox.warning(self, "Could not load file", str(Ex)) self.display.build_grids() # self.display.voxels.resize() self.display.voxels.saved() self.display.reset_camera() self.update_caption() self.refresh_actions() self.display.voxels.enable_undo() self.display.refresh() # Registers a tool in the drawing toolbar def register_tool(self, tool, activate=False): self._tools.append(tool) self._tool_group.addAction(tool.get_action()) before = None bp = 9223372036854775807 for p, action in self._tools_priorities.iteritems(): if p > tool.priority and p < bp: bp = p before = action self.ui.toolbar_drawing.insertAction(before, tool.get_action()) self._tools_priorities[tool.priority] = tool.get_action() if activate: tool.get_action().setChecked(True) # Return the active tool def get_active_tool(self): action = self._tool_group.checkedAction() if not action: return None # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: return tool return None # Load and initialise all plugins def load_plugins(self): # load default plugins from plugins import __all__ as plugins from importlib import import_module for p in plugins: import_module('plugins.' + p) # load user plugins from imp import load_source for p in os.listdir(self.user_plugins_path): if p.endswith(".py"): load_source( os.path.splitext(p)[0], os.path.join(self.user_plugins_path, p)) # Update the state of the UI actions def refresh_actions(self): num_frames = self.display.voxels.get_frame_count() self.ui.action_anim_delete.setEnabled(num_frames > 1) self.ui.action_anim_previous.setEnabled(num_frames > 1) self.ui.action_anim_next.setEnabled(num_frames > 1) self.ui.action_anim_play.setEnabled(num_frames > 1 and not self._timer.isActive()) self.ui.action_anim_stop.setEnabled(self._timer.isActive()) self.update_caption()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.swarm = Swarm() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.agregar_final_pushButton.clicked.connect(self.click_agregar) self.ui.agregar_inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.ver_grafos_action.triggered.connect(self.grafos) self.ui.actionBusqueda.triggered.connect(self.busqueda_grafos) self.ui.actionId.triggered.connect(self.action_ordenar_id) self.ui.actionDistancia.triggered.connect( self.action_ordenar_distancia) self.ui.actionVelocidad.triggered.connect( self.action_ordenar_velocidad) self.ui.mostrar_tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_iid) self.ui.dibujar_pushButton.clicked.connect(self.dibujar) self.ui.limpiar_pushButton.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) @Slot() def grafos(self): self.ui.salida.clear() self.ui.salida.insertPlainText(self.swarm.ver_grafos()) print(self.swarm.ver_grafos()) @Slot() def action_ordenar_id(self): self.swarm.ordenar_id() self.mostrar_tabla() self.click_mostrar() @Slot() def action_ordenar_distancia(self): self.swarm.ordenar_distancia() self.mostrar_tabla() self.click_mostrar() @Slot() def action_ordenar_velocidad(self): self.swarm.ordenar_velocidad() self.mostrar_tabla() self.click_mostrar() def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def dibujar(self): for particula in self.swarm: pen = QPen() pen.setWidth(2) r = particula.red g = particula.green b = particula.blue color = QColor(r, g, b) pen.setColor(color) self.scene.addEllipse(particula.origen_x, particula.origen_y, 3, 3, pen) self.scene.addEllipse(particula.destino_x, particula.destino_y, 3, 3, pen) self.scene.addLine(particula.origen_x + 3, particula.origen_y + 3, particula.destino_x, particula.destino_y, pen) @Slot() def limpiar(self): self.scene.clear() @Slot() def buscar_iid(self): iid = self.ui.buscar_lineEdit.text() encontrado = False for particula in self.swarm: if iid == str(particula.iid): self.ui.tabla.clear() self.ui.tabla.setRowCount(1) iid_widget = QTableWidgetItem(str(particula.iid)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(0, 0, iid_widget) self.ui.tabla.setItem(0, 1, origen_x_widget) self.ui.tabla.setItem(0, 2, origen_y_widget) self.ui.tabla.setItem(0, 3, destino_x_widget) self.ui.tabla.setItem(0, 4, destino_y_widget) self.ui.tabla.setItem(0, 5, velocidad_widget) self.ui.tabla.setItem(0, 6, red_widget) self.ui.tabla.setItem(0, 7, green_widget) self.ui.tabla.setItem(0, 8, blue_widget) self.ui.tabla.setItem(0, 9, distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atencion", f'La particula con el id "{iid}" no fue encontrada') @Slot() def mostrar_tabla(self): self.ui.tabla.setColumnCount(10) headers = [ "Id", "Origen x", "Origen y", "Destino x", "Destino y", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.swarm)) row = 0 for particula in self.swarm: iid_widget = QTableWidgetItem(str(particula.iid)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, iid_widget) self.ui.tabla.setItem(row, 1, origen_x_widget) self.ui.tabla.setItem(row, 2, origen_y_widget) self.ui.tabla.setItem(row, 3, destino_x_widget) self.ui.tabla.setItem(row, 4, destino_y_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 @Slot() def action_abrir_archivo(self): # print('abrir_archivo') ubicacion = QFileDialog.getOpenFileName(self, 'Abrir Archivo', '.', 'JSON (*.json)')[0] if self.swarm.abrir(ubicacion): QMessageBox.information(self, "Exito", "Se abrio el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "Error al abrir el archivo" + ubicacion) self.mostrar_tabla() self.click_mostrar() @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName(self, 'Guardar archivo', '.', 'JSON (*.json)')[0] print(ubicacion) if self.swarm.guardar(ubicacion): QMessageBox.information(self, "Exito", "Se pudo crear el archivo " + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo " + ubicacion) @Slot() def click_mostrar(self): self.ui.salida.clear() self.ui.salida.insertPlainText(str(self.swarm)) @Slot() def click_agregar(self): iid = self.ui.id_spinBox.value() origen_x = self.ui.origenx_spinBox.value() origen_y = self.ui.origeny_spinBox.value() destino_x = self.ui.destinox_spinBox.value() destino_y = 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(iid, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.swarm.agregar_final(particula) @Slot() def click_agregar_inicio(self): iid = self.ui.id_spinBox.value() origen_x = self.ui.origenx_spinBox.value() origen_y = self.ui.origeny_spinBox.value() destino_x = self.ui.destinox_spinBox.value() destino_y = 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(iid, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.swarm.agregar_inicio(particula) @Slot() def busqueda_grafos(self): self.swarm.quitar_peso() self.ui.salida.clear() origen = (self.ui.origenx_spinBox.value(), self.ui.origeny_spinBox.value()) recorrido = self.swarm.algoritmo_busqueda_profundidad(origen) print('Profundidad') self.ui.salida.insertPlainText('Profundidad' + '\n') for i in recorrido: self.ui.salida.insertPlainText(str(i) + '\n') print(i) recorrido2 = self.swarm.algoritmo_busqueda_Amplitud(origen) print('\n' + 'Amplitud') self.ui.salida.insertPlainText('\n' + 'Amplitud' + '\n') for i in recorrido2: self.ui.salida.insertPlainText(str(i) + '\n') print(i)
class MainWindow(QMainWindow): def __init__(self): super().__init__() # Attributes self.comment_options = Comment.default_options self.language = Python() # UI setup self._ui = Ui_MainWindow() self._ui.setupUi(self) self.__setup_ui() # Widgets connections self.__connect_widgets() def __setup_ui(self): # TextEdit font = QFont('Monospace') font.setStyleHint(QFont.TypeWriter) self._ui.textEdit.setFont(font) # ===== Tab Pretty # Defaults self._ui.comboBox_pretty_filling.setCurrentText(self.comment_options['filling']) self._ui.comboBox_pretty_filling_2.setCurrentText(self.comment_options['filling2']) self._ui.checkBox_pretty_capitalize.setChecked(self.comment_options['capitalize']) self._ui.horizontalSlider_pretty_ncols.setValue(self.comment_options['length']) self._ui.checkBox_pretty_right.setChecked(self.comment_options['right-char']) # Filling characters self._ui.comboBox_pretty_filling.addItems(Comment.filling_chars) self._ui.comboBox_pretty_filling_2.addItems(Comment.filling_chars) # Other self._ui.label_pretty_ncols.setText(str(self._ui.horizontalSlider_pretty_ncols.value())) def __connect_widgets(self): # UI display self._ui.horizontalSlider_pretty_ncols.valueChanged.connect( lambda val: self._ui.label_pretty_ncols.setText(str(val)) ) # User interactions # Tab Pretty def link_filling_chars(current): if self._ui.checkBox_pretty_link.isChecked(): self._ui.comboBox_pretty_filling_2.setCurrentText(current) self._ui.comboBox_pretty_filling.currentTextChanged.connect(link_filling_chars) self._ui.pushButton_pretty_load_text.clicked.connect( lambda: self.load_comment_options(self._ui.textEdit.toPlainText()) ) self._ui.pushButton_pretty_options_file.clicked.connect( lambda b: self.load_comment_options() ) self._ui.pushButton_copy_textEdit.clicked.connect( lambda: QApplication.clipboard().setText(self._ui.textEdit.toPlainText()) ) self._ui.horizontalSlider_pretty_ncols.valueChanged.connect( lambda i: self.update_comments('length', i) ) self._ui.lineEdit_pretty_comment.textChanged.connect( lambda t: self.update_comments() ) self._ui.checkBox_pretty_capitalize.clicked.connect( lambda b: self.update_comments('capitalize', b) ) self._ui.comboBox_pretty_filling.currentTextChanged.connect( lambda c: self.update_comments('filling', c) ) self._ui.comboBox_pretty_filling_2.currentTextChanged.connect( lambda c: self.update_comments('filling2', c) ) self._ui.checkBox_pretty_right.clicked.connect( lambda b: self.update_comments('right-char', b) ) # # Data structure to manage signals of Pretty tab: # # tuples (trigger signal, key of comment options) # connections_prettytab = [ # (self._ui.horizontalSlider_pretty_ncols.valueChanged, lambda i: ('length', i)), # (self._ui.lineEdit_pretty_comment.textChanged, lambda t: ('dummy', None)), # (self._ui.comboBox_pretty_filling.currentTextChanged, lambda c: ('filling', c)), # (self._ui.checkBox_pretty_capitalize.clicked, lambda b: ('capitalize', b)) # ] # # for x in connections_prettytab: # triggerfun, argsfun = x[0], x[1] # print(*argsfun(1)) # triggerfun.connect(lambda arg: self.update_comments(*argsfun(arg))) def update_comments(self, key=None, new_value=None): if key is not None: self.comment_options[key] = new_value text = Comment.gen_comment(self._ui.lineEdit_pretty_comment.text(), self.language, self.comment_options) self._ui.textEdit.setText(text) def load_comment_options(self, data=None): print(data) try: if data is None: file, _ = QFileDialog.getOpenFileName(self, 'Open file') with open(file, 'r') as f: data = f.read() self.comment_options = Comment.parse_options(data) self.__setup_ui() except ValueError: QMessageBox.information(self, 'Error', 'Parsing failed')
class MainWindow(QMainWindow): # funcion def __init__(self): # super ==> metodo super(MainWindow, self).__init__() # self se usa para que nuestro objeto exista globalmente y no solo en el constructor. self.administrador = Administrador() # Ui_MainWindow() ==> objeto referenciado self.ui = Ui_MainWindow() # setupUi ==> metodo para enbeber la instruccion self.ui.setupUi(self) # conectar las instrucciones de "conectar_final", # "conectar_inicio" y "mostrar" self.ui.agregar_final_pushButton.clicked.connect(self.click_agregar) self.ui.agregar_inicio_pushButton.clicked.connect(self.click_agregar_inicio) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) # conectar las acciones self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) # Botones para mostrar la tabla y buscar self.ui.mostrar_tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_identificador) # buscar libros @Slot() def buscar_identificador(self): identificador = self.ui.buscar_lineEdit.text() # bandera encontrado = False for particula in self.administrador: if identificador == particula.identificador: self.ui.tabla.clear() self.ui.tabla.setRowCount(1) # asignar 10 columnas en la tabla self.ui.tabla.setColumnCount(10) # asigna nombres a las columnas headers = ["ID", "Origen X", "Origen Y", "Destino X", "Destino Y", "Velocidad", "Red", "Green", "Blue", "Distancia"] # presenta la coleccion "headers" en el encabezado de las columnas self.ui.tabla.setHorizontalHeaderLabels(headers) identificador_widget = QTableWidgetItem(str(particula.identificador)) origenx_widget = QTableWidgetItem(str(particula.origenx)) origeny_widget = QTableWidgetItem(str(particula.origeny)) destinox_widget = QTableWidgetItem(str(particula.destinox)) destinoy_widget = QTableWidgetItem(str(particula.destinoy)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) # imprimir solo una particula en la fila self.ui.tabla.setItem(0, 0, identificador_widget) self.ui.tabla.setItem(0, 1, origenx_widget) self.ui.tabla.setItem(0, 2, origeny_widget) self.ui.tabla.setItem(0, 3, destinox_widget) self.ui.tabla.setItem(0, 4, destinoy_widget) self.ui.tabla.setItem(0, 5, velocidad_widget) self.ui.tabla.setItem(0, 6, red_widget) self.ui.tabla.setItem(0, 7, green_widget) self.ui.tabla.setItem(0, 8, blue_widget) self.ui.tabla.setItem(0, 9, distancia_widget) # validador de la bandera encontrado = True return # negacion de bandera if not encontrado: QMessageBox.warning( self, "Aviso", f'La partícula con identificador "{identificador}" no fue encontrada' ) # funcionamiento del boton de mostrar_tabla @Slot() def mostrar_tabla(self): # asignar 10 columnas en la tabla self.ui.tabla.setColumnCount(10) # asigna nombres a las columnas headers = ["ID", "Origen X", "Origen Y", "Destino X", "Destino Y", "Velocidad", "Red", "Green", "Blue", "Distancia"] # presenta la coleccion "headers" en el encabezado de las columnas self.ui.tabla.setHorizontalHeaderLabels(headers) # asignacion de filas # len(self.libreria) ==> metodo para obtener la cantidad de elementos en la lista self.ui.tabla.setRowCount(len(self.administrador)) row = 0 # sacarparticulas del administrador for particula in self.administrador: identificador_widget = QTableWidgetItem(str(particula.identificador)) origenx_widget = QTableWidgetItem(str(particula.origenx)) origeny_widget = QTableWidgetItem(str(particula.origeny)) destinox_widget = QTableWidgetItem(str(particula.destinox)) destinoy_widget = QTableWidgetItem(str(particula.destinoy)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) red_widget = QTableWidgetItem(str(particula.red)) green_widget = QTableWidgetItem(str(particula.green)) blue_widget = QTableWidgetItem(str(particula.blue)) distancia_widget = QTableWidgetItem(str(particula.distancia)) # metodo para asignar posicion a los elementos de cada particula self.ui.tabla.setItem(row, 0, identificador_widget) self.ui.tabla.setItem(row, 1, origenx_widget) self.ui.tabla.setItem(row, 2, origeny_widget) self.ui.tabla.setItem(row, 3, destinox_widget) self.ui.tabla.setItem(row, 4, destinoy_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, red_widget) self.ui.tabla.setItem(row, 7, green_widget) self.ui.tabla.setItem(row, 8, blue_widget) self.ui.tabla.setItem(row, 9, distancia_widget) #incrementar el contador de filas row += 1 @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName( self, 'Abrir Archivo', '.', 'JSON (*.json)' )[0] if self.administrador.abrir(ubicacion): QMessageBox.information( self, "Abrir", "Se abrió el archivo " + '\n' '\n' + ubicacion ) else: QMessageBox.critical( self, "Abrir", "Error al abrir el archivo " + '\n' '\n' + ubicacion ) @Slot() def action_guardar_archivo(self): # getSaveFileName ==> metodo para recibir parametros y guardarlos # ubicacion: asigna posiciones desde cero ubicacion = QFileDialog.getSaveFileName( self, # el dialogo se lanza desde aqui 'Guardar Archivo', # titulo de la ventana de dialogo '.', # directorio desde el que se corre el archivo ejecutable, desde la carpeta del proyecto 'JSON (*.json)' # extencion del archivo a guardar )[0] print(ubicacion) if self.administrador.guardar(ubicacion): QMessageBox.information( self, "Guardar", "Archivo guardado en: " + '\n' '\n' + ubicacion ) else: QMessageBox.critical( self, "Guardar", "Archivo no guardado: " + '\n' '\n' + ubicacion ) @Slot() def click_mostrar(self): # limpiar pantalla de PlaintText self.ui.salida.clear() # salida datos introducidos por pantalla self.ui.salida.insertPlainText(str(self.administrador)) # funcion Slot para recibir eventos @Slot() def click_agregar(self): # funcion de botones # obtener infornacion para las variables # .tex() ==> estrae el texto ingresado # self. ==> esta asociado a las variables globales de el programa identificador = self.ui.identificador_lineEdit.text() origenx = self.ui.origen_x_spinBox.value() origeny = self.ui.origen_y_spinBox.value() destinox = self.ui.destino_x_spinBox.value() destinoy = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_lineEdit.text() red = self.ui.red_spinBox.value() green = self.ui.green_spinBox.value() blue = self.ui.blue_spinBox.value() # .value() regresa un valor entero # elementos de la particula particula = Particula(identificador, origenx, origeny, destinox, destinoy, velocidad, red, green, blue) # asociar el apartado globalmente # mostrar los datos en el recuadro PlainText self.administrador.agregar_final(particula) # funcion Slot para recibir eventos @Slot() def click_agregar_inicio(self): # funcion de botones # obtener infornacion para las variables # .tex() ==> estrae el texto ingresado # self. ==> esta asociado a las variables globales de el programa identificador = self.ui.identificador_lineEdit.text() origenx = self.ui.origen_x_spinBox.value() origeny = self.ui.origen_y_spinBox.value() destinox = self.ui.destino_x_spinBox.value() destinoy = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_lineEdit.text() red = self.ui.red_spinBox.value() green = self.ui.green_spinBox.value() blue = self.ui.blue_spinBox.value() #.value() regresa un valor entero # elementos de la particula particula = Particula(identificador, origenx, origeny, destinox, destinoy, velocidad, red, green, blue) # asociar el apartado globalmente # mostrar los datos en el recuadro PlainText self.administrador.agregar_inicio(particula)
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): # Initialise the UI self.display = None super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Current file self._filename = None self._last_file_handler = None # Importers / Exporters self._file_handlers = [] # Update our window caption self._caption = "Zoxel" # Our global state self.settings = QtCore.QSettings("Zoxel", "Zoxel") self.state = {} # Load our state if possible self.load_state() # Create our GL Widget try: voxels = GLWidget(self.ui.glparent) self.ui.glparent.layout().addWidget(voxels) self.display = voxels except Exception as e: print "Exception in user code:" print "-" * 60 traceback.print_exc(file=sys.stdout) print "-" * 60 QtGui.QMessageBox.warning(self, "Initialisation Failed", str(e)) exit(1) # Create our Grid Manager Widget self.gridManager = DockGridManager(voxels, voxels.grids, parent=self) self.tabifyDockWidget(self.ui.dock, self.gridManager) tabs_list = self.findChildren(QtGui.QTabBar) if tabs_list: tab_bar = tabs_list[0] tab_bar.setCurrentIndex(0) # Create our palette widget voxels = PaletteWidget(self.ui.palette) self.ui.palette.layout().addWidget(voxels) self.colour_palette = voxels # More UI state value = self.get_setting("display_floor_grid") if value is not None: self.ui.action_floor_grid.setChecked(value) self.display.floor_grid = value value = self.get_setting("background_colour") if value is not None: self.display.background = QtGui.QColor.fromRgb(*value) value = self.get_setting("voxel_edges") if value is not None: self.display.voxel_edges = value self.ui.action_voxel_edges.setChecked(value) else: self.ui.action_voxel_edges.setChecked(self.display.voxel_edges) value = self.get_setting("autoresize") if value is not None: self.display.autoresize = value self.ui.action_autoresize.setChecked(value) else: self.display.autoresize = True self.ui.action_autoresize.setChecked(True) value = self.get_setting("occlusion") if value is None: value = True self.display.voxels.occlusion = value self.ui.action_occlusion.setChecked(value) # Connect some signals if self.display: self.display.voxels.notify = self.on_data_changed self.display.tool_activated.connect(self.on_tool_activated) self.display.tool_dragged.connect(self.on_tool_dragged) self.display.tool_deactivated.connect(self.on_tool_deactivated) if self.colour_palette: self.colour_palette.changed.connect(self.on_colour_changed) # Initialise our tools self._tool_group = QtGui.QActionGroup(self.ui.toolbar_drawing) self._tools = [] # Setup window self.update_caption() @QtCore.Slot() def on_action_about_triggered(self): dialog = AboutDialog(self) if dialog.exec_(): pass @QtCore.Slot() def on_action_floor_grid_triggered(self): self.display.floor_grid = self.ui.action_floor_grid.isChecked() self.set_setting("display_floor_grid", self.display.floor_grid) @QtCore.Slot() def on_action_voxel_edges_triggered(self): self.display.voxel_edges = self.ui.action_voxel_edges.isChecked() self.set_setting("voxel_edges", self.display.voxel_edges) @QtCore.Slot() def on_action_new_triggered(self): if self.display.voxels.changed: if not self.confirm_save(): return # Clear our data self._filename = "" self.display.clear() self.display.voxels.saved() self.update_caption() @QtCore.Slot() def on_action_wireframe_triggered(self): self.display.wireframe = self.ui.action_wireframe.isChecked() self.set_setting("display_wireframe", self.display.wireframe) @QtCore.Slot() def on_action_save_triggered(self): # Save self.save() @QtCore.Slot() def on_action_saveas_triggered(self): # Save self.save(True) @QtCore.Slot() def on_action_open_triggered(self): # Load self.load() @QtCore.Slot() def on_action_resize_triggered(self): # Resize model dimensions dialog = ResizeDialog(self) dialog.ui.width.setValue(self.display.voxels.width) dialog.ui.height.setValue(self.display.voxels.height) dialog.ui.depth.setValue(self.display.voxels.depth) if dialog.exec_(): new_width = dialog.ui.width.value() new_height = dialog.ui.height.value() new_depth = dialog.ui.depth.value() new_width_scale = float(new_width) / self.display.voxels.width new_height_scale = float(new_height) / self.display.voxels.height new_depth_scale = float(new_depth) / self.display.voxels.depth self.display.voxels.resize(new_width, new_height, new_depth) self.display.grids.scale_offsets(new_width_scale, new_height_scale, new_depth_scale) self.display.refresh() @QtCore.Slot() def on_action_reset_camera_triggered(self): self.display.reset_camera() @QtCore.Slot() def on_action_autoresize_triggered(self): self.display.autoresize = self.ui.action_autoresize.isChecked() self.set_setting("autoresize", self.display.autoresize) @QtCore.Slot() def on_action_occlusion_triggered(self): self.display.voxels.occlusion = self.ui.action_occlusion.isChecked() self.set_setting("occlusion", self.display.voxels.occlusion) self.display.refresh() @QtCore.Slot() def on_action_background_triggered(self): # Choose a background colour colour = QtGui.QColorDialog.getColor() if colour.isValid(): self.display.background = colour colour = (colour.red(), colour.green(), colour.blue()) self.set_setting("background_colour", colour) def on_tool_activated(self): self.activate_tool(self.display.target) def on_tool_dragged(self): self.drag_tool(self.display.target) def on_tool_deactivated(self): self.deactivate_tool(self.display.target) # Confirm if user wants to save before doing something drastic. # returns True if we should continue def confirm_save(self): responce = QtGui.QMessageBox.question( self, "Save changes?", "Save changes before discarding?", buttons=(QtGui.QMessageBox.Save | QtGui.QMessageBox.Cancel | QtGui.QMessageBox.No), ) if responce == QtGui.QMessageBox.StandardButton.Save: if not self.save(): return False elif responce == QtGui.QMessageBox.StandardButton.Cancel: return False return True # Voxel data changed signal handler def on_data_changed(self): self.update_caption() # Colour selection changed handler def on_colour_changed(self): self.display.voxel_colour = self.colour_palette.colour # Return a section of our internal config def get_setting(self, name): if name in self.state: return self.state[name] return None # Set some config. Value should be a serialisable type def set_setting(self, name, value): self.state[name] = value def closeEvent(self, event): # Save state self.save_state() if self.display.voxels.changed: if not self.confirm_save(): event.ignore() return event.accept() # Save our state def save_state(self): try: state = json.dumps(self.state) self.settings.setValue("system/state", state) except Exception as E: # XXX Fail. Never displays because we're on our way out error = QtGui.QErrorMessage(self) error.showMessage(str(E)) print str(E) # Load our state def load_state(self): try: state = self.settings.value("system/state") if state: self.state = json.loads(state) except Exception as E: error = QtGui.QErrorMessage(self) error.showMessage(str(E)) # Update the window caption to reflect the current state def update_caption(self): caption = "Zoxel" if self._filename: caption += " - [%s]" % self._filename else: caption += " - [Unsaved model]" if self.display and self.display.voxels.changed: caption += " *" if caption != self._caption: self.setWindowTitle(caption) self._caption = caption # Save the current data def save(self, newfile=False): # Find the handlers that support saving handlers = [x for x in self._file_handlers if hasattr(x, "save")] saved = False filename = self._filename handler = self._last_file_handler if handler: filetype = handler.filetype # Build list of available types choices = [] for exporter in handlers: choices.append("%s (%s)" % (exporter.description, exporter.filetype)) choices = ";;".join(choices) # Get a filename if we need one if newfile or not filename: filename, filetype = QtGui.QFileDialog.getSaveFileName( self, "Save As", "model", choices, selectedFilter="Zoxel Files (*.zox)" ) if not filename: return handler = None # Find the handler if we need to if not handler: for exporter in handlers: ourtype = "%s (%s)" % (exporter.description, exporter.filetype) if filetype == ourtype: handler = exporter # Call the save handler try: handler.save(filename) saved = True except Exception as Ex: QtGui.QMessageBox.warning(self, "Save Failed", str(Ex)) # If we saved, clear edited state if saved: self._filename = filename self._last_file_handler = handler self.display.voxels.saved() self.update_caption() return saved # Registers an file handler (importer/exporter) with the system def register_file_handler(self, handler): self._file_handlers.append(handler) # load a file def load(self): # If we have changes, perhaps we should save? if self.display.voxels.changed: if not self.confirm_save(): return # Find the handlers that support loading handler = None handlers = [x for x in self._file_handlers if hasattr(x, "load")] # Build list of types we can load choices = [] for importer in handlers: choices.append("%s (%s)" % (importer.description, importer.filetype)) choices = ";;".join(choices) # Get a filename filename, filetype = QtGui.QFileDialog.getOpenFileName( self, caption="Open file", filter=choices, selectedFilter="Zoxel Files (*.zox)" ) if not filename: return # Find the handler for importer in handlers: ourtype = "%s (%s)" % (importer.description, importer.filetype) if filetype == ourtype: handler = importer self._last_file_handler = handler # Force auto-resizing autoresize = self.display.autoresize if not autoresize: self.display.autoresize = True # Load the file self.display.clear() self._filename = None try: handler.load(filename) self._filename = filename except Exception as Ex: QtGui.QMessageBox.warning(self, "Could not load file", str(Ex)) # Put auto resize setting back to how it was self.display.autoresize = autoresize self.display.voxels.resize() self.display.voxels.saved() self.display.reset_camera() self.update_caption() self.display.refresh() # Registers a tool in the drawing toolbar def register_tool(self, tool): self._tools.append(tool) self._tool_group.addAction(tool.get_action()) self.ui.toolbar_drawing.addAction(tool.get_action()) # Send an activation event to the currently selected drawing tool def activate_tool(self, target): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_activate(target) return # Send drag activation to the current selected drawing tool def drag_tool(self, target): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_drag(target) return # Send an deactivation event to the currently selected drawing tool def deactivate_tool(self, target): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_deactivate(target) return # Load and initialise all plugins def load_plugins(self): import plugin_loader
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): # Initialise the UI self.display = None super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Current file self._filename = None self._last_file_handler = None # Importers / Exporters self._file_handlers = [] # Update our window caption self._caption = "Zoxel" # Our global state self.settings = QtCore.QSettings("Zoxel", "Zoxel") self.state = {} # Our animation timer self._timer = QtCore.QTimer(self) self.connect(self._timer, QtCore.SIGNAL("timeout()"), self.on_animation_tick) self._anim_speed = 200 # Load our state if possible self.load_state() # Create our GL Widget try: voxels = GLWidget(self.ui.glparent) self.ui.glparent.layout().addWidget(voxels) self.display = voxels except Exception as E: QtGui.QMessageBox.warning(self, "Initialisation Failed", str(E)) exit(1) # Load default model dimensions width = self.get_setting("default_model_width") height = self.get_setting("default_model_height") depth = self.get_setting("default_model_depth") if width: self.resize_voxels(width, height, depth) # Resize is detected as a change, discard changes self.display.voxels.saved() # Create our palette widget voxels = PaletteWidget(self.ui.palette) self.ui.palette.layout().addWidget(voxels) self.colour_palette = voxels # More UI state value = self.get_setting("display_axis_grids") if value is not None: self.ui.action_axis_grids.setChecked(value) self.display.axis_grids = value value = self.get_setting("background_colour") if value is not None: self.display.background = QtGui.QColor.fromRgb(*value) value = self.get_setting("voxel_edges") if value is not None: self.display.voxel_edges = value self.ui.action_voxel_edges.setChecked(value) else: self.ui.action_voxel_edges.setChecked(self.display.voxel_edges) value = self.get_setting("occlusion") if value is None: value = True self.display.voxels.occlusion = value self.ui.action_occlusion.setChecked(value) # Connect some signals if self.display: self.display.voxels.notify = self.on_data_changed self.display.tool_activated.connect(self.on_tool_activated) self.display.tool_activated_alt.connect(self.on_tool_activated_alt) self.display.tool_dragged.connect(self.on_tool_dragged) self.display.tool_deactivated.connect(self.on_tool_deactivated) if self.colour_palette: self.colour_palette.changed.connect(self.on_colour_changed) # Initialise our tools self._tool_group = QtGui.QActionGroup(self.ui.toolbar_drawing) self._tools = [] # Setup window self.update_caption() self.refresh_actions() def on_animation_tick(self): self.on_action_anim_next_triggered() @QtCore.Slot() def on_action_about_triggered(self): dialog = AboutDialog(self) if dialog.exec_(): pass @QtCore.Slot() def on_action_axis_grids_triggered(self): self.display.axis_grids = self.ui.action_axis_grids.isChecked() self.set_setting("display_axis_grids", self.display.axis_grids) @QtCore.Slot() def on_action_voxel_edges_triggered(self): self.display.voxel_edges = self.ui.action_voxel_edges.isChecked() self.set_setting("voxel_edges", self.display.voxel_edges) @QtCore.Slot() def on_action_zoom_in_triggered(self): self.display.zoom_in() @QtCore.Slot() def on_action_zoom_out_triggered(self): self.display.zoom_out() @QtCore.Slot() def on_action_new_triggered(self): if self.display.voxels.changed: if not self.confirm_save(): return # Clear our data self._filename = "" self.display.clear() self.display.voxels.saved() self.update_caption() self.refresh_actions() @QtCore.Slot() def on_action_wireframe_triggered(self): self.display.wireframe = self.ui.action_wireframe.isChecked() self.set_setting("display_wireframe", self.display.wireframe) @QtCore.Slot() def on_action_save_triggered(self): # Save self.save() @QtCore.Slot() def on_action_saveas_triggered(self): # Save self.save(True) @QtCore.Slot() def on_action_open_triggered(self): # Load self.load() @QtCore.Slot() def on_action_undo_triggered(self): # Undo self.display.voxels.undo() self.display.refresh() @QtCore.Slot() def on_action_redo_triggered(self): # Redo self.display.voxels.redo() self.display.refresh() @QtCore.Slot() def on_action_resize_triggered(self): # Resize model dimensions dialog = ResizeDialog(self) dialog.ui.width.setValue(self.display.voxels.width) dialog.ui.height.setValue(self.display.voxels.height) dialog.ui.depth.setValue(self.display.voxels.depth) if dialog.exec_(): width = dialog.ui.width.value() height = dialog.ui.height.value() depth = dialog.ui.depth.value() self.resize_voxels(width, height, depth) def resize_voxels(self, width, height, depth): new_width_scale = float(width) / self.display.voxels.width new_height_scale = float(height) / self.display.voxels.height new_depth_scale = float(depth) / self.display.voxels.depth self.display.voxels.resize(width, height, depth) self.display.grids.scale_offsets(new_width_scale, new_height_scale, new_depth_scale) self.display.refresh() # Remember these dimensions self.set_setting("default_model_width", width) self.set_setting("default_model_height", height) self.set_setting("default_model_depth", depth) @QtCore.Slot() def on_action_reset_camera_triggered(self): self.display.reset_camera() @QtCore.Slot() def on_action_occlusion_triggered(self): self.display.voxels.occlusion = self.ui.action_occlusion.isChecked() self.set_setting("occlusion", self.display.voxels.occlusion) self.display.refresh() @QtCore.Slot() def on_action_background_triggered(self): # Choose a background colour colour = QtGui.QColorDialog.getColor() if colour.isValid(): self.display.background = colour colour = (colour.red(), colour.green(), colour.blue()) self.set_setting("background_colour", colour) @QtCore.Slot() def on_action_anim_add_triggered(self): self.display.voxels.add_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_delete_triggered(self): self.display.voxels.delete_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_play_triggered(self): self._timer.start(self._anim_speed) self.refresh_actions() @QtCore.Slot() def on_action_anim_stop_triggered(self): self._timer.stop() self.refresh_actions() @QtCore.Slot() def on_action_anim_next_triggered(self): self.display.voxels.select_next_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_previous_triggered(self): self.display.voxels.select_previous_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_settings_triggered(self): pass @QtCore.Slot() def on_action_rotate_x_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.X_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_y_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Y_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_z_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Z_AXIS) self.display.refresh() @QtCore.Slot() def on_action_voxel_colour_triggered(self): # Choose a voxel colour colour = QtGui.QColorDialog.getColor() if colour.isValid(): self.colour_palette.colour = colour @QtCore.Slot() def on_action_export_image_triggered(self): png = QtGui.QPixmap.grabWidget(self.display) choices = "PNG Image (*.png);;JPEG Image (*.jpg)" # Grab our default location directory = self.get_setting("default_directory") # grab a filename filename, filetype = QtGui.QFileDialog.getSaveFileName( self, caption="Export Image As", filter=choices, dir=directory) if not filename: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Save the PNG png.save(filename, filetype.split()[0]) def on_tool_activated(self): self.activate_tool(self.display.target, self.display.mouse_position) def on_tool_activated_alt(self): self.activate_tool_alt(self.display.target, self.display.mouse_position) def on_tool_dragged(self): self.drag_tool(self.display.target, self.display.mouse_position) def on_tool_deactivated(self): self.deactivate_tool(self.display.target) # Confirm if user wants to save before doing something drastic. # returns True if we should continue def confirm_save(self): responce = QtGui.QMessageBox.question( self, "Save changes?", "Save changes before discarding?", buttons=(QtGui.QMessageBox.Save | QtGui.QMessageBox.Cancel | QtGui.QMessageBox.No)) if responce == QtGui.QMessageBox.StandardButton.Save: if not self.save(): return False elif responce == QtGui.QMessageBox.StandardButton.Cancel: return False return True # Voxel data changed signal handler def on_data_changed(self): self.update_caption() self.refresh_actions() # Colour selection changed handler def on_colour_changed(self): self.display.voxel_colour = self.colour_palette.colour # Return a section of our internal config def get_setting(self, name): if name in self.state: return self.state[name] return None # Set some config. Value should be a serialisable type def set_setting(self, name, value): self.state[name] = value def closeEvent(self, event): # Save state self.save_state() if self.display.voxels.changed: if not self.confirm_save(): event.ignore() return event.accept() # Save our state def save_state(self): try: state = json.dumps(self.state) self.settings.setValue("system/state", state) except Exception as E: # XXX Fail. Never displays because we're on our way out error = QtGui.QErrorMessage(self) error.showMessage(str(E)) print str(E) # Load our state def load_state(self): try: state = self.settings.value("system/state") if state: self.state = json.loads(state) except Exception as E: error = QtGui.QErrorMessage(self) error.showMessage(str(E)) # Update the window caption to reflect the current state def update_caption(self): caption = "Zoxel" if self._filename: caption += " - [%s]" % self._filename else: caption += " - [Unsaved model]" if self.display and self.display.voxels.changed: caption += " *" numframes = self.display.voxels.get_frame_count() frame = self.display.voxels.get_frame_number() + 1 if numframes > 1: caption += " - Frame {0} of {1}".format(frame, numframes) if caption != self._caption: self.setWindowTitle(caption) self._caption = caption # Save the current data def save(self, newfile=False): # Find the handlers that support saving handlers = [x for x in self._file_handlers if hasattr(x, 'save')] saved = False filename = self._filename handler = self._last_file_handler if handler: filetype = handler.filetype # Build list of available types choices = [] for exporter in handlers: choices.append("%s (%s)" % (exporter.description, exporter.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename if we need one if newfile or not filename: filename, filetype = QtGui.QFileDialog.getSaveFileName( self, caption="Save As", filter=choices, dir=directory, selectedFilter="Zoxel Files (*.zox)") if not filename: return handler = None # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler if we need to if not handler: for exporter in handlers: ourtype = "%s (%s)" % (exporter.description, exporter.filetype) if filetype == ourtype: handler = exporter # Call the save handler try: handler.save(filename) saved = True except Exception as Ex: QtGui.QMessageBox.warning(self, "Save Failed", str(Ex)) # If we saved, clear edited state if saved: self._filename = filename self._last_file_handler = handler self.display.voxels.saved() self.update_caption() self.refresh_actions() return saved # Registers an file handler (importer/exporter) with the system def register_file_handler(self, handler): self._file_handlers.append(handler) # load a file def load(self): # If we have changes, perhaps we should save? if self.display.voxels.changed: if not self.confirm_save(): return # Find the handlers that support loading handler = None handlers = [x for x in self._file_handlers if hasattr(x, 'load')] # Build list of types we can load choices = [] for importer in handlers: choices.append("%s (%s)" % (importer.description, importer.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename filename, filetype = QtGui.QFileDialog.getOpenFileName( self, caption="Open file", filter=choices, dir=directory, selectedFilter="Zoxel Files (*.zox)") if not filename: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler for importer in handlers: ourtype = "%s (%s)" % (importer.description, importer.filetype) if filetype == ourtype: handler = importer self._last_file_handler = handler # Load the file self.display.clear() self.display.voxels.disable_undo() self._filename = None try: handler.load(filename) self._filename = filename except Exception as Ex: self.display.voxels.enable_undo() QtGui.QMessageBox.warning(self, "Could not load file", str(Ex)) self.display.build_grids() #self.display.voxels.resize() self.display.voxels.saved() self.display.reset_camera() self.update_caption() self.refresh_actions() self.display.voxels.enable_undo() self.display.refresh() # Registers a tool in the drawing toolbar def register_tool(self, tool, activate=False): self._tools.append(tool) self._tool_group.addAction(tool.get_action()) self.ui.toolbar_drawing.addAction(tool.get_action()) if activate: tool.get_action().setChecked(True) # Send an activation event to the currently selected drawing tool def activate_tool(self, target, mouse_position): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_activate(target, mouse_position) return # Send an alternative activation event to the currently selected tool def activate_tool_alt(self, target, mouse_position): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_activate_alt(target, mouse_position) return # Send drag activation to the current selected drawing tool def drag_tool(self, target, mouse_position): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_drag(target, mouse_position) return # Send an deactivation event to the currently selected drawing tool def deactivate_tool(self, target): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_deactivate(target) return # Load and initialise all plugins def load_plugins(self): import plugin_loader # Update the state of the UI actions def refresh_actions(self): num_frames = self.display.voxels.get_frame_count() self.ui.action_anim_delete.setEnabled(num_frames > 1) self.ui.action_anim_previous.setEnabled(num_frames > 1) self.ui.action_anim_next.setEnabled(num_frames > 1) self.ui.action_anim_play.setEnabled(num_frames > 1 and not self._timer.isActive()) self.ui.action_anim_stop.setEnabled(self._timer.isActive()) self.update_caption()
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.paqueteria = Paqueteria() self.ui.pushButton.clicked.connect(self.click) self.ui.pushButton_2.clicked.connect(self.mostrar) self.ui.actionGuardar.triggered.connect(self.guardar) self.ui.actionAbrir.triggered.connect(self.abrir) self.scene = QGraphicsScene() ##COMENTERA ABAJAO self.scene.setSceneRect(0, 0, 500, 500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(30) self.scene.addLine(0, 0, 499, 0, self.pen) self.scene.addLine(0, 499, 499, 499, self.pen) self.scene.addLine(0, 0, 0, 499, self.pen) self.scene.addLine(499, 0, 499, 499, self.pen) self.pen.setColor(QColor(100, 20, 200)) self.scene.addLine(10, 10, 490, 490, self.pen) self.scene.addEllipse(10, 10, 5, 5, self.pen, QBrush(QColor(50, 100, 0))) self.scene.addEllipse(490, 490, 5, 5, self.pen, QBrush(QColor(50, 100, 0))) self.ui.pushButton_3.clicked.connect(self.ordenar_origen) self.ui.pushButton_4.clicked.connect(self.ordenar_distancia) @Slot() def ordenar_origen(self): self.paqueteria.oredenar_origen() @Slot() def ordenar_distancia(self): self.paqueteria.ordenar_distancia() @Slot() def abrir(self): file = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.', 'JSON(*.json)') self.paqueteria.recuperar(file[0]) @Slot() def mostrar(self): #self.paqueteria.mostrar() for paquete in self.paqueteria.lista: self.ui.plainTextEdit.insertPlainText(str(paquete)) @Slot() def guardar(self): file = QFileDialog.getSaveFileName(self, 'Guardar Archivo...', '.', 'JSON (*.json)') print(file) self.paqueteria.guardar(file[0]) @Slot() def click(self): id = self.ui.lineEdit.text() origen = self.ui.lineEdit_2.text() destino = self.ui.lineEdit_3.text() distancia = self.ui.lineEdit_4.text() peso = self.ui.lineEdit_5.text() print(id, origen, destino, distancia, peso) paquete = Paquete() paquete.id = id paquete.origen = origen paquete.destino = destino paquete.distancia = distancia paquete.peso = peso self.paqueteria.agregar(paquete) msg = QMessageBox.information( self, 'Exito', 'Se agrego paquete con exito' ) #Ventana de mensaje de la libreria QMessageBox self.ui.lineEdit.clear() #Limpiar campos self.ui.lineEdit_2.clear() self.ui.lineEdit_3.clear() self.ui.lineEdit_4.clear() self.ui.lineEdit_5.clear()
class MainWindow(QMainWindow): def __init__(self): super().__init__(flags=Qt.WindowContextHelpButtonHint | Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setUpMainWindow() def setUpMainWindow(self): self.setWindowTitle( "Lab Tools 1.0 (2021 Edition) - Applications of ML in Mechatronics" ) # set icon self.setUpIcon() #set up the info and start processing button self.inputLineEdit = QLineEdit() self.outputFolderLineEdit = QLineEdit() self.modelLineEdit = QLineEdit() self.browseOutputButton = QPushButton() self.browseInputButton = QPushButton() self.browseModelButton = QPushButton() self.startStopButton = QPushButton() self.useDefaultModelCheckbox = QCheckBox() self.inputLineEdit = self.findChild(QLineEdit, "inputLineEdit") self.modelLineEdit = self.findChild(QLineEdit, "modelLineEdit") self.outputFolderLineEdit = self.findChild(QLineEdit, "outputFolderLineEdit") self.browseOutputButton = self.findChild(QPushButton, "browseOutputButton") self.browseInputButton = self.findChild(QPushButton, "browseInputButton") self.browseModelButton = self.findChild(QPushButton, "browseModelButton") self.startStopButton = self.findChild(QPushButton, "startStopButton") self.useDefaultModelCheckbox = self.findChild( QCheckBox, "useDefaultModelCheckbox") self.chooseModelLabel = self.findChild(QLabel, "chooseModelLabel") #disabling model transfer capability if needed self._modelRPiPath = False if DISABLE_MODEL_TRASFER: self.useDefaultModelCheckbox.hide() self.modelLineEdit.setEnabled(1) self.browseModelButton.hide() self.chooseModelLabel.setText(self.chooseModelLabel.text() + " Name") # self.gridLayout = self.findChild(QGridLayout, "gridLayout") # self.gridLayout.removeWidget(self.browseModelButton) # self.gridLayout.removeWidget(self.useDefaultModelCheckbox) self._modelRPiPath = True self.startStopButton.clicked.connect(self.handleStartStopButtonClicked) self.browseOutputButton.clicked.connect(self.handleBrowseOutputButton) self.browseInputButton.clicked.connect(self.handleBrowseInputButton) self.browseModelButton.clicked.connect(self.handleBrowseModelButton) self.useDefaultModelCheckbox.stateChanged.connect( self.handleUseDefaultModelCheckboxStateChanged) self.useDefaultModelCheckbox.setChecked(True) #set up the log and progress bar self.logTextBrowser = QTextBrowser() self.lastLogTextLabel = QLabel() self.logTextBrowser = self.findChild(QTextBrowser, "logTextBrowser") self.progressBar = self.findChild(QProgressBar, "progressBar") self.clearLogButton = self.findChild(QPushButton, "clearLogButton") self.saveLogButton = self.findChild(QPushButton, "saveLogButton") self.lastLogTextLabel = self.findChild(QLabel, "lastLogTextLabel") self.clearLogButton.clicked.connect(self.handleClearLogButton) self.saveLogButton.clicked.connect(self.handleSaveLogButton) #set up menu bar self.actionHelp = self.findChild(QAction, "actionHelp") self.actionAbout = self.findChild(QAction, "actionAbout") self.actionHelp.triggered.connect(self.handleActionHelpClicked) self.actionAbout.triggered.connect(self.handleActionAboutClicked) # Add additional menu actions self.utilitiesMenu = self.menuBar().addMenu("Utilities") self.actionGetRPiIP = QAction("Get RPi IP") self.utilitiesMenu.addAction(self.actionGetRPiIP) self.actionGetRPiIP.triggered.connect(self.handleActionGetRPiIPClicked) self.actionUpdateRPiScript = QAction("Updare RPi Script") self.utilitiesMenu.addAction(self.actionUpdateRPiScript) self.actionUpdateRPiScript.triggered.connect( self.handleActionUpdateRPiScript) #create objects from the other classes self.logger = Logger(self.logTextBrowser, self.lastLogTextLabel) #initialize member variables self._b_processRunning = False # set up lab names self.setUpLabNames() #set up serial comms self.setupSerial() self.refreshSerialPorts() self.logger.log("The application is ready!", type="INFO") def setUpIcon(self): self.appIcon = QIcon("images/favicon.png") self.setWindowIcon(self.appIcon) def setUpLabNames(self): self.labNameComboBox = QComboBox() self.labNameComboBox = self.findChild(QComboBox, "labNameComboBox") self.labNameComboBox.currentIndexChanged.connect( self.handleLabNameComboboxCurrentIndexChanged) for code, name in utils.lab_names.items(): self.labNameComboBox.addItem(code + ": " + name) self.labNameComboBox.setCurrentIndex(1) def setupSerial(self): self.refreshSerialPortsButton = QPushButton() self.connectDisconnectSerialButton = QPushButton() self.serialPortComboBox = QComboBox() self.refreshSerialPortsButton = self.findChild( QPushButton, "refreshSerialPortsButton") self.connectDisconnectSerialButton = self.findChild( QPushButton, "connectDisconnectSerialButton") self.serialPortComboBox = self.findChild(QComboBox, "serialPortComboBox") self.refreshSerialPortsButton.clicked.connect(self.refreshSerialPorts) self.connectDisconnectSerialButton.clicked.connect( self.handleSerialConnectDisconnect) self._b_serialConnected = False def refreshSerialPorts(self): availablePorts = utils.find_serial_ports() self.serialPortComboBox.clear() for portName in availablePorts: self.serialPortComboBox.addItem(portName) def handleSerialConnectDisconnect(self): if not self.b_serialConnected: try: currentPortName = self.serialPortComboBox.currentText() self.port = serial.Serial(currentPortName, 115200, timeout=1, write_timeout=240, bytesize=8, parity='N', stopbits=1) self.port.set_buffer_size(rx_size=10**3, tx_size=10**8) self.serialPortComboBox.setItemText( self.serialPortComboBox.currentIndex(), currentPortName + " (CONNECTED)") self.connectDisconnectSerialButton.setText("Disconnect") self.b_serialConnected = True self.refreshSerialPortsButton.setDisabled(1) except (OSError, serial.SerialException): print("Problem with Serial Connection!") self.logger.log( "Problem with Serial Connection, Make sure you chose the right port", type="ERROR") else: try: self.port.close() self.refreshSerialPorts() self.connectDisconnectSerialButton.setText("Connect") self.b_serialConnected = False self.refreshSerialPortsButton.setEnabled(1) except (OSError, serial.SerialException): print("Problem with Serial Connection!") self.logger.log("Problem with Serial Connection", type="ERROR") def _startButtonClicked(self): self.logger.log("Attempting to start the processing", type="INFO") if not self.b_serialConnected: self.logger.log( "Serial is not connected, Please connect serial first", type="ERROR") return if self.inputLineEdit.text()[-4:].lower() != ".csv": self.logger.log("Please select a valid input csv file", type="ERROR") return if self.outputFolderLineEdit.text() == "": self.logger.log("Please select an output directory", type="ERROR") return self.executer = Executer(serialObj=self.port, loggerObj=self.logger) if self.modelLineEdit.text() != "": modelPath = self.modelLineEdit.text() else: modelPath = None if self._modelRPiPath: self.logger.log( "Please select a valid model that is already available in the folder saved_models on the RPi", type="ERROR") return #Read the Input File try: inputDataFrame = pd.read_csv(self.inputLineEdit.text()) except: self.logger.log("CSV File Reading Failed, select a valid csv file", type="ERROR") possibleInputs = list(inputDataFrame.columns) #Display a dialog to ask the user to choose what inputs they want dialog = QDialog(self) dialog.setWindowTitle("Select the Input Fields") dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0) dialogButtons.accepted.connect(dialog.accept) dialogButtons.rejected.connect(dialog.reject) mainLayout = QVBoxLayout(dialog) scroll = QScrollArea(dialog) scroll.setWidgetResizable(True) layoutWidget = QWidget() layout = QVBoxLayout(layoutWidget) scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setWidget(layoutWidget) chosenInputs = [] checkboxes = [] def handleCheckboxClicked(): dialogButtons.button(QDialogButtonBox.Ok).setDisabled(1) for checkbox in checkboxes: if checkbox.isChecked(): dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0) for input in possibleInputs: checkbox = QCheckBox(text=input) checkbox.clicked.connect(handleCheckboxClicked) checkbox.setChecked(True) checkboxes.append(checkbox) layout.addWidget(checkbox) mainLayout.addWidget( QLabel(text="Please select the input fields from the following:")) mainLayout.addWidget(scroll) mainLayout.addWidget(dialogButtons) dialog.setLayout(mainLayout) # dialog.setFixedHeight(400) if dialog.exec_() == QDialog.Accepted: for checkbox in checkboxes: if checkbox.isChecked(): chosenInputs.append(checkbox.text()) self.logger.log("The chosen input fields are: " + ', '.join(chosenInputs), type="INFO") else: return self.startStopButton.setText("Stop Processing") self.b_processRunning = True executionResult = self.executer.execute(self.labNameComboBox.currentText().split(":")[0], inputDataFrame, \ self.outputFolderLineEdit.text(), inputFields=chosenInputs, progressBar=self.progressBar, \ model=modelPath if not self._modelRPiPath else "RPI:"+modelPath) if executionResult == ExecutionResult.COMPLETED: self._stopButtonClicked(finishedProcessing=True) elif executionResult == ExecutionResult.INTERRUPTED or executionResult == ExecutionResult.FAILED: self._stopButtonClicked() if self.executer.reset() == ExecutionResult.FAILED: self.logger.log( "Resetting the serial state of RPi Failed, please power cycle the RPi", type="ERROR") else: self.logger.log("The serial state of RPi has been reset", type="INFO") def _stopButtonClicked(self, finishedProcessing=False): self.startStopButton.setText("Start Processing") if finishedProcessing: self.logger.log("", special="ProcessingCompleted") else: self.logger.log("", special="ProcessingStopped") self.b_processRunning = False #TODO: Complete Implementing this def handleStartStopButtonClicked(self): if (self.b_processRunning): self.executer.requestStop() else: self._startButtonClicked() def handleActionHelpClicked(self): helpBox = QMessageBox() helpBox.setIcon(QMessageBox.Information) helpBox.setStandardButtons(QMessageBox.Ok) helpBox.setWindowTitle("Need Help?") helpBox.setText( "For Help, please reach out to your Instructor or TA or read the lab manual" ) helpBox.setTextFormat(Qt.RichText) helpBox.setInformativeText( f"You can access the project <a href=\"{utils.docs_link}\">Manual</a> and source in the <a href=\"{utils.repo_link}\">Github Repo!</a>" ) helpBox.setWindowIcon(self.appIcon) helpBox.exec_() def handleActionAboutClicked(self): aboutBox = QMessageBox() aboutBox.setIcon(QMessageBox.Information) aboutBox.setStandardButtons(QMessageBox.Ok) aboutBox.setWindowTitle("About the Software") aboutBox.setText(utils.license_text) aboutBox.setWindowIcon(self.appIcon) aboutBox.exec_() def handleBrowseInputButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFile) dialog.setNameFilter("*.csv") if dialog.exec_(): filePath = dialog.selectedFiles() if len(filePath) == 1: self.inputLineEdit.setText(filePath[0]) def handleBrowseModelButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFile) dialog.setNameFilter(utils.lab_model_extensions[ self.labNameComboBox.currentText().split(":")[0]]) if dialog.exec_(): filePath = dialog.selectedFiles() if len(filePath) == 1: self.modelLineEdit.setText(filePath[0]) def handleBrowseOutputButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.DirectoryOnly) dialog.setOption(QFileDialog.ShowDirsOnly) if dialog.exec_(): folderPath = dialog.selectedFiles() if len(folderPath) == 1: self.outputFolderLineEdit.setText(folderPath[0]) def handleSaveLogButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.AnyFile) dialog.AcceptMode(QFileDialog.AcceptSave) dialog.setNameFilter("*.txt") if dialog.exec_(): filePath = dialog.selectedFiles() if len(filePath) == 1: if self.logger.saveLog(filePath[0]) != -1: self.logger.log( "The log has been saved, feel free to clear the log now", type="SUCCESS") return self.logger.log("Failed to save the log, please select a valid file", type="ERROR") def handleClearLogButton(self): self.logger.clearLog() def handleUseDefaultModelCheckboxStateChanged(self): if self._modelRPiPath: return if not self.useDefaultModelCheckbox.checkState(): self.modelLineEdit.setDisabled(0) self.browseModelButton.setDisabled(0) else: self.modelLineEdit.clear() self.modelLineEdit.setDisabled(1) self.browseModelButton.setDisabled(1) def handleLabNameComboboxCurrentIndexChanged(self): if self._modelRPiPath: self.modelLineEdit.setText(utils.lab_default_models[ self.labNameComboBox.currentText().split(":")[0]]) # Disable the model options when the lab selected is Communication Test if self.labNameComboBox.currentIndex() == 0: self.modelLineEdit.setDisabled(1) self.browseModelButton.setDisabled(1) self.modelLineEdit.setText("Model is not required") else: self.modelLineEdit.setDisabled(0) self.browseModelButton.setDisabled(0) def handleActionGetRPiIPClicked(self): self.logger.log("Attempting to Get Raspberry Pi IP Address", type="INFO") if not self.b_serialConnected: replyMessage = "Serial is not connected, Please connect serial first" else: self.executer = Executer(serialObj=self.port, loggerObj=self.logger) ipaddr = self.executer.executeOther("GET_IP") replyMessage = ( "Raspberry Pi IP is " + ipaddr ) if ipaddr != ExecutionResult.FAILED else "Failed to obtain the IP Address" self.logger.log(replyMessage) ipAddrMessage = QMessageBox() ipAddrMessage.setIcon(QMessageBox.Information) ipAddrMessage.setStandardButtons(QMessageBox.Ok) ipAddrMessage.setWindowTitle("Raspberry Pi IP Address") ipAddrMessage.setText(replyMessage) ipAddrMessage.setTextFormat(Qt.RichText) ipAddrMessage.setWindowIcon(self.appIcon) ipAddrMessage.exec_() def handleActionUpdateRPiScript(self): self.logger.log( 'Attempting to "git pull" for the Raspberry Pi Python Script', type="INFO") if not self.b_serialConnected: replyMessage = "Serial is not connected, Please connect serial first" else: self.executer = Executer(serialObj=self.port, loggerObj=self.logger) result = self.executer.executeOther("UPDATE_SCRIPT") if result != ExecutionResult.FAILED and "FAIL" not in result: replyMessage = "Raspberry Pi Script has been updated. You still need to reboot or power cycle the Raspberry Pi for the updated script to run" \ "\nReceived: " + result else: replyMessage = "Failed to update the RPi Script" if "FAIL" in result: replyMessage = replyMessage + "\nReceived: " + result self.logger.log(replyMessage) ipAddrMessage = QMessageBox() ipAddrMessage.setIcon(QMessageBox.Information) ipAddrMessage.setStandardButtons(QMessageBox.Ok) ipAddrMessage.setWindowTitle("Raspberry Pi Script Updating Status") ipAddrMessage.setText(replyMessage) ipAddrMessage.setTextFormat(Qt.RichText) ipAddrMessage.setWindowIcon(self.appIcon) ipAddrMessage.exec_() @property def b_processRunning(self): return self._b_processRunning @property def b_serialConnected(self): return self._b_serialConnected @b_serialConnected.setter def b_serialConnected(self, newValue): self._b_serialConnected = newValue if newValue is True: self.logger.log("", special="SerialConnected") else: self.logger.log("", special="SerialDisconnected") @b_processRunning.setter def b_processRunning(self, newValue): self._b_processRunning = newValue if newValue is True: self.logger.log("", special="ProcessingStarted") def __del__(self): if self.b_serialConnected: self.port.close()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.AlmacenP = AlmacenDeParticulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.AgregarFinal.clicked.connect(self.click_agregar) self.ui.AgregarInicio.clicked.connect(self.click_agregarInicio) self.ui.Mostrar.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.Mostrar_Tabla_Boton.clicked.connect(self.mostrar_tabla) self.ui.Buscar_Boton.clicked.connect(self.buscar_id) self.ui.Dibujar.clicked.connect(self.dibujar) self.ui.Limpiar.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) self.ui.OrdId.clicked.connect(self.ordId) self.ui.OrdDistancia.clicked.connect(self.ordDistancia) self.ui.OrdVelocidad.clicked.connect(self.ordVelocidad) # def sort_by_Distancia(self.__lista): # return self.__particulas.Distancia @Slot() def ordId(self): self.AlmacenP.ordenar() @Slot() def ordDistancia(self): self.AlmacenP.ordenarD() @Slot() def ordVelocidad(self): self.AlmacenP.ordenarV() @Slot() def dibujar(self): pen = QPen() pen.setWidth(3) for Particulas in self.AlmacenP: r = float(Particulas.Red) g = float(Particulas.Green) b = float(Particulas.Blue) # origen_x = randint(0, 500) # origen_y = randint(0, 500) # destino_x = randint(0, 500) # destino_y = randint(0, 500) color = QColor(r, g, b) pen.setColor(color) self.scene.addEllipse(float(Particulas.OrigenX), float(Particulas.OrigenY), 3, 3, pen) self.scene.addEllipse(float(Particulas.DestinoX), float(Particulas.DestinoY), 3, 3, pen) self.scene.addLine( float(Particulas.OrigenX) + 3, float(Particulas.OrigenY) + 3, float(Particulas.DestinoX), float(Particulas.DestinoY), pen) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def limpiar(self): self.scene.clear() @Slot() def buscar_id(self): Id = self.ui.Buscar.text() encontrado = False for Particulas in self.AlmacenP: if Id == str(Particulas.Id): self.ui.tableWidget.clear() self.ui.tableWidget.setRowCount(1) Id_widget = QTableWidgetItem(str(Particulas.Id)) OrigenX_widget = QTableWidgetItem(str(Particulas.OrigenX)) OrigenY_widget = QTableWidgetItem(str(Particulas.OrigenY)) DestinoX_widget = QTableWidgetItem(str(Particulas.DestinoX)) DestinoY_widget = QTableWidgetItem(str(Particulas.DestinoY)) Velocidad_widget = QTableWidgetItem(str(Particulas.Velocidad)) Red_widget = QTableWidgetItem(str(Particulas.Red)) Green_widget = QTableWidgetItem(str(Particulas.Green)) Blue_widget = QTableWidgetItem(str(Particulas.Blue)) Distancia_widget = QTableWidgetItem(str(Particulas.Distancia)) self.ui.tableWidget.setItem(0, 0, Id_widget) self.ui.tableWidget.setItem(0, 1, OrigenX_widget) self.ui.tableWidget.setItem(0, 2, OrigenY_widget) self.ui.tableWidget.setItem(0, 3, DestinoX_widget) self.ui.tableWidget.setItem(0, 4, DestinoY_widget) self.ui.tableWidget.setItem(0, 5, Velocidad_widget) self.ui.tableWidget.setItem(0, 6, Red_widget) self.ui.tableWidget.setItem(0, 7, Green_widget) self.ui.tableWidget.setItem(0, 8, Blue_widget) self.ui.tableWidget.setItem(0, 9, Distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, 'Atencion', f'La particula con el Id "{Id}" no fue encontrado') @Slot() def mostrar_tabla(self): #print('mostrar_tabla') self.ui.tableWidget.setColumnCount(10) headers = [ "Id", "OrigenX", "OrigenY", "DestinoX", "DestinoY", "Velocidad", "Red", "Green", "Blue", "Distancia" ] self.ui.tableWidget.setHorizontalHeaderLabels(headers) self.ui.tableWidget.setRowCount(len(self.AlmacenP)) row = 0 for Particulas in self.AlmacenP: Id_widget = QTableWidgetItem(str(Particulas.Id)) OrigenX_widget = QTableWidgetItem(str(Particulas.OrigenX)) OrigenY_widget = QTableWidgetItem(str(Particulas.OrigenY)) DestinoX_widget = QTableWidgetItem(str(Particulas.DestinoX)) DestinoY_widget = QTableWidgetItem(str(Particulas.DestinoY)) Velocidad_widget = QTableWidgetItem(str(Particulas.Velocidad)) Red_widget = QTableWidgetItem(str(Particulas.Red)) Green_widget = QTableWidgetItem(str(Particulas.Green)) Blue_widget = QTableWidgetItem(str(Particulas.Blue)) Distancia_widget = QTableWidgetItem(str(Particulas.Distancia)) self.ui.tableWidget.setItem(row, 0, Id_widget) self.ui.tableWidget.setItem(row, 1, OrigenX_widget) self.ui.tableWidget.setItem(row, 2, OrigenY_widget) self.ui.tableWidget.setItem(row, 3, DestinoX_widget) self.ui.tableWidget.setItem(row, 4, DestinoY_widget) self.ui.tableWidget.setItem(row, 5, Velocidad_widget) self.ui.tableWidget.setItem(row, 6, Red_widget) self.ui.tableWidget.setItem(row, 7, Green_widget) self.ui.tableWidget.setItem(row, 8, Blue_widget) self.ui.tableWidget.setItem(row, 9, Distancia_widget) row += 1 @Slot() def action_abrir_archivo(self): #print('abrir_archivo') ubication = QFileDialog.getOpenFileName(self, 'Abrir Archivo', '.', 'JSON (*.json)')[0] if self.AlmacenP.abrir(ubication): QMessageBox.information(self, "Exito", "Se abrio el archivo " + ubication) else: QMessageBox.critical(self, "Error", "Eror al abrir el archivo" + ubication) @Slot() def action_guardar_archivo(self): #print('Guardar_archivo') ubication = QFileDialog.getSaveFileName(self, 'Guardar Archivo', '.', 'JSON (*.json)')[0] print(ubication) if self.AlmacenP.guardar(ubication): QMessageBox.information(self, "Exito", "Se pudo crear el archivo" + ubication) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo" + ubication) @Slot() def click_mostrar(self): #self.AlmacenP.mostrar() self.ui.plainTextEdit.clear() self.ui.plainTextEdit.insertPlainText(str(self.AlmacenP)) @Slot() def click_agregar(self): Id = self.ui.Id_spinBox.value() 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() Distancia = self.ui.Distancia_spinBox.value() Particulas = Particula(Id, OrigenX, OrigenY, DestinoX, DestinoY, Velocidad, Red, Green, Blue) self.AlmacenP.agregar_final(Particulas) # print(Id, OrigenX, OrigenY, DestinoX, DestinoY, Velocidad, Red, Green, Blue) # self.ui.plainTextEdit.insertPlainText(str(Id) + str(OrigenX) + str(OrigenY) + str(DestinoX) + str(DestinoY) + str(Velocidad) + str(Red) + str(Green) + str(Blue)) @Slot() def click_agregarInicio(self): Id = self.ui.Id_spinBox.value() 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() Distancia = self.ui.Distancia_spinBox.value() Particulas = Particula(Id, OrigenX, OrigenY, DestinoX, DestinoY, Velocidad, Red, Green, Blue, Distancia) self.AlmacenP.agregar_inicio(Particulas)
# -*- coding: utf-8 -*- # @Time : 2016-12-07 16:00 # @Author : wzb<*****@*****.**> import serial.tools.list_ports import sys from PyQt5.QtWidgets import QApplication, QMainWindow from ui_mainwindow import Ui_MainWindow if __name__ == '__main__': app = QApplication(sys.argv) mainWindow = QMainWindow() ui = Ui_MainWindow() ui.setupUi(mainWindow) mainWindow.show() sys.exit(app.exec_())
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.adm_part = Adm_part() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.agregar_final_pushButton.clicked.connect(self.click_agregar) self.ui.agregar_inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) self.ui.actionOrdenar_por_ID.triggered.connect( self.action_Ordenar_por_ID) self.ui.actionOrdenar_por_distancia.triggered.connect( self.action_Ordenar_por_distancia) self.ui.actionOrdenar_por_velocidad.triggered.connect( self.action_Ordenar_por_velocidad) self.ui.actionGrafo.triggered.connect(self.action_Grafo) self.ui.mostrar_tabla_pushButton.clicked.connect(self.mostrar_tabla) self.ui.buscar_pushButton.clicked.connect(self.buscar_id) self.ui.dibujar.clicked.connect(self.dibujar) self.ui.limpiar.clicked.connect(self.limpiar) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def action_Grafo(self): grafo = {} for particula in self.adm_part: key = particula.origen_x, particula.origen_y value = particula.destino_x, particula.destino_y, int( particula.distancia) if key in grafo: grafo[key].append(value) else: grafo[key] = [value] for particula in self.adm_part: key = particula.destino_x, particula.destino_y value = particula.origen_x, particula.origen_y, int( particula.distancia) if key in grafo: grafo[key].append(value) else: grafo[key] = [value] str = pformat(grafo, width=40, indent=1) print(str) @Slot() def action_Ordenar_por_ID(self): lista = [] for particula in self.adm_part: lista.append(particula) lista.sort(key=lambda particula: particula.id) for particula in lista: self.adm_part.ordenar(particula) @Slot() def action_Ordenar_por_distancia(self): lista = [] for particula in self.adm_part: lista.append(particula) lista.sort(key=lambda particula: particula.distancia, reverse=True) for particula in lista: self.adm_part.ordenar(particula) @Slot() def action_Ordenar_por_velocidad(self): lista = [] for particula in self.adm_part: lista.append(particula) lista.sort(key=lambda particula: particula.velocidad) for particula in lista: self.adm_part.ordenar(particula) @Slot() def dibujar(self): pen = QPen() pen.setWidth(2) for particula in self.adm_part: r = int(particula.rojo) g = int(particula.verde) b = int(particula.azul) color = QColor(r, g, b) pen.setColor(color) origen_x = int(particula.origen_x) origen_y = int(particula.origen_y) destino_x = int(particula.destino_x) destino_y = int(particula.destino_y) self.scene.addEllipse(origen_x, origen_y, 3, 3, pen) self.scene.addEllipse(destino_x, destino_y, 3, 3, pen) self.scene.addLine(origen_x + 3, origen_y + 3, destino_x, destino_y, pen) @Slot() def limpiar(self): self.scene.clear() @Slot() def buscar_id(self): id = self.ui.buscar_spinBox.value() encontrado = False for particula in self.adm_part: if id == particula.id: self.ui.tabla.clear() self.ui.tabla.setRowCount(1) id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) rojo_widget = QTableWidgetItem(str(particula.rojo)) verde_widget = QTableWidgetItem(str(particula.verde)) azul_widget = QTableWidgetItem(str(particula.azul)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(0, 0, id_widget) self.ui.tabla.setItem(0, 1, origen_x_widget) self.ui.tabla.setItem(0, 2, origen_y_widget) self.ui.tabla.setItem(0, 3, destino_x_widget) self.ui.tabla.setItem(0, 4, destino_y_widget) self.ui.tabla.setItem(0, 5, velocidad_widget) self.ui.tabla.setItem(0, 6, rojo_widget) self.ui.tabla.setItem(0, 7, verde_widget) self.ui.tabla.setItem(0, 8, azul_widget) self.ui.tabla.setItem(0, 9, distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atención", f'La particula con el ID "{id}" no fue encontrada') @Slot() def mostrar_tabla(self): self.ui.tabla.setColumnCount(10) headers = [ "ID", "Origen en x", "Origen en y", "Destino en x", "Destino en y", "Velocidad", "Rojo", "Verde", "Azul", "Distancia" ] self.ui.tabla.setHorizontalHeaderLabels(headers) self.ui.tabla.setRowCount(len(self.adm_part)) row = 0 for particula in self.adm_part: id_widget = QTableWidgetItem(str(particula.id)) origen_x_widget = QTableWidgetItem(str(particula.origen_x)) origen_y_widget = QTableWidgetItem(str(particula.origen_y)) destino_x_widget = QTableWidgetItem(str(particula.destino_x)) destino_y_widget = QTableWidgetItem(str(particula.destino_y)) velocidad_widget = QTableWidgetItem(str(particula.velocidad)) rojo_widget = QTableWidgetItem(str(particula.rojo)) verde_widget = QTableWidgetItem(str(particula.verde)) azul_widget = QTableWidgetItem(str(particula.azul)) distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.tabla.setItem(row, 0, id_widget) self.ui.tabla.setItem(row, 1, origen_x_widget) self.ui.tabla.setItem(row, 2, origen_y_widget) self.ui.tabla.setItem(row, 3, destino_x_widget) self.ui.tabla.setItem(row, 4, destino_y_widget) self.ui.tabla.setItem(row, 5, velocidad_widget) self.ui.tabla.setItem(row, 6, rojo_widget) self.ui.tabla.setItem(row, 7, verde_widget) self.ui.tabla.setItem(row, 8, azul_widget) self.ui.tabla.setItem(row, 9, distancia_widget) row += 1 @Slot() def action_abrir_archivo(self): #print('abrir_archivo') ubicacion = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.', 'JSON(*.json)')[0] if self.adm_part.abrir(ubicacion): QMessageBox.information(self, "Exito", "Se abrió el archivo " + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo abrir el archivo " + ubicacion) @Slot() def action_guardar_archivo(self): #print('guardar_archivo') ubicacion = QFileDialog.getSaveFileName(self, 'Guardar Archivo', '.', 'JSON (*.json)')[0] print(ubicacion) if self.adm_part.guardar(ubicacion): QMessageBox.information(self, "Exito", "Se pudo crear el archivo " + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo " + ubicacion) @Slot() def click_mostrar(self): #self.adm_part.mostrar() self.ui.plainTextEdit.clear() self.ui.plainTextEdit.insertPlainText(str(self.adm_part)) @Slot() def click_agregar(self): id = self.ui.id_spinBox.value() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_spinBox.value() rojo = self.ui.rojo_spinBox.value() azul = self.ui.azul_spinBox.value() verde = self.ui.verde_spinBox.value() particula = Particula(id, origen_x, origen_y, destino_x, destino_y, velocidad, rojo, verde, azul) self.adm_part.agregar_final(particula) #print(id,origen_x,origen_y,destino_x,destino_y,rojo,azul,verde) #self.ui.plainTextEdit.insertPlainText(id + origen_x + origen_y + #destino_x + destino_y + rojo + azul + verde) @Slot() def click_agregar_inicio(self): id = self.ui.id_spinBox.value() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_spinBox.value() rojo = self.ui.rojo_spinBox.value() azul = self.ui.azul_spinBox.value() verde = self.ui.verde_spinBox.value() particula = Particula(id, origen_x, origen_y, destino_x, destino_y, velocidad, rojo, verde, azul) self.adm_part.agregar_inicio(particula)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.particulas = Admin_particulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.Agregar_Inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.Agregar_Final_pushButton.clicked.connect( self.click_agregar_final) self.ui.Mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.actionAbrir_Archivo.triggered.connect( self.action_abrir_archivo) self.ui.actionGuardar_Archivo.triggered.connect( self.action_guardar_archivo) @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName(self, 'Abrir Archivo', '.', 'JSON (*.json)')[0] if self.particulas.abrir(ubicacion): QMessageBox.information( self, "Éxito", "Apertura exitosa del archivo en " + ubicacion) else: QMessageBox.critical( self, "Error", "Fallo al intentar abir el archivo en " + ubicacion) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName(self, 'Guardar Archivo', '.', 'JSON (*.json)')[0] if self.particulas.guardar(ubicacion): QMessageBox.information( self, "Éxito", "Archivo creado correctamente en " + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo en " + ubicacion) @Slot() def click_agregar_inicio(self): Id = self.ui.ID_spinBox.value() Origen_X = self.ui.Origen_X_spinBox.value() Origen_Y = self.ui.Origen_Y_spinBox.value() Destino_X = self.ui.Destino_X_spinBox.value() Destino_Y = self.ui.Destino_Y_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, Origen_X, Origen_Y, Destino_X, Destino_Y, Velocidad, Red, Green, Blue) self.particulas.agregar_inicio(particula) @Slot() def click_agregar_final(self): Id = self.ui.ID_spinBox.value() Origen_X = self.ui.Origen_X_spinBox.value() Origen_Y = self.ui.Origen_Y_spinBox.value() Destino_X = self.ui.Destino_X_spinBox.value() Destino_Y = self.ui.Destino_Y_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, Origen_X, Origen_Y, Destino_X, Destino_Y, Velocidad, Red, Green, Blue) self.particulas.agregar_final(particula) @Slot() def click_mostrar(self): self.ui.Salida.clear() self.ui.Salida.insertPlainText(str(self.particulas))
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.ui= Ui_MainWindow() self.ui.setupUi(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.scene = QGraphicsScene() #self.scene.setSceneRect(0,500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(1) self.lista=[]; self.listaMenor=[]; self.capturador=Capturador() self.ui.pushButton.clicked.connect(self.click) self.ui.pushButton_2.clicked.connect(self.mostrar) self.ui.actionGuardar.triggered.connect(self.guardar) self.ui.actionAbrir_2.triggered.connect(self.abrir) self.ui.actionMostar.triggered.connect(self.mostarParticulasPuntos) self.ui.actionPuntos_Cercanos.triggered.connect(self.puntos_cercanos) self.ui.pushButton_3.clicked.connect(self.ordenar_velocidad) self.ui.pushButton_4.clicked.connect(self.ordenar_distancia) self.ui.pushButton_5.clicked.connect(self.grafo) @Slot() def grafo(self): grafoG = dict() # {} self.scene.clear() self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) for particula in self.capturador.lista: origen=(particula.origenX,particula.origenY) destino=(particula.destinoX,particula.destinoY) if origen in grafoG: grafoG[origen].append((destino, particula.distancia)) else: grafoG[origen] = [(destino, particula.distancia)] if destino in grafoG: grafoG[destino].append((origen, particula.distancia)) else: grafoG[destino] = [(origen, particula.distancia)] str = pprint.pformat(grafoG, width=40) self.ui.plainTextEdit.insertPlainText(str) @Slot() def puntos_cercanos(self): for i in range(len(self.lista)-1): particulaMenor=self.lista[i+1]; for j in range(len(self.lista)-1): particula2=self.lista[j] if(j==0): auxDistancia=math.sqrt(pow((int(particula2['x']) - int(particulaMenor['x'])), 2) + pow((int(particula2['y']) - int(particulaMenor['y'])), 2)) aux={'origen':particulaMenor,'destino':particula2} if((math.sqrt(pow((int(particula2['x'])-int(particulaMenor['x'])),2)+pow((int(particula2['y'])-int(particulaMenor['y'])),2))<auxDistancia)and(particulaMenor!=particula2)): auxDistancia = math.sqrt(pow((int(particula2['x']) - int(particulaMenor['x'])), 2) + pow((int(particula2['y']) - int(particulaMenor['y'])), 2)) aux = {'origen': particulaMenor, 'destino': particula2} self.listaMenor.append(aux); self.dibujar(); @Slot() def mostarParticulasPuntos(self): self.scene.clear() self.scene = QGraphicsScene() # self.scene.setSceneRect(0,500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(1) self.capturador.ordenar_velocidad() for particula in self.capturador.lista: self.lista.append({ 'x':particula.origenX, 'y':particula.origenY, 'color':{ 'red':particula.red, 'green':particula.green, 'blue':particula.blue } }) self.lista.append({ 'x':particula.destinoX, 'y':particula.destinoY, 'color':{ 'red':particula.red, 'green':particula.green, 'blue':particula.blue } }) self.ui.plainTextEdit.insertPlainText(str(particula)) self.pen.setColor(QColor(particula.red, particula.green, particula.blue)) self.scene.addEllipse(particula.origenX, particula.origenY, 5, 5, self.pen, QBrush(QColor(particula.red, 10,particula.green, particula.blue))) @Slot() def ordenar_velocidad(self): self.scene.clear() self.scene = QGraphicsScene() #self.scene.setSceneRect(0,500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(1) self.capturador.ordenar_velocidad() y=0 for particula in self.capturador.lista: self.ui.plainTextEdit.insertPlainText(str(particula)) self.pen.setColor(QColor(particula.red, particula.green, particula.blue)) self.scene.addLine(0, y, particula.distancia, y, self.pen) y=y+2 def dibujar(self): self.scene.clear() self.scene = QGraphicsScene() # self.scene.setSceneRect(0,500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(1) self.capturador.ordenar_distancia() for new in self.listaMenor: self.scene.addEllipse(new['origen']['x'], new['origen']['y'], 5, 5, self.pen,QBrush(QColor(new['origen']['color']['red'], 10, new['origen']['color']['green'], new['origen']['color']['blue']))) self.pen.setColor(QColor(new['origen']['color']['red'], new['origen']['color']['green'], new['origen']['color']['blue'])) self.scene.addLine(new['origen']['x'], new['origen']['y'], new['destino']['x'], new['destino']['y'], self.pen) @Slot() def ordenar_distancia(self): self.scene.clear() self.scene = QGraphicsScene() #self.scene.setSceneRect(0,500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(1) self.capturador.ordenar_distancia() y=0 for particula in self.capturador.lista: self.ui.plainTextEdit.insertPlainText(str(particula)) self.pen.setColor(QColor(particula.red, particula.green, particula.blue)) self.scene.addLine(0, y, particula.distancia, y, self.pen) y=y+2 @Slot() def guardar(self): self.scene = QGraphicsScene() #self.scene.setSceneRect(0,500) self.ui.graphicsView.setScene(self.scene) self.pen = QPen() self.pen.setColor(QColor(0, 0, 0)) self.pen.setWidth(1) file= QFileDialog.getSaveFileName(self, 'Guardar archivo...', '.', 'JSON (*.json)') print(file) self.capturador.guardar(file[0],self.pen,self.scene) @Slot() def abrir(self): file= QFileDialog.getOpenFileName(self, 'Abrir archivo', '.', 'JSON (*.json)') self.capturador.recuperar(file[0]) @Slot() def mostrar(self): self.scene.clear() self.scene.addLine(0, 0, 499, 0, self.pen) y=0 for particula in self.capturador.lista: self.ui.plainTextEdit.insertPlainText(str(particula)) self.pen.setColor(QColor(particula.red, particula.green, particula.blue)) self.scene.addLine(0, y, particula.distancia, y, self.pen) y=y+2 #for particula in self.capturador.lista: # self.ui.plainTextEdit.insertPlainText(str(particula)) # self.pen.setColor(QColor(particula.red, particula.green, particula.blue)) # self.scene.addEllipse(particula.origenX, particula.origenY, 5, 5, self.pen, QBrush(QColor(particula.red, 10,particula.green, particula.blue))) #self.scene.addLine(particula.origenX, particula.origenY, particula.destinoX, particula.destinoY, self.pen) #self.paqueteria.mostrar() @Slot() def click(self): id=self.ui.lineEdit.text() origenX=self.ui.lineEdit_2.text() origenY=self.ui.lineEdit_6.text() destinoX=self.ui.lineEdit_3.text() destinoY=self.ui.lineEdit_7.text() velocidad=self.ui.lineEdit_4.text() red=self.ui.lineEdit_5.text() green=self.ui.lineEdit_8.text() blue=self.ui.lineEdit_9.text() print(id, origenX, origenY,destinoX, destinoY, velocidad, red, green, blue) partiula=Particula() partiula.id= id partiula.origenX=int(origenX) partiula.origenY=int(origenY) partiula.destinoX=int(destinoX) partiula.destinoY=int(destinoY) partiula.distancia=math.sqrt(pow((int(destinoX)-int(origenX)),2)+pow((int(destinoY)-int(origenY)),2)) partiula.red=int(red) partiula.green=int(green) partiula.blue=int(blue) partiula.velocidad=int(velocidad) self.capturador.agregar(partiula) msg=QMessageBox.information(self, 'Exito', 'Se agrego paquete con exito') #Ventana de mensaje de la libreria QMessageBox self.ui.lineEdit.clear() #Limpiar campos self.ui.lineEdit_2.clear() self.ui.lineEdit_3.clear() self.ui.lineEdit_4.clear() self.ui.lineEdit_5.clear() self.ui.lineEdit_6.clear() self.ui.lineEdit_7.clear() self.ui.lineEdit_8.clear() self.ui.lineEdit_9.clear()
class MainWindow(QtGui.QMainWindow): POLLING_DURATION = 10000 # 10000msec = 10sec SETTINGS_FILE_NAME = "nicopealert.dat" INIT_SETTINGS = { "version": "0.0.1", # 設定ファイルが互換性がなくなるときに変更 "watchList": {}, "communityList": {}, "tabList": [], "browserOpenMode": 0, } def checkSemaphore(self): self.sem = QtCore.QSystemSemaphore("nicopealert-app", 1) self.sem.acquire() self.firstApp = True self.inited = False def __init__(self, app, logger): # 同時に1起動制限 self.firstApp = False t = threading.Thread(target=self.checkSemaphore) t.start() t.join(0.2) if not self.firstApp: sys.exit(1) # 初期化処理 QtGui.QDialog.__init__(self) self.app = app self.logger = logger self.ui = Ui_MainWindow() self.ui.setupUi(self) # load settings try: f = open(self.SETTINGS_FILE_NAME, "rb") self.settings = pickle.load(f) f.close() for k, v in self.INIT_SETTINGS.items(): if not self.settings.has_key(k): self.settings[k] = v except: self.settings = self.INIT_SETTINGS # models self.dicTableModel = NicoDicTableModel(self) self.liveTableModel = NicoLiveTableModel(self) self.watchListTableModel = WatchListTableModel(self) self.communityListTableModel = CommunityTableModel(self) # tab widget self.tabWidget = DraggableTabWidget(self.ui.centralwidget) self.tabWidget.setLayoutDirection(QtCore.Qt.LeftToRight) self.ui.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) self.connect(self.tabWidget, QtCore.SIGNAL("currentChanged(int)"), self.tabWidgetChangedHandler) # initial tabs DicUserTabWidget(self) LiveUserTabWidget(self) WatchListUserTabWidget(self) CommunityListUserTabWidget(self) self.tabWidget.setCurrentIndex(0) # trayIcon/trayIconMenu/trayIconImg self.trayIconImg = QtGui.QIcon(self.tr(":/dic.ico")) self.trayIconMenu = QtGui.QMenu(self) self.trayIconMenu.addAction(u"表示/非表示", lambda: self.toggleWindowVisibility()) self.trayIconMenu.addAction(u"終了", lambda: self.app.quit()) self.trayIcon = QtGui.QSystemTrayIcon(self) self.trayIcon.setContextMenu(self.trayIconMenu) self.trayIcon.setIcon(self.trayIconImg) self.trayIcon.show() self.connect(self.trayIcon, QtCore.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.trayIconHandler) # window style self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowMinimizeButtonHint) # first data fetch self.nicopoll = NicoPoll(self.dicTableModel, self.liveTableModel) self.nicopoll.fetch(self) # menu self.fileMenu = QtGui.QMenu(self.ui.menubar) self.fileMenu.addAction(u"設定", lambda: self.showSettingsDialog()) self.fileMenu.addSeparator() self.fileMenu.addAction(u"トレイアイコンに収納", lambda: self.hide()) self.fileMenu.addAction(u"終了", lambda: self.app.quit()) self.fileMenu.setTitle(self.trUtf8("ファイル")) self.ui.menubar.addAction(self.fileMenu.menuAction()) def show(self): QtGui.QMainWindow.show(self) self.activateWindow() if not self.inited: # データ挿入 self.watchListTableModel.appendItems(self.settings["watchList"]) self.communityListTableModel.appendItems(self.settings["communityList"]) for tabcond in self.settings["tabList"]: if tabcond["class"] == u"DicUserTabWidget": t = DicUserTabWidget(self, False) t.setCond(tabcond) elif tabcond["class"] == u"LiveUserTabWidget": t = LiveUserTabWidget(self, False) t.setCond(tabcond) # タブの見た目関係初期化 for i in xrange(0, self.tabWidget.count()): w = self.tabWidget.widget(i) w.init_after_show() self.inited = True # set timer for polling self.timer = QtCore.QTimer(self) self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.timer_handler) self.timer.setInterval(self.POLLING_DURATION) self.timer.start() def timer_handler(self): self.nicopoll.fetch(self) # def showVersionUpDialog(self): # クライアントバージョンが古い msg = QtGui.QMessageBox.critical( self, self.trUtf8("バージョンアップのお知らせ"), self.trUtf8("ニコ百アラートがバージョンアップしました。お使いのバージョンは今後利用できなくなります。お手数ですが、バージョンアップお願いいたします。"), self.trUtf8("ダウンロードページを開く"), self.trUtf8("終了する"), ) if msg == 0: import webbrowser webbrowser.open("http://dic.nicovideo.jp/nicopealert/") sys.exit(2) def toggleWindowVisibility(self): if self.isVisible(): self.hide() else: self.show() def trayIconHandler(self, reason): # NOTE: Macではダメっぽい if reason == QtGui.QSystemTrayIcon.DoubleClick: self.toggleWindowVisibility() def tabWidgetChangedHandler(self, index): self.tabWidget.currentWidget().setTabNotify(False) def appendWatchList(self, category, title, view_title): key = u"%s%s" % (category, title) i = {"category": category, "title": title, "view_title": view_title} self.watchListTableModel.appendItems({key: i}) self.settings["watchList"][key] = i self.saveSettings() def appendCommunityList(self, com_id, com_name): # NOTE: com_idはkeyにもvalueにも入っている。 u = {"id": com_id, "name": com_name} self.communityListTableModel.appendItems({com_id: u}) self.settings["communityList"][com_id] = u self.saveSettings() # 各タブの情報を保存する def saveTabs(self): tabList = [] for i in xrange(0, self.tabWidget.count()): w = self.tabWidget.widget(i) # 初期タブ以外を保存 if not w.initial: tabList.append(w.cond()) self.settings["tabList"] = tabList self.saveSettings() # NOTE: 小汚い def removeWatchList(self, row): category, title = map(lambda d: unicode(d.toString()), self.watchListTableModel.raw_row_data(row)[0:2]) key = u"%s%s" % (category, title) self.watchListTableModel.removeRow(row) del self.settings["watchList"][key] self.saveSettings() # NOTE: 小汚い def removeCommunityList(self, row): com_id = unicode( self.communityListTableModel.raw_row_data(row)[self.communityListTableModel.COL_COM_ID_INDEX].toString() ) self.communityListTableModel.removeRow(row) del self.settings["communityList"][com_id] self.saveSettings() def saveSettings(self): try: tmpfilename = self.SETTINGS_FILE_NAME + ".tmp" f = open(tmpfilename, "wb") pickle.dump(self.settings, f) f.close() if os.name == "nt": try: os.remove(self.SETTINGS_FILE_NAME) except: pass os.rename(tmpfilename, self.SETTINGS_FILE_NAME) except: pass def closeEvent(self, event): # ×ボタンで、タスクトレイバーのみになる self.hide() event.ignore() def showSettingsDialog(self): d = SettingsDialog() d.load(self) d.show() def browserOpen(self, url): print self.settings["browserOpenMode"] webbrowser.open(url, self.settings["browserOpenMode"])
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.particulas = Admin_particulas() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.Agregar_Inicio_pushButton.clicked.connect(self.click_agregar_inicio) self.ui.Agregar_Final_pushButton.clicked.connect(self.click_agregar_final) self.ui.Mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.Ordenar_ID_pushButton.clicked.connect(self.ordenar_ID) self.ui.Ordenar_Distancia_pushButton.clicked.connect(self.ordenar_Distancia) self.ui.Ordenar_Velocidad_pushButton.clicked.connect(self.ordenar_Velocidad) self.ui.Dibujar_Grafo_pushButton.clicked.connect(self.dibujar_Grafo) self.ui.Recorrido_Profundidad_pushButton.clicked.connect(self.recorrido_profundidad) self.ui.Recorrido_Amplitud_pushButton.clicked.connect(self.recorrido_amplitud) self.ui.actionAbrir_Archivo.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar_Archivo.triggered.connect(self.action_guardar_archivo) self.ui.Buscar_pushButton.clicked.connect(self.buscar_ID) self.ui.Dibujar_pushButton.clicked.connect(self.dibujar_particulas) self.ui.Limpiar_pushButton.clicked.connect(self.limpiar_pantalla) self.scene = QGraphicsScene() self.ui.graphicsView.setScene(self.scene) def wheelEvent(self, event): if event.delta() > 0: self.ui.graphicsView.scale(1.2, 1.2) else: self.ui.graphicsView.scale(0.8, 0.8) @Slot() def ordenar_ID(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.particulas.sort(1) self.click_mostrar() @Slot() def ordenar_Distancia(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.particulas.sort(2) self.click_mostrar() @Slot() def ordenar_Velocidad(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.particulas.sort(3) self.click_mostrar() @Slot() def dibujar_Grafo(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: grafo = dict() for particula in self.particulas: origen = (particula.origen_x, particula.origen_y) destino = (particula.destino_x, particula.destino_y) peso = particula.distancia arista_o_d = (destino, peso) arista_d_o = (origen, peso) if origen in grafo: grafo[origen].append(arista_o_d) else: grafo[origen] = [arista_o_d] if destino in grafo: grafo[destino].append(arista_d_o) else: grafo[destino] = [arista_d_o] self.dibujar_particulas() str = pformat(grafo, width=80, indent=1) self.ui.Pantalla_Diccionarios.clear() self.ui.Pantalla_Diccionarios.insertPlainText(str) @Slot() def recorrido_profundidad(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: grafo = dict() for particula in self.particulas: origen = (particula.origen_x, particula.origen_y) destino = (particula.destino_x, particula.destino_y) peso = particula.distancia arista_o_d = (destino, peso) arista_d_o = (origen, peso) if origen in grafo: grafo[origen].append(arista_o_d) else: grafo[origen] = [arista_o_d] if destino in grafo: grafo[destino].append(arista_d_o) else: grafo[destino] = [arista_d_o] keys = list(grafo.keys()) elementos = list(grafo.items()) visitados = [keys[0]] pila = [keys[0]] recorrido = [] while pila: recorrido.append(pila[len(pila)-1]) i = 0 for key in keys: if key == pila[len(pila)-1]: break i += 1 pila.pop() for elemento in elementos[i][1]: if not elemento[0] in visitados: visitados.append(elemento[0]) pila.append(elemento[0]) self.ui.Pantalla_Recorridos.clear() self.ui.Pantalla_Recorridos.insertPlainText("\n\n Recorrido Profundidad ") for vertice in recorrido: if vertice != recorrido[len(recorrido)-1]: self.ui.Pantalla_Recorridos.insertPlainText(str(vertice)+", ") else: self.ui.Pantalla_Recorridos.insertPlainText(str(vertice)) self.mostrar_dict() @Slot() def recorrido_amplitud(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: grafo = dict() for particula in self.particulas: origen = (particula.origen_x, particula.origen_y) destino = (particula.destino_x, particula.destino_y) peso = particula.distancia arista_o_d = (destino, peso) arista_d_o = (origen, peso) if origen in grafo: grafo[origen].append(arista_o_d) else: grafo[origen] = [arista_o_d] if destino in grafo: grafo[destino].append(arista_d_o) else: grafo[destino] = [arista_d_o] keys = list(grafo.keys()) elementos = list(grafo.items()) visitados = [keys[0]] cola = [keys[0]] recorrido = [] while cola: recorrido.append(cola[0]) i = 0 for key in keys: if key == cola[0]: break i += 1 cola.pop(0) for elemento in elementos[i][1]: if not elemento[0] in visitados: visitados.append(elemento[0]) cola.append(elemento[0]) self.ui.Pantalla_Recorridos.clear() self.ui.Pantalla_Recorridos.insertPlainText("\n\n Recorrido Amplitud ") for vertice in recorrido: if vertice != recorrido[len(recorrido)-1]: self.ui.Pantalla_Recorridos.insertPlainText(str(vertice)+", ") else: self.ui.Pantalla_Recorridos.insertPlainText(str(vertice)) self.mostrar_dict() @Slot() def mostrar_dict(self): grafo = dict() for particula in self.particulas: origen = (particula.origen_x, particula.origen_y) destino = (particula.destino_x, particula.destino_y) peso = particula.distancia arista_o_d = (destino, peso) arista_d_o = (origen, peso) if origen in grafo: grafo[origen].append(arista_o_d) else: grafo[origen] = [arista_o_d] if destino in grafo: grafo[destino].append(arista_d_o) else: grafo[destino] = [arista_d_o] str = pformat(grafo, width=80, indent=1) self.ui.Pantalla_Diccionarios.clear() self.ui.Pantalla_Diccionarios.insertPlainText(str) @Slot() def dibujar_particulas(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado particulas existentes' ) else: for particula in self.particulas: pen = QPen() color = QColor(particula.red, particula.green, particula.blue) pen.setColor(color) pen.setWidth(2) self.scene.addEllipse(particula.origen_x, particula.origen_y, 3, 3, pen) self.scene.addEllipse(particula.destino_x, particula.destino_y, 3, 3, pen) self.scene.addLine(particula.origen_x + 3, particula.origen_y, particula.destino_x + 3, particula.destino_y, pen) @Slot() def limpiar_pantalla(self): self.scene.clear() @Slot() def buscar_ID(self): id = self.ui.Buscar_lineEdit.text() encontrado = False for particula in self.particulas: if id == str(particula.id): self.ui.Table.clear() self.ui.Table.setRowCount(1) ID_widget = QTableWidgetItem(str(particula.id)) Origen_X_widget = QTableWidgetItem(str(particula.origen_x)) Origen_Y_widget = QTableWidgetItem(str(particula.origen_y)) Destino_X_widget = QTableWidgetItem(str(particula.destino_x)) Destino_Y_widget = QTableWidgetItem(str(particula.destino_y)) Velocidad_widget = QTableWidgetItem(str(particula.velocidad)) Red_widget = QTableWidgetItem(str(particula.red)) Green_widget = QTableWidgetItem(str(particula.green)) Blue_widget = QTableWidgetItem(str(particula.blue)) Distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.Table.setItem(0, 0, ID_widget) self.ui.Table.setItem(0, 1, Origen_X_widget) self.ui.Table.setItem(0, 2, Origen_Y_widget) self.ui.Table.setItem(0, 3, Destino_X_widget) self.ui.Table.setItem(0, 4, Destino_Y_widget) self.ui.Table.setItem(0, 5, Velocidad_widget) self.ui.Table.setItem(0, 6, Red_widget) self.ui.Table.setItem(0, 7, Green_widget) self.ui.Table.setItem(0, 8, Blue_widget) self.ui.Table.setItem(0, 9, Distancia_widget) encontrado = True return if not encontrado: QMessageBox.warning( self, "Atención", f'La particula con el ID "{id}" no fue encontrada' ) @Slot() def mostrar_tabla(self): self.ui.Table.setColumnCount(10) headers = ["ID", "Origen en X", "Origen en Y", "Destino en X", "Destino en Y", "Velocidad", "Red", "Green", "Blue", "Distancia"] self.ui.Table.setHorizontalHeaderLabels(headers) self.ui.Table.setRowCount(len(self.particulas)) row = 0 for particula in self.particulas: ID_widget = QTableWidgetItem(str(particula.id)) Origen_X_widget = QTableWidgetItem(str(particula.origen_x)) Origen_Y_widget = QTableWidgetItem(str(particula.origen_y)) Destino_X_widget = QTableWidgetItem(str(particula.destino_x)) Destino_Y_widget = QTableWidgetItem(str(particula.destino_y)) Velocidad_widget = QTableWidgetItem(str(particula.velocidad)) Red_widget = QTableWidgetItem(str(particula.red)) Green_widget = QTableWidgetItem(str(particula.green)) Blue_widget = QTableWidgetItem(str(particula.blue)) Distancia_widget = QTableWidgetItem(str(particula.distancia)) self.ui.Table.setItem(row, 0, ID_widget) self.ui.Table.setItem(row, 1, Origen_X_widget) self.ui.Table.setItem(row, 2, Origen_Y_widget) self.ui.Table.setItem(row, 3, Destino_X_widget) self.ui.Table.setItem(row, 4, Destino_Y_widget) self.ui.Table.setItem(row, 5, Velocidad_widget) self.ui.Table.setItem(row, 6, Red_widget) self.ui.Table.setItem(row, 7, Green_widget) self.ui.Table.setItem(row, 8, Blue_widget) self.ui.Table.setItem(row, 9, Distancia_widget) row +=1 @Slot() def action_abrir_archivo(self): ubicacion = QFileDialog.getOpenFileName( self, 'Abrir Archivo', '.', 'JSON (*.json)' )[0] if self.particulas.abrir(ubicacion): QMessageBox.information( self, "Éxito", "Apertura exitosa del archivo en " + ubicacion ) else: QMessageBox.critical( self, "Error", "Fallo al intentar abir el archivo en " + ubicacion ) @Slot() def action_guardar_archivo(self): ubicacion = QFileDialog.getSaveFileName( self, 'Guardar Archivo', '.', 'JSON (*.json)' )[0] if self.particulas.guardar(ubicacion): QMessageBox.information( self, "Éxito", "Archivo creado correctamente en " + ubicacion ) else: QMessageBox.critical( self, "Error", "No se pudo crear el archivo en " + ubicacion ) @Slot() def click_agregar_inicio(self): Id = self.ui.ID_spinBox.value() Origen_X = self.ui.Origen_X_spinBox.value() Origen_Y = self.ui.Origen_Y_spinBox.value() Destino_X = self.ui.Destino_X_spinBox.value() Destino_Y = self.ui.Destino_Y_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, Origen_X, Origen_Y, Destino_X, Destino_Y, Velocidad, Red, Green, Blue) self.particulas.agregar_inicio(particula) @Slot() def click_agregar_final(self): Id = self.ui.ID_spinBox.value() Origen_X = self.ui.Origen_X_spinBox.value() Origen_Y = self.ui.Origen_Y_spinBox.value() Destino_X = self.ui.Destino_X_spinBox.value() Destino_Y = self.ui.Destino_Y_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, Origen_X, Origen_Y, Destino_X, Destino_Y, Velocidad, Red, Green, Blue) self.particulas.agregar_final(particula) @Slot() def click_mostrar(self): if len(self.particulas) == 0: QMessageBox.warning( self, "Atención", 'No se han detectado partículas existentes' ) else: self.ui.Salida.clear() self.ui.Salida.insertPlainText(str(self.particulas)) self.mostrar_tabla()
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): # Initialise the UI self.display = None super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Current file self._filename = None self._last_file_handler = None # Importers / Exporters self._file_handlers = [] # Update our window caption self._caption = "Zoxel" # Our global state self.settings = QtCore.QSettings("Zoxel", "Zoxel") self.state = {} # Our animation timer self._timer = QtCore.QTimer(self) self.connect(self._timer, QtCore.SIGNAL("timeout()"), self.on_animation_tick) self._anim_speed = 200 # Load our state if possible self.load_state() # Create our GL Widget try: voxels = GLWidget(self.ui.glparent) self.ui.glparent.layout().addWidget(voxels) self.display = voxels except Exception as E: QtGui.QMessageBox.warning(self, "Initialisation Failed", str(E)) exit(1) # Load default model dimensions width = self.get_setting("default_model_width") height = self.get_setting("default_model_height") depth = self.get_setting("default_model_depth") if width: self.resize_voxels(width, height, depth) # Resize is detected as a change, discard changes self.display.voxels.saved() # Create our palette widget voxels = PaletteWidget(self.ui.palette) self.ui.palette.layout().addWidget(voxels) self.colour_palette = voxels # More UI state value = self.get_setting("display_axis_grids") if value is not None: self.ui.action_axis_grids.setChecked(value) self.display.axis_grids = value value = self.get_setting("background_colour") if value is not None: self.display.background = QtGui.QColor.fromRgb(*value) value = self.get_setting("voxel_edges") if value is not None: self.display.voxel_edges = value self.ui.action_voxel_edges.setChecked(value) else: self.ui.action_voxel_edges.setChecked(self.display.voxel_edges) value = self.get_setting("occlusion") if value is None: value = True self.display.voxels.occlusion = value self.ui.action_occlusion.setChecked(value) # Connect some signals if self.display: self.display.voxels.notify = self.on_data_changed self.display.tool_activated.connect(self.on_tool_activated) self.display.tool_activated_alt.connect(self.on_tool_activated_alt) self.display.tool_dragged.connect(self.on_tool_dragged) self.display.tool_deactivated.connect(self.on_tool_deactivated) if self.colour_palette: self.colour_palette.changed.connect(self.on_colour_changed) # Initialise our tools self._tool_group = QtGui.QActionGroup(self.ui.toolbar_drawing) self._tools = [] # Setup window self.update_caption() self.refresh_actions() def on_animation_tick(self): self.on_action_anim_next_triggered() @QtCore.Slot() def on_action_about_triggered(self): dialog = AboutDialog(self) if dialog.exec_(): pass @QtCore.Slot() def on_action_axis_grids_triggered(self): self.display.axis_grids = self.ui.action_axis_grids.isChecked() self.set_setting("display_axis_grids", self.display.axis_grids) @QtCore.Slot() def on_action_voxel_edges_triggered(self): self.display.voxel_edges = self.ui.action_voxel_edges.isChecked() self.set_setting("voxel_edges", self.display.voxel_edges) @QtCore.Slot() def on_action_zoom_in_triggered(self): self.display.zoom_in() @QtCore.Slot() def on_action_zoom_out_triggered(self): self.display.zoom_out() @QtCore.Slot() def on_action_new_triggered(self): if self.display.voxels.changed: if not self.confirm_save(): return # Clear our data self._filename = "" self.display.clear() self.display.voxels.saved() self.update_caption() self.refresh_actions() @QtCore.Slot() def on_action_wireframe_triggered(self): self.display.wireframe = self.ui.action_wireframe.isChecked() self.set_setting("display_wireframe", self.display.wireframe) @QtCore.Slot() def on_action_save_triggered(self): # Save self.save() @QtCore.Slot() def on_action_saveas_triggered(self): # Save self.save(True) @QtCore.Slot() def on_action_open_triggered(self): # Load self.load() @QtCore.Slot() def on_action_undo_triggered(self): # Undo self.display.voxels.undo() self.display.refresh() @QtCore.Slot() def on_action_redo_triggered(self): # Redo self.display.voxels.redo() self.display.refresh() @QtCore.Slot() def on_action_resize_triggered(self): # Resize model dimensions dialog = ResizeDialog(self) dialog.ui.width.setValue(self.display.voxels.width) dialog.ui.height.setValue(self.display.voxels.height) dialog.ui.depth.setValue(self.display.voxels.depth) if dialog.exec_(): width = dialog.ui.width.value() height = dialog.ui.height.value() depth = dialog.ui.depth.value() self.resize_voxels(width, height, depth) def resize_voxels(self, width, height, depth): new_width_scale = float(width) / self.display.voxels.width new_height_scale = float(height) / self.display.voxels.height new_depth_scale = float(depth) / self.display.voxels.depth self.display.voxels.resize(width, height, depth) self.display.grids.scale_offsets( new_width_scale, new_height_scale, new_depth_scale ) self.display.refresh() # Remember these dimensions self.set_setting("default_model_width", width) self.set_setting("default_model_height", height) self.set_setting("default_model_depth", depth) @QtCore.Slot() def on_action_reset_camera_triggered(self): self.display.reset_camera() @QtCore.Slot() def on_action_occlusion_triggered(self): self.display.voxels.occlusion = self.ui.action_occlusion.isChecked() self.set_setting("occlusion", self.display.voxels.occlusion) self.display.refresh() @QtCore.Slot() def on_action_background_triggered(self): # Choose a background colour colour = QtGui.QColorDialog.getColor() if colour.isValid(): self.display.background = colour colour = (colour.red(), colour.green(), colour.blue()) self.set_setting("background_colour", colour) @QtCore.Slot() def on_action_anim_add_triggered(self): self.display.voxels.add_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_delete_triggered(self): self.display.voxels.delete_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_play_triggered(self): self._timer.start(self._anim_speed) self.refresh_actions() @QtCore.Slot() def on_action_anim_stop_triggered(self): self._timer.stop() self.refresh_actions() @QtCore.Slot() def on_action_anim_next_triggered(self): self.display.voxels.select_next_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_previous_triggered(self): self.display.voxels.select_previous_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_settings_triggered(self): pass @QtCore.Slot() def on_action_rotate_x_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.X_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_y_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Y_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_z_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Z_AXIS) self.display.refresh() @QtCore.Slot() def on_action_voxel_colour_triggered(self): # Choose a voxel colour colour = QtGui.QColorDialog.getColor() if colour.isValid(): self.colour_palette.colour = colour @QtCore.Slot() def on_action_export_image_triggered(self): png = QtGui.QPixmap.grabWidget(self.display) choices = "PNG Image (*.png);;JPEG Image (*.jpg)" # Grab our default location directory = self.get_setting("default_directory") # grab a filename filename, filetype = QtGui.QFileDialog.getSaveFileName(self, caption = "Export Image As", filter = choices, dir = directory) if not filename: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Save the PNG png.save(filename,filetype.split()[0]) def on_tool_activated(self): self.activate_tool(self.display.target, self.display.mouse_position) def on_tool_activated_alt(self): self.activate_tool_alt(self.display.target, self.display.mouse_position) def on_tool_dragged(self): self.drag_tool(self.display.target, self.display.mouse_position) def on_tool_deactivated(self): self.deactivate_tool(self.display.target) # Confirm if user wants to save before doing something drastic. # returns True if we should continue def confirm_save(self): responce = QtGui.QMessageBox.question(self,"Save changes?", "Save changes before discarding?", buttons = (QtGui.QMessageBox.Save | QtGui.QMessageBox.Cancel | QtGui.QMessageBox.No)) if responce == QtGui.QMessageBox.StandardButton.Save: if not self.save(): return False elif responce == QtGui.QMessageBox.StandardButton.Cancel: return False return True # Voxel data changed signal handler def on_data_changed(self): self.update_caption() self.refresh_actions() # Colour selection changed handler def on_colour_changed(self): self.display.voxel_colour = self.colour_palette.colour # Return a section of our internal config def get_setting(self, name): if name in self.state: return self.state[name] return None # Set some config. Value should be a serialisable type def set_setting(self, name, value): self.state[name] = value def closeEvent(self, event): # Save state self.save_state() if self.display.voxels.changed: if not self.confirm_save(): event.ignore() return event.accept() # Save our state def save_state(self): try: state = json.dumps(self.state) self.settings.setValue("system/state", state) except Exception as E: # XXX Fail. Never displays because we're on our way out error = QtGui.QErrorMessage(self) error.showMessage(str(E)) print str(E) # Load our state def load_state(self): try: state = self.settings.value("system/state") if state: self.state = json.loads(state) except Exception as E: error = QtGui.QErrorMessage(self) error.showMessage(str(E)) # Update the window caption to reflect the current state def update_caption(self): caption = "Zoxel" if self._filename: caption += " - [%s]" % self._filename else: caption += " - [Unsaved model]" if self.display and self.display.voxels.changed: caption += " *" numframes = self.display.voxels.get_frame_count() frame = self.display.voxels.get_frame_number()+1 if numframes > 1: caption += " - Frame {0} of {1}".format(frame, numframes) if caption != self._caption: self.setWindowTitle(caption) self._caption = caption # Save the current data def save(self, newfile = False): # Find the handlers that support saving handlers = [x for x in self._file_handlers if hasattr(x, 'save')] saved = False filename = self._filename handler = self._last_file_handler if handler: filetype = handler.filetype # Build list of available types choices = [] for exporter in handlers: choices.append( "%s (%s)" % (exporter.description, exporter.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename if we need one if newfile or not filename: filename, filetype = QtGui.QFileDialog.getSaveFileName(self, caption = "Save As", filter = choices, dir = directory, selectedFilter="Zoxel Files (*.zox)") if not filename: return handler = None # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler if we need to if not handler: for exporter in handlers: ourtype = "%s (%s)" % (exporter.description, exporter.filetype) if filetype == ourtype: handler = exporter # Call the save handler try: handler.save(filename) saved = True except Exception as Ex: QtGui.QMessageBox.warning(self, "Save Failed", str(Ex)) # If we saved, clear edited state if saved: self._filename = filename self._last_file_handler = handler self.display.voxels.saved() self.update_caption() self.refresh_actions() return saved # Registers an file handler (importer/exporter) with the system def register_file_handler(self, handler): self._file_handlers.append(handler) # load a file def load(self): # If we have changes, perhaps we should save? if self.display.voxels.changed: if not self.confirm_save(): return # Find the handlers that support loading handler = None handlers = [x for x in self._file_handlers if hasattr(x, 'load')] # Build list of types we can load choices = [] for importer in handlers: choices.append( "%s (%s)" % (importer.description, importer.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename filename, filetype = QtGui.QFileDialog.getOpenFileName(self, caption="Open file", filter=choices, dir = directory, selectedFilter="Zoxel Files (*.zox)") if not filename: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler for importer in handlers: ourtype = "%s (%s)" % (importer.description, importer.filetype) if filetype == ourtype: handler = importer self._last_file_handler = handler # Load the file self.display.clear() self.display.voxels.disable_undo() self._filename = None try: handler.load(filename) self._filename = filename except Exception as Ex: self.display.voxels.enable_undo() QtGui.QMessageBox.warning(self, "Could not load file", str(Ex)) self.display.build_grids() #self.display.voxels.resize() self.display.voxels.saved() self.display.reset_camera() self.update_caption() self.refresh_actions() self.display.voxels.enable_undo() self.display.refresh() # Registers a tool in the drawing toolbar def register_tool(self, tool, activate = False): self._tools.append(tool) self._tool_group.addAction(tool.get_action()) self.ui.toolbar_drawing.addAction(tool.get_action()) if activate: tool.get_action().setChecked(True) # Send an activation event to the currently selected drawing tool def activate_tool(self, target, mouse_position): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_activate(target, mouse_position) return # Send an alternative activation event to the currently selected tool def activate_tool_alt(self, target, mouse_position): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_activate_alt(target, mouse_position) return # Send drag activation to the current selected drawing tool def drag_tool(self, target, mouse_position): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_drag(target, mouse_position) return # Send an deactivation event to the currently selected drawing tool def deactivate_tool(self, target): action = self._tool_group.checkedAction() if not action: return # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: tool.on_deactivate(target) return # Load and initialise all plugins def load_plugins(self): import plugin_loader # Update the state of the UI actions def refresh_actions(self): num_frames = self.display.voxels.get_frame_count() self.ui.action_anim_delete.setEnabled(num_frames > 1) self.ui.action_anim_previous.setEnabled(num_frames > 1) self.ui.action_anim_next.setEnabled(num_frames > 1) self.ui.action_anim_play.setEnabled(num_frames > 1 and not self._timer.isActive()) self.ui.action_anim_stop.setEnabled(self._timer.isActive()) self.update_caption()
class Controller(QObject): def __init__(self, parent): QObject.__init__(self, parent) self.window = KMainWindow() self.ui = Ui_MainWindow() self.ui.setupUi(self.window) self.createActions() self.createDragMeWidget() self.createScene() self.createToolBox() self.window.resize(700, 500) def createScene(self): self.scene = Scene(self.window) self.ui.view.setScene(self.scene) QObject.connect(self.scene, SIGNAL("selectToolRequested()"), self.slotSelectToolRequested) QObject.connect(self.scene, SIGNAL("selectionChanged()"), self.slotSelectionChanged) self.pixmapItem = PixmapItem() self.pixmapItem.setZValue(-1) self.scene.addItem(self.pixmapItem) def createToolBox(self): self.toolGroup = QActionGroup(self) self.toolGroup.addAction(self.ui.actionSelect) self.toolGroup.addAction(self.ui.actionBubble) self.toolGroup.addAction(self.ui.actionLine) QObject.connect(self.toolGroup, SIGNAL("triggered(QAction*)"), self.slotToolChanged) self.ui.toolBar.addSeparator() self.colorSelector = KColorButton() self.colorSelector.setColor(self.scene.newShapeSettings.pen.color()) QObject.connect(self.colorSelector, SIGNAL("changed(const QColor&)"), self.slotColorChanged) self.ui.toolBar.addWidget(self.colorSelector) self.thicknessSelector = QSpinBox() self.thicknessSelector.setMinimum(1) self.thicknessSelector.setMaximum(16) self.thicknessSelector.setValue(self.scene.newShapeSettings.pen.width()) QObject.connect(self.thicknessSelector, SIGNAL("valueChanged(int)"), self.slotThicknessChanged) self.ui.toolBar.addWidget(self.thicknessSelector) def createDragMeWidget(self): dragMeWidget = DragWidget(self.tr("Drag Me"), self.window) self.ui.mainToolBar.addWidget(dragMeWidget) QObject.connect(dragMeWidget, SIGNAL("dragStarted()"), self.slotDragStarted) def createActions(self): actionOpen = KStandardAction.open(self.open, self) actionSave = KStandardAction.save(self.save, self) actionScreenshot = KAction(self.tr("Screenshot"), self) actionScreenshot.setIcon(KIcon("camera-photo")) QObject.connect(actionScreenshot, SIGNAL("triggered()"), self.grabScreenshot) actionDelete = KAction(self) actionDelete.setShortcut(Qt.Key_Delete) QObject.connect(actionDelete, SIGNAL("triggered()"), self.deleteItems) self.ui.mainToolBar.addAction(actionOpen) self.ui.mainToolBar.addAction(actionSave) self.ui.mainToolBar.addSeparator() self.ui.mainToolBar.addAction(actionScreenshot) self.window.addAction(actionDelete) def slotDragStarted(self): drag = QDrag(self.window) mimeData = QMimeData() variant = QVariant(self.imageFromScene()) mimeData.setImageData(variant) drag.setMimeData(mimeData) drag.start() def selectedShapes(self): return [self.scene.shapeForItem(x) for x in self.scene.selectedItems()] def slotSelectToolRequested(self): self.ui.actionSelect.setChecked(True) self.slotToolChanged(self.ui.actionSelect) def slotSelectionChanged(self): shapes = self.selectedShapes() color = None thickness = None if shapes: color = shapes[0].settings.pen.color() thickness = shapes[0].settings.pen.width() for shape in shapes[1:]: pen = shape.settings.pen if color and pen.color() != color: color = None if thickness and pen.width() != thickness: thickness = None else: color = self.scene.newShapeSettings.pen.color() thickness = self.scene.newShapeSettings.pen.width() if color: self.colorSelector.setColor(color) if thickness: self.thicknessSelector.setValue(thickness) def slotColorChanged(self, color): shapes = self.selectedShapes() if shapes: for shape in shapes: shape.settings.setColor(color) else: self.scene.newShapeSettings.setColor(color) def slotThicknessChanged(self, thickness): shapes = self.selectedShapes() if shapes: for shape in shapes: shape.settings.setThickness(thickness) else: self.scene.newShapeSettings.setThickness(thickness) def show(self): self.window.show() def open(self): name = QFileDialog.getOpenFileName(self.window, self.tr("Open Image")) if name.isEmpty(): return self.load(name) def grabScreenshot(self): pos = self.window.pos() self.window.hide() try: pix = grab.showDialog() if pix is not None: self.setPixmap(pix) finally: self.window.show() self.window.move(pos) KWindowSystem.forceActiveWindow(self.window.winId()) def save(self): name = QFileDialog.getSaveFileName(self.window, self.tr("Save Image as")) if name.isEmpty(): return image = self.imageFromScene() ok = image.save(name) if not ok: KMessageBox.error(self.window, self.tr("Failed to save image as %1").arg(name)); def imageFromScene(self): # Hide elements we don't want to show selection = self.scene.selectedItems() self.scene.clearSelection() self.pixmapItem.setHandlesVisible(False) # Render rect = self.scene.itemsBoundingRect() image = QImage(int(rect.width()), int(rect.height()), QImage.Format_ARGB32) image.fill(Qt.transparent) painter = QPainter(image) painter.setRenderHint(QPainter.Antialiasing) self.scene.render(painter, QRectF(image.rect()), rect) painter.end() # Restore hidden elements for item in selection: item.setSelected(True) self.pixmapItem.setHandlesVisible(True) return image def load(self, fileName): self.setPixmap(QPixmap(fileName)) def setPixmap(self, pix): self.pixmapItem.setPixmap(pix) self.scene.setSceneRect(QRectF(pix.rect())) def slotToolChanged(self, action): toolFromAction = { self.ui.actionBubble: AddBubbleTool, self.ui.actionLine: AddLineTool, } klass = toolFromAction.get(action) if klass: tool = klass(self.scene) else: tool = None self.scene.setTool(tool) def deleteItems(self): for shape in self.selectedShapes(): self.scene.removeShape(shape)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() # Set up the user interface from Designer. self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionVolumetric_Efficiency.triggered.connect(self.openVE) self.ui.actionSpark_Advance.triggered.connect(self.openSA) self.currentport = "" layout = QGridLayout(self.ui.centralwidget) self.ui.centralwidget.setLayout(layout) try: self.vetable = pickle.load(open("tuningve.smv", "rb")) except FileNotFoundError: print("No existing tuning found!") self.vetable = ModelVE() try: self.satable = pickle.load(open("tuningsa.smv", "rb")) except FileNotFoundError: print("No existing tuning found!") self.satable = ModelSA() self.vemodel = TableModel(self.vetable) self.vewindow = TableWindow("Volumetric Efficiency Table") self.vewindow.setModel(self.vemodel) self.samodel = TableModel(self.satable) self.sawindow = TableWindow("Spark Advance Table") self.sawindow.setModel(self.samodel) self.value = 0 self.meters = [] for i in range(0,3): for k in range(0,2): spd = Speedometer("testlol", "units", 0, 100) self.meters.append(spd) layout.addWidget(spd, k, i) ports = self.serial_ports() if len(ports): self.ui.menuSerial_Port.clear() self.actiongroup = QActionGroup(self.ui.menuSerial_Port) for port in ports: action = QAction(port, self.ui.menuSerial_Port) action.setCheckable(True) self.actiongroup.addAction(action) self.actiongroup.actions()[0].setChecked(True) self.setSerialPort() self.ui.menuSerial_Port.addActions(self.actiongroup.actions()) self.actiongroup.triggered.connect(self.setSerialPort) QTimer.singleShot(20, self.increment) def setSerialPort(self): portaction = self.actiongroup.checkedAction() self.currentport = portaction.text() print("set current port to %s" % self.currentport) def increment(self): self.value = (self.value + 1) % 101 for spd in self.meters: spd.setSpeed(self.value) QTimer.singleShot(50, self.increment) def openVE(self): self.vewindow.show() def openSA(self): self.sawindow.show() def closeEvent(self, evt): reply = QMessageBox.question(self, "Preparing to exit", "Save changes before exit?", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: pickle.dump(self.vetable, open("tuningve.smv", "wb")) pickle.dump(self.satable, open("tuningsa.smv", "wb")) evt.accept() def serial_ports(self): if sys.platform.startswith('win'): ports = ['COM' + str(i + 1) for i in range(256)] elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): # this is to exclude your current terminal "/dev/tty" ports = glob.glob('/dev/tty[A-Za-z]*') elif sys.platform.startswith('darwin'): ports = glob.glob('/dev/tty.*') else: raise EnvironmentError('Unsupported platform') result = [] for port in ports: try: s = serial.Serial(port) s.close() result.append(port) print("found %s" % port) except (OSError, serial.SerialException): pass return result
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.dataDir = os.path.dirname(__file__) self.setupQueryList() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.centralWidget().layout().setMargin(0) self.setupQueryListWidget() self.setupFilter() self.setupActions() self.setupJinjaEnv() self.setupFilterWidgets() for obj, signal in [ (self.ui.fromDateEdit, "dateChanged(QDate)"), (self.ui.toDateEdit, "dateChanged(QDate)"), (self.filterLineEdit, "textEdited(QString)"), ]: QObject.connect(obj, SIGNAL(signal), self.updateQuery) QObject.connect(self.ui.queryListWidget, SIGNAL("itemSelectionChanged()"), self.onCurrentQueryChanged) QObject.connect(self.ui.webView, SIGNAL("linkClicked(const QUrl&)"), self.openUrl) self.updateFilterWidgets() self.updateQuery() def setupQueryList(self): self.query = None self.queryList = [] self.queryList.append(queries.DueQuery()) self.queryList.append(queries.ProjectQuery("All Projects")) projectQueryFileName = os.path.expanduser("~/.config/qyok/projects.yaml") if os.path.exists(projectQueryFileName): self.queryList.extend(queries.loadProjectQueries(projectQueryFileName)) self.queryList.append(queries.DoneQuery()) def setupQueryListWidget(self): widget = self.ui.queryListWidget # Create items and associated shortcuts for index, query in enumerate(self.queryList): if index < 12: label = query.name + " (F%d)" % (index + 1) shortcut = QShortcut("F%d" % (index + 1), self) shortcut.setProperty("row", index) shortcut.activated.connect(self.onQueryShortcutActivated) else: label = query.name item = QListWidgetItem(label, widget) # Set widget width to be just a little wider than what is necessary to # show all items fm = QFontMetrics(widget.font()) width = max(fm.width(widget.item(x).text()) for x in range(widget.count())) widget.setFixedWidth(width + 3 * fm.width("m")) # Set item heights to twice the font size so that they are easier to click sh = QSize(width, fm.height() * 2) for idx in range(widget.count()): widget.item(idx).setSizeHint(sh) widget.setCurrentRow(0) def setupFilterWidgets(self): self.ui.fromDateEdit.setDate(QDate.currentDate().addDays(-7)) self.ui.toDateEdit.setDate(QDate.currentDate()) pal = QPalette(self) bg = pal.window().color() gradient = QLinearGradient(0, 0, 0, self.ui.doneFrame.height()) gradient.setColorAt(0, bg.darker(150)) gradient.setColorAt(0.2, bg.darker(120)) pal.setBrush(QPalette.Window, QBrush(gradient)) pal.setBrush(QPalette.Button, bg) self.ui.doneFrame.setPalette(pal) def setupActions(self): self.ui.newTaskAction.setIcon(QIcon.fromTheme("document-new")) QObject.connect(self.ui.newTaskAction, SIGNAL("triggered()"), self.addTask) actions = [self.ui.newTaskAction] for action in actions: shortcut = action.shortcut() if not shortcut.isEmpty(): toolTip = self.tr("%1 (%2)", "%1 is the tooltip text, %2 is the action shortcut") \ .arg(action.toolTip()) \ .arg(shortcut.toString()) action.setToolTip(toolTip) def setupFilter(self): self.filterLineEdit = QLineEdit() self.filterLineEdit.setPlaceholderText(self.tr("Filter (Ctrl+F)")) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.ui.toolBar.addWidget(spacer) self.ui.toolBar.addWidget(self.filterLineEdit) shortcut = QShortcut(self) shortcut.setKey(Qt.CTRL + Qt.Key_F) shortcut.activated.connect(self.filterLineEdit.setFocus) def setupJinjaEnv(self): self.jinjaEnv = Environment() self.jinjaEnv.filters["dueDateCssClass"] = queries.dueDateCssClass self.jinjaEnv.filters["formatDate"] = queries.formatDate self.jinjaEnv.filters["formatDueDate"] = queries.formatDueDate self.jinjaEnv.filters["markdown"] = markdown.markdown tmplDir = os.path.join(self.dataDir, "templates") self.jinjaEnv.loader = FileSystemLoader(tmplDir) def onQueryShortcutActivated(self): row, ok = self.sender().property("row").toInt() if ok: self.ui.queryListWidget.setCurrentRow(row) def onCurrentQueryChanged(self): row = self.ui.queryListWidget.currentRow() query = self.queryList[row] defaultFilters = [] if query.defaultProjectName is not None: defaultFilters.append(query.defaultProjectName) defaultFilters.extend(["@" + x for x in query.defaultKeywordFilters]) self.filterLineEdit.setText(" ".join(defaultFilters)) self.updateQuery() self.updateFilterWidgets() def updateFilterWidgets(self): self.ui.doneFrame.setVisible(isinstance(self.query, queries.DoneQuery)) def generateHtml(self): args = self.query.run() args["palette"] = CssPalette(self.palette()) tmpl = self.jinjaEnv.get_template(self.query.templateName) return tmpl.render(args) def updateView(self): page = WebPage(logger=None, parent=self) page.setLinkDelegationPolicy(QWebPage.DelegateAllLinks) page.mainFrame().addToJavaScriptWindowObject("qtWindow", self) self.ui.webView.setPage(page) html = self.generateHtml() # baseUrl must end with a trailing '/' otherwise QWebView won't be able # to load files from there baseUrl = QUrl.fromLocalFile(os.path.join(self.dataDir, "static/")) self.ui.webView.setHtml(html, baseUrl) def updateQuery(self): row = self.ui.queryListWidget.currentRow() self.query = self.queryList[row] # Project projectName, keywordFilters = parseutils.extractKeywords(unicode(self.filterLineEdit.text())) self.query.projectName = projectName self.query.keywordFilters = keywordFilters # Status if isinstance(self.query, queries.DoneQuery): minDate = datetimeFromQDate(self.ui.fromDateEdit.date()) maxDate = datetimeFromQDate(self.ui.toDateEdit.date()) if minDate is not None and maxDate is not None and maxDate < minDate: minDate, maxDate = maxDate, minDate if maxDate is not None: maxDate += timedelta(1) self.query.minDate = minDate self.query.maxDate = maxDate self.updateView() def updateViewAndKeepPosition(self): frame = self.ui.webView.page().currentFrame() pos = frame.scrollPosition() self.updateView() frame.setScrollPosition(pos) def openUrl(self, url): QDesktopServices.openUrl(url) def addTask(self): dlg = AddTaskDialog(task=None, parent=self) if dlg.exec_() == QDialog.Accepted: self.updateViewAndKeepPosition() def editTask(self, taskId): task = Task.get(taskId) dlg = AddTaskDialog(task, self) if dlg.exec_() == QDialog.Accepted: self.updateViewAndKeepPosition() def removeTask(self, taskId): Task.delete(taskId) self.updateViewAndKeepPosition() @pyqtSlot(int, str) def setTaskStatus(self, taskId, status): task = Task.get(taskId) status = unicode(status) task.status = status if status == "done": task.doneDate = datetime.now() @pyqtSlot(int, str) def showTaskPopup(self, taskId, buttonId): frame = self.ui.webView.page().mainFrame() element = frame.findFirstElement(buttonId) assert element rect = element.geometry() topLeft = self.ui.webView.mapToGlobal(rect.topLeft() - frame.scrollPosition()) menu = QMenu() edit = menu.addAction(self.tr("Edit")) rmMenu = menu.addMenu(self.tr("Remove")) remove = rmMenu.addAction(self.tr("Do It")) menuHeight = menu.sizeHint().height() screenHeight = QApplication.desktop().screenGeometry(self).height() if topLeft.y() + menuHeight < screenHeight: pos = QPoint(topLeft.x(), topLeft.y() + rect.height()) else: pos = QPoint(topLeft.x(), topLeft.y() - menuHeight) action = menu.exec_(pos) if action == edit: self.editTask(taskId) elif action == remove: self.removeTask(taskId)
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): # Initialise the UI self.display = None super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Current file self._filename = None self._filetype = None self._last_file_handler = None # Importers / Exporters self._file_handlers = [] # Update our window caption self._caption = "Zoxel" # Our global state + user plugins if platform.system() == "Windows": appdata = os.path.expandvars("%APPDATA%") elif platform.system() == "Darwin": appdata = os.path.expanduser("~/Library/Application Support") else: appdata = os.path.expanduser("~/.local/share") self.user_plugins_path = os.path.join(appdata, "Zoxel", "plugins") if not os.path.isdir(self.user_plugins_path): os.makedirs(self.user_plugins_path, 16877) QtCore.QCoreApplication.setOrganizationName("Zoxel") QtCore.QCoreApplication.setApplicationName("Zoxel") QtCore.QSettings.setDefaultFormat(QtCore.QSettings.IniFormat) QtCore.QSettings.setPath(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, appdata) self.settings = QtCore.QSettings() self.state = {} # Our animation timer self._timer = QtCore.QTimer(self) self.connect(self._timer, QtCore.SIGNAL("timeout()"), self.on_animation_tick) self._anim_speed = 200 # Load our state if possible self.load_state() # Create our GL Widget try: glw = GLWidget(self.ui.glparent) self.ui.glparent.layout().addWidget(glw) self.display = glw except Exception as E: QtGui.QMessageBox.warning(self, "Initialisation Failed", str(E)) exit(1) # Load default model dimensions width = self.get_setting("default_model_width") height = self.get_setting("default_model_height") depth = self.get_setting("default_model_depth") if width: self.resize_voxels(width, height, depth) # Resize is detected as a change, discard changes self.display.voxels.saved() # Create our palette widget voxels = PaletteWidget(self.ui.palette, RGBvalue=self.ui.paletteRGBvalue) self.ui.palette.layout().addWidget(voxels) self.color_palette = voxels # More UI state value = self.get_setting("display_axis_grids") if value is not None: self.ui.action_axis_grids.setChecked(value) self.display.axis_grids = value value = self.get_setting("background_color") if value is not None: self.display.background = QtGui.QColor.fromRgb(*value) value = self.get_setting("voxel_edges") if value is not None: self.display.voxel_edges = value self.ui.action_voxel_edges.setChecked(value) else: self.ui.action_voxel_edges.setChecked(self.display.voxel_edges) value = self.get_setting("occlusion") if value is None: value = True self.display.voxels.occlusion = value self.ui.action_occlusion.setChecked(value) # Connect some signals if self.display: self.display.voxels.notify = self.on_data_changed self.display.mouse_click_event.connect(self.on_tool_mouse_click) self.display.start_drag_event.connect(self.on_tool_drag_start) self.display.end_drag_event.connect(self.on_tool_drag_end) self.display.drag_event.connect(self.on_tool_drag) if self.color_palette: self.color_palette.changed.connect(self.on_color_changed) # Initialise our tools self._tool_group = QtGui.QActionGroup(self.ui.toolbar_drawing) self._tools = [] self._tools_priorities = {} # Setup window self.update_caption() self.refresh_actions() self.display.ready = True # Update Check try: latest_tag = urllib.urlopen("https://github.com/chrmoritz/zoxel/releases/latest").geturl() if not latest_tag.endswith(ZOXEL_TAG): responce = QtGui.QMessageBox.question(self, "Outdated Zoxel version", "A new version of Zoxel is available! Do you want to update now?", buttons=(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), defaultButton=QtGui.QMessageBox.Yes) if responce == QtGui.QMessageBox.Yes: webbrowser.open(latest_tag, 2) sys.exit(0) except IOError: pass def on_animation_tick(self): self.on_action_anim_next_triggered() @QtCore.Slot() def on_action_about_triggered(self): dialog = AboutDialog(self) if dialog.exec_(): pass @QtCore.Slot() def on_action_axis_grids_triggered(self): self.display.axis_grids = self.ui.action_axis_grids.isChecked() self.set_setting("display_axis_grids", self.display.axis_grids) @QtCore.Slot() def on_action_voxel_edges_triggered(self): self.display.voxel_edges = self.ui.action_voxel_edges.isChecked() self.set_setting("voxel_edges", self.display.voxel_edges) @QtCore.Slot() def on_action_zoom_in_triggered(self): self.display.zoom_in() @QtCore.Slot() def on_action_zoom_out_triggered(self): self.display.zoom_out() @QtCore.Slot() def on_action_new_triggered(self): if self.display.voxels.changed: if not self.confirm_save(): return # Clear our data self._filename = None self._filetype = None self.display.clear() self.display.voxels.saved() self.update_caption() self.refresh_actions() @QtCore.Slot() def on_action_wireframe_triggered(self): self.display.wireframe = self.ui.action_wireframe.isChecked() self.set_setting("display_wireframe", self.display.wireframe) @QtCore.Slot() def on_action_save_triggered(self): # Save self.save() @QtCore.Slot() def on_action_saveas_triggered(self): # Save self.save(True) @QtCore.Slot() def on_action_open_triggered(self): # Load self.load() @QtCore.Slot() def on_action_undo_triggered(self): # Undo self.display.voxels.undo() self.display.refresh() @QtCore.Slot() def on_action_redo_triggered(self): # Redo self.display.voxels.redo() self.display.refresh() @QtCore.Slot() def on_action_resize_triggered(self): # Resize model dimensions dialog = ResizeDialog(self) dialog.ui.width.setValue(self.display.voxels.width) dialog.ui.height.setValue(self.display.voxels.height) dialog.ui.depth.setValue(self.display.voxels.depth) if dialog.exec_(): width = dialog.ui.width.value() height = dialog.ui.height.value() depth = dialog.ui.depth.value() self.resize_voxels(width, height, depth) def resize_voxels(self, width, height, depth): new_width_scale = float(width) / self.display.voxels.width new_height_scale = float(height) / self.display.voxels.height new_depth_scale = float(depth) / self.display.voxels.depth self.display.voxels.resize(width, height, depth) self.display.grids.scale_offsets(new_width_scale, new_height_scale, new_depth_scale) self.display.refresh() # Remember these dimensions self.set_setting("default_model_width", width) self.set_setting("default_model_height", height) self.set_setting("default_model_depth", depth) @QtCore.Slot() def on_action_reset_camera_triggered(self): self.display.reset_camera() @QtCore.Slot() def on_action_occlusion_triggered(self): self.display.voxels.occlusion = self.ui.action_occlusion.isChecked() self.set_setting("occlusion", self.display.voxels.occlusion) self.display.refresh() @QtCore.Slot() def on_action_background_triggered(self): # Choose a background color color = QtGui.QColorDialog.getColor() if color.isValid(): self.display.background = color color = (color.red(), color.green(), color.blue()) self.set_setting("background_color", color) @QtCore.Slot() def on_action_anim_add_triggered(self): value, res = QtGui.QInputDialog.getInt(self, "Add frame", "Add new frame after:", self.display.voxels.get_frame_number() + 1, 1, self.display.voxels.get_frame_count()) if res: self.display.voxels.insert_frame(value, True) self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_add_empty_triggered(self): value, res = QtGui.QInputDialog.getInt(self, "Add frame", "Add new frame after:", self.display.voxels.get_frame_number() + 1, 1, self.display.voxels.get_frame_count()) if res: self.display.voxels.insert_frame(value, False) self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_copy_triggered(self): value, res = QtGui.QInputDialog.getInt(self, "Copy frame", "Replace current frame with:", 1, 1, self.display.voxels.get_frame_count()) if res: self.display.voxels.copy_to_current(value) self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_delete_triggered(self): ret = QtGui.QMessageBox.question(self, "Zoxel", "Do you really want to delete this frame?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) if ret == QtGui.QMessageBox.Yes: self.display.voxels.delete_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_play_triggered(self): self._timer.start(self._anim_speed) self.refresh_actions() @QtCore.Slot() def on_action_anim_stop_triggered(self): self._timer.stop() self.refresh_actions() @QtCore.Slot() def on_action_anim_next_triggered(self): self.display.voxels.select_next_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_previous_triggered(self): self.display.voxels.select_previous_frame() self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_anim_settings_triggered(self): pass @QtCore.Slot() def on_action_rotate_x_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.X_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_y_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Y_AXIS) self.display.refresh() @QtCore.Slot() def on_action_rotate_z_triggered(self): self.display.voxels.rotate_about_axis(self.display.voxels.Z_AXIS) self.display.refresh() @QtCore.Slot() def on_action_mirror_x_triggered(self): self.display.voxels.mirror_in_axis(self.display.voxels.X_AXIS) self.display.refresh() @QtCore.Slot() def on_action_mirror_y_triggered(self): self.display.voxels.mirror_in_axis(self.display.voxels.Y_AXIS) self.display.refresh() @QtCore.Slot() def on_action_mirror_z_triggered(self): self.display.voxels.mirror_in_axis(self.display.voxels.Z_AXIS) self.display.refresh() @QtCore.Slot() def on_action_voxel_color_triggered(self): # Choose a voxel color color = QtGui.QColorDialog.getColor() if color.isValid(): self.color_palette.color = color @QtCore.Slot() def on_paletteRGBvalue_editingFinished(self): s = self.ui.paletteRGBvalue.text() i = s.find('rgb(') if i >= 0: c = map(int, s[i+4:s.find(')')].split(',')) color = QtGui.QColor(c[0], c[1], c[2]) else: color = QtGui.QColor() color.setNamedColor(s) if color.isValid(): self.color_palette.color = color @QtCore.Slot() def on_action_export_image_triggered(self): self.display.paintGL() png = QtGui.QPixmap(self.display.grabFrameBuffer()) choices = "PNG Image (*.png);;JPEG Image (*.jpg)" # Grab our default location directory = self.get_setting("default_directory") # grab a filename filename, filetype = QtGui.QFileDialog.getSaveFileName(self, caption="Export Image As", filter=choices, dir=directory) if not filename: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Save the PNG png.save(filename, filetype.split()[0]) @QtCore.Slot() def on_action_export_troxel_triggered(self): from base64 import b64encode from struct import pack data = [self.display.voxels.width, self.display.voxels.height, self.display.voxels.depth, 0, 85, 0, 0] vox = [] for z in xrange(self.display.voxels.depth - 1, -1, -1): for y in xrange(self.display.voxels.height): for x in xrange(self.display.voxels.width - 1, -1, -1): v = self.display.voxels.get(x, y, z) if v: vox.append(((v & 0xff000000) >> 24, (v & 0xff0000) >> 16, (v & 0xff00) >> 8)) else: vox.append(None) rcolors = {} for v in vox: if v: hex = v[2] + 256 * v[1] + 65536 * v[0] data.extend((0, v[0], v[1], v[2], 255)) rcolors[hex] = (len(data) - 7) // 5 data[5] = (len(data) - 7) // 1280 short = data[5] == 0 data[6] = (len(data) - 7) // 5 % 256 i = 0 length = len(vox) while i < length: r = 1 while r < 129: if (i + r < length) and (vox[i + r - 1] == vox[i + r]): r += 1 else: break if r > 1: data.append(126 + r) if vox[i]: index = rcolors[vox[i][2] + 256 * vox[i][1] + 65536 * vox[i][0]] if short: data.append(index) else: data.extend((index // 256, index % 256)) else: if short: data.append(0) else: data.extend((0, 0)) i += r webbrowser.open("https://chrmoritz.github.io/Troxel/#m=" + b64encode(pack('B' * len(data), *data)), 2) @QtCore.Slot() def on_action_copy_selection_to_frame_triggered(self): target_frame, res = QtGui.QInputDialog.getInt(self, "Copy selection", "Copy selection to frame:", 1, 1, self.display.voxels.get_frame_count()) if res: target_frame -= 1 original_frame = self.display.voxels.get_frame_number() original_selection = copy.deepcopy(self.display.voxels._selection) if target_frame != original_frame: stamp = [] for x, y, z in self.display.voxels._selection: col = self.display.voxels.get(x, y, z) stamp.append((x, y, z, col)) self.display.voxels.select_frame(target_frame) btns = QtGui.QMessageBox.StandardButton.Abort | QtGui.QMessageBox.StandardButton.Ignore if (self.display.voxels.is_free(stamp) or QtGui.QMessageBox.question(self, "Copy selection", "This would override voxel data in the targeted frame!", btns) == QtGui.QMessageBox.Ignore): for x, y, z, col in stamp: self.display.voxels.set(x, y, z, col) self.display.voxels.select_frame(original_frame) self.display.voxels._selection = original_selection self.display.refresh() self.refresh_actions() @QtCore.Slot() def on_action_reload_plugins_triggered(self): # reset plugin state self.ui.toolbar_drawing.clear() for a in self._tool_group.actions(): self._tool_group.removeAction(a) self._tools = [] self._tools_priorities.clear() self._file_handlers = [] self._last_file_handler = None # reload default plugins from plugins import __all__ as plugins from sys import modules for p in plugins: reload(modules["plugins." + p]) # reload user plugins from imp import load_source for p in os.listdir(self.user_plugins_path): if p.endswith(".py"): load_source(os.path.splitext(p)[0], os.path.join(self.user_plugins_path, p)) @QtCore.Slot() def on_action_manage_plugins_triggered(self): webbrowser.open('file://' + self.user_plugins_path) def on_tool_mouse_click(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_mouse_click(data) def on_tool_drag_start(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_drag_start(data) def on_tool_drag(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_drag(data) def on_tool_drag_end(self): tool = self.get_active_tool() if not tool: return data = self.display.target tool.on_drag_end(data) # Confirm if user wants to save before doing something drastic. # returns True if we should continue def confirm_save(self): responce = QtGui.QMessageBox.question(self, "Save changes?", "Save changes before discarding?", buttons=(QtGui.QMessageBox.Save | QtGui.QMessageBox.Cancel | QtGui.QMessageBox.No)) if responce == QtGui.QMessageBox.StandardButton.Save: if not self.save(): return False elif responce == QtGui.QMessageBox.StandardButton.Cancel: return False return True # Voxel data changed signal handler def on_data_changed(self): self.update_caption() self.refresh_actions() # Color selection changed handler def on_color_changed(self): self.display.voxel_color = self.color_palette.color # Return a section of our internal config def get_setting(self, name): if name in self.state: return self.state[name] return None # Set some config. Value should be a serialisable type def set_setting(self, name, value): self.state[name] = value def closeEvent(self, event): # Save state self.save_state() if self.display.voxels.changed: if not self.confirm_save(): event.ignore() return event.accept() # Save our state def save_state(self): try: state = json.dumps(self.state) self.settings.setValue("system/state", state) except Exception as E: # XXX Fail. Never displays because we're on our way out error = QtGui.QErrorMessage(self) error.showMessage(str(E)) # Load our state def load_state(self): try: state = self.settings.value("system/state") if state: self.state = json.loads(state) except Exception as E: error = QtGui.QErrorMessage(self) error.showMessage(str(E)) # Update the window caption to reflect the current state def update_caption(self): caption = "Zoxel" if self._filename: caption += " - [%s]" % self._filename else: caption += " - [Unsaved model]" if self.display and self.display.voxels.changed: caption += " *" numframes = self.display.voxels.get_frame_count() frame = self.display.voxels.get_frame_number() + 1 if numframes > 1: caption += " - Frame {0} of {1}".format(frame, numframes) if caption != self._caption: self.setWindowTitle(caption) self._caption = caption # Save the current data def save(self, newfile=False): # Find the handlers that support saving handlers = [x for x in self._file_handlers if hasattr(x, 'save')] saved = False filename = self._filename filetype = self._filetype handler = self._last_file_handler # Build list of available types choices = [] for exporter in handlers: choices.append("%s (%s)" % (exporter.description, exporter.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename if we need one if newfile or not filename: filename, filetype = QtGui.QFileDialog.getSaveFileName(self, caption="Save As", filter=choices, dir=directory, selectedFilter="Zoxel Files (*.zox)") if not filename: return handler = None # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler if we need to if not handler: for exporter in handlers: ourtype = "%s (%s)" % (exporter.description, exporter.filetype) if filetype == ourtype: handler = exporter # Call the save handler try: handler.save(filename) saved = True except Exception as Ex: QtGui.QMessageBox.warning(self, "Save Failed", str(Ex)) # If we saved, clear edited state if saved: self._filename = filename self._filetype = filetype self._last_file_handler = handler self.display.voxels.saved() self.update_caption() self.refresh_actions() return saved # Registers an file handler (importer/exporter) with the system def register_file_handler(self, handler): self._file_handlers.append(handler) # load a file def load(self): # If we have changes, perhaps we should save? if self.display.voxels.changed: if not self.confirm_save(): return # Find the handlers that support loading handler = None handlers = [x for x in self._file_handlers if hasattr(x, 'load')] # Build list of types we can load choices = ["All Files (*)"] for importer in handlers: choices.append("%s (%s)" % (importer.description, importer.filetype)) choices = ";;".join(choices) # Grab our default location directory = self.get_setting("default_directory") # Get a filename filename, filetype = QtGui.QFileDialog.getOpenFileName(self, caption="Open file", filter=choices, dir=directory, selectedFilter="All Files (*)") if not filename: return if filetype == "All Files (*)": filetype = None for importer in handlers: if filename.endswith(importer.filetype[1:]): filetype = "%s (%s)" % (importer.description, importer.filetype) break if filetype is None: return # Remember the location directory = os.path.dirname(filename) self.set_setting("default_directory", directory) # Find the handler for importer in handlers: ourtype = "%s (%s)" % (importer.description, importer.filetype) if filetype == ourtype: handler = importer self._last_file_handler = handler # Load the file self.display.clear() self.display.voxels.disable_undo() self._filename = None try: handler.load(filename) self._filename = filename self._filetype = filetype except Exception as Ex: self.display.voxels.enable_undo() QtGui.QMessageBox.warning(self, "Could not load file", str(Ex)) self.display.build_grids() # self.display.voxels.resize() self.display.voxels.saved() self.display.reset_camera() self.update_caption() self.refresh_actions() self.display.voxels.enable_undo() self.display.refresh() # Registers a tool in the drawing toolbar def register_tool(self, tool, activate=False): self._tools.append(tool) self._tool_group.addAction(tool.get_action()) before = None bp = 9223372036854775807 for p, action in self._tools_priorities.iteritems(): if p > tool.priority and p < bp: bp = p before = action self.ui.toolbar_drawing.insertAction(before, tool.get_action()) self._tools_priorities[tool.priority] = tool.get_action() if activate: tool.get_action().setChecked(True) # Return the active tool def get_active_tool(self): action = self._tool_group.checkedAction() if not action: return None # Find who owns this action and activate for tool in self._tools: if tool.get_action() is action: return tool return None # Load and initialise all plugins def load_plugins(self): # load default plugins from plugins import __all__ as plugins from importlib import import_module for p in plugins: import_module('plugins.' + p) # load user plugins from imp import load_source for p in os.listdir(self.user_plugins_path): if p.endswith(".py"): load_source(os.path.splitext(p)[0], os.path.join(self.user_plugins_path, p)) # Update the state of the UI actions def refresh_actions(self): num_frames = self.display.voxels.get_frame_count() self.ui.action_anim_delete.setEnabled(num_frames > 1) self.ui.action_anim_previous.setEnabled(num_frames > 1) self.ui.action_anim_next.setEnabled(num_frames > 1) self.ui.action_anim_play.setEnabled(num_frames > 1 and not self._timer.isActive()) self.ui.action_anim_stop.setEnabled(self._timer.isActive()) self.update_caption()
class MainWindow(QMainWindow): def __init__(self, filename=None, parent=None): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) if filename is not None: self.initCommandModel(load_commands(filename)) else: self.initCommandModel([]) self.ui.action_Load.triggered.connect(self.loadCommands) self.ui.action_Save.triggered.connect(self.saveCommands) self.ui.action_Add.triggered.connect(self.addCommand) self.ui.action_Edit.triggered.connect(self.editCommand) self.ui.action_Remove.triggered.connect(self.removeCommand) self.ui.action_Apply.triggered.connect(self.render) self.ui.action_About_BashMate.triggered.connect(self.about) self.ui.commandView.activated.connect(self.changeDetailsView) self.ui.applyButton.clicked.connect(self.render) self.ui.filterEdit.textChanged.connect(self.filter_changed) #self.ui.addButton.clicked.connect(self.addCommand) #self.ui.editButton.clicked.connect(self.editCommand) #self.ui.removeButton.clicked.connect(self.removeCommand) #self.ui.commandView.model().dataChanged.connect(self.change) #self.ui.commandView.activated.connect(self.activate) def initCommandModel(self, commands=[]): self.cmdmodel = CommandModel(commands, self) proxymodel= QSortFilterProxyModel(self) proxymodel.setSourceModel(self.cmdmodel) proxymodel.setFilterKeyColumn(1) self.ui.commandView.setModel(proxymodel) def loadCommands(self): filename = unicode(QFileDialog.getOpenFileName(self, u"Load CommandTemplate File", ".", u"CommandTemplate File (*.json)")) self.initCommandModel(load_commands(filename)) def saveCommands(self): filename = unicode(QFileDialog.getSaveFileName(self, u"Save CommandTemplate File", ".", u"CommandTemplate File (*.json)")) dump_commands(self.cmdmodel.commands, filename) def changeDetailsView(self, index): command = self.cmdmodel.currentCommand(index) self.ui.commandBrowser.setText(command.command) self.ui.infoBrowser.setText(command.info) self.ui.bindView.setModel(BindModel(command, self)) def render(self): command = self.cmdmodel.currentCommand( self.ui.commandView.currentIndex()) bindings = self.ui.bindView.model().bindings self.ui.cmdEdit.setText(command.render(**bindings)) def addCommand(self): dialog = CommandDialog(parent=self) if dialog.exec_() == QDialog.Accepted: self.cmdmodel.addCommand(dialog.command) def editCommand(self): command = self.cmdmodel.currentCommand( self.ui.commandView.currentIndex()) dialog = CommandDialog(command, parent=self) if dialog.exec_() == QDialog.Accepted: commands = self.cmdmodel.commands commands[commands.index(command)] = dialog.command def removeCommand(self): self.cmdmodel.removeCommand(self.ui.commandView.currentIndex()) def filter_changed(self, pattern): regExp = QRegExp(pattern, Qt.CaseInsensitive) self.ui.commandView.model().setFilterRegExp(regExp) def change(self, left, right): print self.ui.commandView.currentIndex().row() self.changeDetailsView(self.ui.commandView.currentIndex()) def about(self): box = QMessageBox() box.setText(u"BashMate - the beginner firendly Shell Snippet Manager") box.setInformativeText( u"(c) 2011 by Christian Hausknecht <*****@*****.**>") box.exec_()
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionAdd_camera.triggered.connect(self.handle_add_camera_triggered) self.ui.actionOpen_dataset.triggered.connect(self.handle_open_dataset_triggered) self.ui.actionSave_dataset.triggered.connect(self.handle_save_dataset_triggered) self.ui.actionClose_dataset.triggered.connect(self.handle_close_dataset_triggered) self.ui.actionExport_to_JSON.triggered.connect(self.handle_export_to_json_triggered) self.startup_page = QWidget() self.startup_page_ui = Ui_StartupPage() self.startup_page_ui.setupUi(self.startup_page) self.startup_page_ui.addCamera_button.setDefaultAction(self.ui.actionAdd_camera) self.startup_page_ui.openDataset_button.setDefaultAction(self.ui.actionOpen_dataset) self.startup_page_ui.openDataset_button.setMenu(None) self.startup_page_ui.openDataset_button.setArrowType(Qt.NoArrow) self.startup_page_ui.label_recent_datasets_image_placeholder.setPixmap( QPixmap(':/icons/document-open-recent.svg')) self.startup_page_ui.label_recent_cameras_image_placeholder.setPixmap( QPixmap(':/icons/document-open-recent.svg')) self.startup_dataset_buttons: List[QToolButton] = [] self.startup_camera_buttons: List[QToolButton] = [] self.state = self.get_config_state() self.recent_datasets: List[Path] = [] self.recent_datasets_menu = QMenu() self.recent_datasets_menu.setToolTipsVisible(True) self.recent_dataset_qactions = [] for ds in self.state['recent_datasets']: self.add_dataset_entry_to_recent(Path(ds)) if len(self.recent_datasets) == 0: self.startup_page_ui.verticalLayout_recentDatasets.addWidget(self.startup_page_ui.label_noRecentDatasets) self.startup_page_ui.label_noRecentDatasets.setAlignment(Qt.AlignHCenter) self.startup_page_ui.label_noRecentDatasets.show() self.recent_datasets_menu.triggered.connect(lambda action: self.open_dataset(Path(action.toolTip()))) self.ui.actionOpen_dataset.setMenu(self.recent_datasets_menu) self.recent_cameras: List[Path] = [] self.recent_cameras_menu = QMenu() self.recent_cameras_menu.setToolTipsVisible(True) self.recent_cameras_qactions: Dict[str, QAction] = {} for cam in self.state['recent_cameras']: self.add_camera_entry_to_recent(Path(cam)) if len(self.recent_cameras) == 0: self.startup_page_ui.verticalLayout_recentCameras.addWidget(self.startup_page_ui.label_noRecentCameras) self.startup_page_ui.label_noRecentCameras.setAlignment(Qt.AlignHCenter) self.startup_page_ui.label_noRecentCameras.show() self.recent_cameras_menu.triggered.connect(self.handle_add_recent_camera_triggered) self.ui.actionAdd_camera.setMenu(self.recent_cameras_menu) self.dataset = Dataset() self.processing_widget = CameraProcessingWidget() self.processing_widget.set_dataset(self.dataset) self.processing_widget.camera_loaded.connect(self.handle_camera_added) self.processing_widget.processing_started.connect(self.show_progress_bar) self.processing_widget.processing_updated.connect(self.update_progress_bar) self.processing_widget.processing_stopped.connect(self.hide_progress_bar) self.processing_widget.stick_verification_needed.connect(self.notify_user) self.processing_widget.no_cameras_open.connect(self.handle_no_cameras_open) self.ui.stackedWidget.removeWidget(self.ui.page) self.ui.stackedWidget.removeWidget(self.ui.page_2) self.ui.stackedWidget.addWidget(self.startup_page) self.ui.stackedWidget.addWidget(self.processing_widget) self.ui.stackedWidget.setCurrentIndex(0) self.setCentralWidget(self.ui.stackedWidget) self.ui.toolBar.hide() self.progress_bar = QProgressBar() self.progress_bar.hide() skipped_q_indicator = QPixmap(24, 24) skipped_q_indicator.fill(QColor(150, 150, 150)) skipped_label = QLabel() skipped_label.setPixmap(skipped_q_indicator) bad_q_indicator = QPixmap(24, 24) bad_q_indicator.fill(QColor(200, 0, 0)) bad_label = QLabel() bad_label.setPixmap(bad_q_indicator) ok_q_indicator = QPixmap(24, 24) ok_q_indicator.fill(QColor(200, 100, 0)) ok_label = QLabel() ok_label.setPixmap(ok_q_indicator) good_q_indicator = QPixmap(24, 24) good_q_indicator.fill(QColor(100, 200, 0)) good_label = QLabel() good_label.setPixmap(good_q_indicator) status_box = QHBoxLayout() indicator_box = QHBoxLayout() self.statusBar().hide() indicator_box.addWidget(QLabel("Stick visibility:\t")) indicator_box.addWidget(skipped_label) indicator_box.addWidget(QLabel(" Skipped ")) indicator_box.addWidget(bad_label) indicator_box.addWidget(QLabel(" Bad ")) indicator_box.addWidget(ok_label) indicator_box.addWidget(QLabel(" OK ")) indicator_box.addWidget(good_label) indicator_box.addWidget(QLabel(" Good ")) status_box.addItem(indicator_box) status_box.addWidget(self.progress_bar) status_box.setAlignment(indicator_box, Qt.AlignLeft) status_box.setSpacing(100) status_widget = QWidget() status_widget.setLayout(status_box) self.statusBar().addPermanentWidget(status_widget, 1) self.progress_bar.setFormat("%v / %m") self.sys_tray = QSystemTrayIcon(QIcon(':icons/snowflake.svg')) self.sys_tray.show() self.thread_pool = QThreadPool() def handle_save_dataset_triggered(self, checked: bool): if self.dataset.path == Path("."): file_dialog = QFileDialog(self) file_dialog.setWindowTitle("Save dataset") file_dialog.setFileMode(QFileDialog.AnyFile) file_dialog.setNameFilter("*.json") file_dialog.setAcceptMode(QFileDialog.AcceptSave) if file_dialog.exec_(): file_path = Path(file_dialog.selectedFiles()[0]) self.dataset.save_as(file_path) self.add_dataset_entry_to_recent(file_path) self.save_state() else: self.dataset.save() def handle_add_camera_triggered(self, checked: bool): file_dialog = QFileDialog(self) file_dialog.setFileMode(QFileDialog.Directory) if file_dialog.exec_(): if self.dataset.add_camera(Path(file_dialog.selectedFiles()[0])): self.add_camera_entry_to_recent(Path(file_dialog.selectedFiles()[0])) def handle_open_dataset_triggered(self, checked: bool): file_dialog = QFileDialog(self) file_dialog.setNameFilter("*.json") file_dialog.setFileMode(QFileDialog.AnyFile) file_dialog.setWindowTitle("Open dataset file") if file_dialog.exec_(): file_path = Path(file_dialog.selectedFiles()[0]) if not self.open_dataset(file_path): return self.setWindowTitle(str(self.dataset.path)) self.add_dataset_entry_to_recent(file_path) self.ui.actionOpen_dataset.setMenu(self.recent_datasets_menu) self.save_state() def handle_add_recent_camera_triggered(self, action: QAction): if self.dataset.add_camera(Path(action.toolTip())): self.add_camera_entry_to_recent(Path(action.toolTip())) else: QMessageBox.critical(self, "Failed to open camera folder", f'Could not open {action.toolTip()}') def connect_dataset_signals(self): self.dataset.camera_added.connect(self.handle_camera_added) def save_state(self): try: with open(Path(sys.argv[0]).parent / 'state.json', 'w') as f: self.state['recent_datasets'] = list(reversed(list(map(lambda p: str(p), self.recent_datasets)))) self.state['recent_cameras'] = list(reversed(list(map(lambda p: str(p), self.recent_cameras)))) json.dump(self.state, f) except PermissionError: pass def add_camera_entry_to_recent(self, p: Path): if not self.startup_page_ui.label_noRecentCameras.isHidden(): self.startup_page_ui.label_noRecentCameras.hide() self.startup_page_ui.verticalLayout_recentCameras.removeWidget(self.startup_page_ui.label_noRecentCameras) if p not in self.recent_cameras: self.recent_cameras.insert(0, p) action = QAction(str(p.name)) action.setToolTip(str(p)) self.recent_cameras_qactions[str(p)] = action if len(self.recent_cameras_menu.actions()) > 0: self.recent_cameras_menu.insertAction(self.recent_cameras_menu.actions()[0], action) else: self.recent_cameras_menu.addAction(action) btn = QToolButton() btn.setDefaultAction(action) btn.setStyleSheet('font-size: 12pt') btn.setText(str(p.name)) btn.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.startup_camera_buttons.insert(0, btn) self.startup_page_ui.label_noRecentCameras.hide() self.startup_page_ui.verticalLayout_recentCameras.insertWidget(0, btn) else: action_idx = self.recent_cameras_menu.actions().index(self.recent_cameras_qactions[str(p)]) btn = self.startup_page_ui.verticalLayout_recentCameras.itemAt(action_idx).widget() #self.startup_page_ui.verticalLayout_recentCameras.removeItem(btn) self.startup_page_ui.verticalLayout_recentCameras.removeWidget(btn) self.startup_page_ui.verticalLayout_recentCameras.insertWidget(0, btn) self.recent_cameras.remove(p) self.recent_cameras.insert(0, p) self.recent_cameras_menu.clear() for i in range(self.startup_page_ui.verticalLayout_recentCameras.count()): btn: QToolButton = self.startup_page_ui.verticalLayout_recentCameras.itemAt(i).widget() self.recent_cameras_menu.addAction(btn.defaultAction()) if len(self.recent_cameras) > 10: self.remove_camera_entry_from_recent(self.recent_cameras[-1]) def add_dataset_entry_to_recent(self, p: Path): if not self.startup_page_ui.label_noRecentDatasets.isHidden(): self.startup_page_ui.label_noRecentDatasets.hide() self.startup_page_ui.verticalLayout_recentDatasets.removeWidget(self.startup_page_ui.label_noRecentDatasets) if p not in self.recent_datasets: self.recent_datasets.insert(0, p) action = QAction(str(p.name)) action.setToolTip(str(p)) self.recent_dataset_qactions.insert(0, action) if len(self.recent_datasets_menu.actions()) > 0: self.recent_datasets_menu.insertAction(self.recent_datasets_menu.actions()[0], action) else: self.recent_datasets_menu.addAction(action) btn = QToolButton() btn.setDefaultAction(action) btn.setStyleSheet('font-size: 12pt') btn.setText(str(p)) btn.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.startup_page_ui.verticalLayout_recentDatasets.insertWidget(0, btn) self.startup_dataset_buttons.append(btn) if len(self.recent_datasets) > 10: self.remove_dataset_entry_from_recent(self.recent_datasets[-1]) def remove_dataset_entry_from_recent(self, path: Path): actions = list(filter(lambda action: action.toolTip() == str(path), self.recent_dataset_qactions)) if len(actions) > 0: action = actions[0] btn = list(filter(lambda btn_: btn_.defaultAction() == action, self.startup_dataset_buttons))[0] self.startup_dataset_buttons.remove(btn) self.startup_page_ui.verticalLayout_recentDatasets.removeWidget(btn) self.recent_dataset_qactions.remove(action) self.recent_datasets_menu.removeAction(action) self.recent_datasets.remove(path) btn.setVisible(False) btn.deleteLater() if len(self.recent_datasets) == 0: self.startup_page_ui.verticalLayout_recentDatasets.addWidget(self.startup_page_ui.label_noRecentDatasets) self.startup_page_ui.label_noRecentDatasets.setAlignment(Qt.AlignHCenter) self.startup_page_ui.label_noRecentDatasets.show() def remove_camera_entry_from_recent(self, path: Path): action = self.recent_cameras_qactions[str(path)] btn = list(filter(lambda btn_: btn_.defaultAction() == action, self.startup_camera_buttons))[0] self.startup_camera_buttons.remove(btn) self.startup_page_ui.verticalLayout_recentCameras.removeWidget(btn) del self.recent_cameras_qactions[str(path)] self.recent_cameras_menu.removeAction(action) self.recent_cameras.remove(path) btn.setVisible(False) btn.deleteLater() if len(self.recent_cameras) == 0: self.startup_page_ui.verticalLayout_recentCameras.addWidget(self.startup_page_ui.label_noRecentCameras) self.startup_page_ui.label_noRecentCameras.setAlignment(Qt.AlignHCenter) self.startup_page_ui.label_noRecentCameras.show() def open_dataset(self, path: Path) -> bool: if len(self.dataset.cameras) > 0: self.dataset.save() if not os.access(path, mode=os.F_OK): self.remove_dataset_entry_from_recent(path) msg_box = QMessageBox(QMessageBox.Warning, 'File not found', f'The file {str(path)} does not exist.', QMessageBox.Open | QMessageBox.Close) if msg_box.exec_() == QMessageBox.Open: self.ui.actionOpen_dataset.trigger() else: msg_box.close() return False elif not os.access(path, mode=os.W_OK): self.remove_dataset_entry_from_recent(path) msg_box = QMessageBox(QMessageBox.Warning, 'Permission denied', f'The application can\'t modify the ' f'file {str(path)}', QMessageBox.Close) msg_box.exec_() return False self.dataset = Dataset() self.processing_widget.set_dataset(self.dataset) if not self.dataset.load_from(path): self.processing_widget.cleanup() self.ui.stackedWidget.setCurrentIndex(0) return False return True @staticmethod def get_config_state(): try: with open(Path(sys.argv[0]).parent / 'state.json', 'r') as f: state = json.load(f) if sorted(list(state.keys())) != ['first_time_startup', 'recent_cameras', 'recent_datasets']: raise AttributeError return state except (FileNotFoundError, AttributeError) as _: return { 'first_time_startup': True, 'recent_cameras': [], 'recent_datasets': [], } def closeEvent(self, event: QCloseEvent) -> None: if self.processing_widget is not None: self.processing_widget.cleanup() self.save_state() super().closeEvent(event) def handle_close_dataset_triggered(self): self.dataset.save() self.processing_widget.cleanup() self.dataset = Dataset() self.processing_widget.set_dataset(self.dataset) self.ui.stackedWidget.setCurrentIndex(0) self.ui.toolBar.hide() self.statusBar().hide() def handle_camera_added(self): self.ui.stackedWidget.setCurrentIndex(1) self.ui.toolBar.show() self.statusBar().show() def show_progress_bar(self, cam_name: str, photo_count: int): self.statusBar().showMessage(f'Processing camera {cam_name}', 0) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(photo_count) self.progress_bar.setValue(0) self.progress_bar.show() def update_progress_bar(self, value: int): self.progress_bar.setValue(value) def hide_progress_bar(self, val: int): self.statusBar().clearMessage() self.progress_bar.hide() def notify_user(self, camera_name: str): self.sys_tray.showMessage("Verification needed", f'Camera {camera_name} requires verification of stick positions', QSystemTrayIcon.NoIcon, 5000) def handle_no_cameras_open(self): self.ui.stackedWidget.setCurrentIndex(0) self.ui.toolBar.hide() self.statusBar().hide() def handle_export_to_json_triggered(self): file_dialog = QFileDialog(self) file_dialog.setWindowTitle("Save measurements") file_dialog.setFileMode(QFileDialog.AnyFile) file_dialog.setNameFilter("*.json") file_dialog.setAcceptMode(QFileDialog.AcceptSave) if file_dialog.exec_(): file_path = Path(file_dialog.selectedFiles()[0]) dat = self.processing_widget.dataset.get_json_data() with open(file_path, "w") as f: f.write(dat)
class GUI(QtGui.QMainWindow): def __init__(self, app): QtGui.QMainWindow.__init__(self) self.app = app self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionAbout_Qt.triggered.connect(app.aboutQt) self.ui.actionAbout.triggered.connect(self.showAbout) self.ui.actionQuit.triggered.connect(self.quit) self.ui.quitBtn.clicked.connect(self.quit) self.ui.moduleNotebook.currentChanged.connect(self.updateWizButtons) self.ui.nextBtn.clicked.connect(self.nextTab) self.ui.prevBtn.clicked.connect(self.prevTab) self.welcome_container = QtGui.QWidget() self.welcomeTab = Ui_Welcome() self.welcomeTab.setupUi(self.welcome_container) self.ui.moduleNotebook.insertTab(0, self.welcome_container, "Welcome") self.createConfigTab() self.updateWizButtons() def updateWizButtons(self): if self.ui.moduleNotebook.currentIndex() <= 0: self.ui.prevBtn.setEnabled(False) else: self.ui.prevBtn.setEnabled(True) if self.isLast(): self.ui.nextBtn.setText(_("Finish")) else: self.ui.nextBtn.setText(_("Next")) if self.ui.moduleNotebook.currentIndex() < 0: self.ui.nextBtn.setEnabled(False) else: self.ui.nextBtn.setEnabled(True) def nextTab(self, *args): if self.isLast(): self.quit() else: self.chTab(1) def prevTab(self, *args): self.chTab(-1) def chTab(self, amt): self.ui.moduleNotebook.setCurrentIndex( self.ui.moduleNotebook.currentIndex() + amt) def isLast(self): return self.ui.moduleNotebook.count() - 1 <= self.ui.moduleNotebook.currentIndex() def createConfigTab(self): configs = config.Configuration self.configTab = QtGui.QWidget() self.configTab.vlayout = QtGui.QVBoxLayout(self.configTab) # Master notebook (stores the sections) self.configTab.notebook1 = QtGui.QTabWidget(self.configTab) self.configTab.vlayout.addWidget(self.configTab.notebook1) self.fillConfiguration(configs, self.configTab) self.ui.moduleNotebook.addTab(self.configTab, _("Configuration")) def addCategory(self, section, category): i = section c = category fw = QtGui.QWidget(self.configTab.notebook1.__dict__[i].nbook) vb = QtGui.QVBoxLayout(fw) self.configTab.notebook1.__dict__[i].nbook.__dict__[ c] = QtGui.QScrollArea(fw) vb.addWidget(self.configTab.notebook1.__dict__[i].nbook.__dict__[c]) self.configTab.notebook1.__dict__[i].nbook.__dict__[ c].setWidgetResizable(True) self.configTab.notebook1.__dict__[i].nbook.__dict__[ c].flayout = QtGui.QFormLayout() #self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setSizeConstraint( # QtGui.QLayout.SetFixedSize) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setFieldGrowthPolicy( QtGui.QFormLayout.ExpandingFieldsGrow) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setLabelAlignment( QtCore.Qt.AlignLeft) #self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setFormAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop); self.configTab.notebook1.__dict__[i].nbook.__dict__[ c].flayoutC = QtGui.QWidget() self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayoutC.setLayout( self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayoutC.setSizePolicy( QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].setWidget( self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayoutC) self.configTab.notebook1.__dict__[i].nbook.addTab( fw, c) def fillConfiguration(self, configs, widget): # TODO: Clean this mess, or at least comment it l = "l" v = "v" for i in configs.keys(): # If the section is not in the notebook, add it if not i in self.configTab.notebook1.__dict__: self.configTab.notebook1.__dict__[i] = QtGui.QWidget() self.configTab.notebook1.__dict__[i].vlayout = QtGui.QVBoxLayout( self.configTab.notebook1.__dict__[i]) self.configTab.notebook1.__dict__[i].nbook = QtGui.QTabWidget( self.configTab.notebook1.__dict__[i]) self.configTab.notebook1.__dict__[i].vlayout.addWidget( self.configTab.notebook1.__dict__[i].nbook) self.configTab.notebook1.addTab( self.configTab.notebook1.__dict__[i], i) for c in configutils.getValue(configs[i][configutils.categories]): self.addCategory(i, c) for x in configs[i].keys(): if x == configutils.categories: continue c = configutils.getValueP(configs[i][x], configutils.category) n = configutils.getValueP(configs[i][x], configutils.name) t = configutils.getValueP(configs[i][x], configutils.types) d = configutils.getValueP(configs[i][x], configutils.desc) v_ = configutils.getValue(configs[i][x]) c_ = configutils.getChoices(t) var = (i, x) uw = True # If the category is not in the section's notebook, add it if not c in self.configTab.notebook1.__dict__[i].nbook.__dict__: self.addCategory(i, c) # Add the dictionary self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n] = {} # Add the label self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][l] = QtGui.QLabel() self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][l].setText(n) self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][l].setToolTip(d) # Add the value if t == configutils.yesno: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v] = ConfigWidget(QtGui.QCheckBox(), var) if v_: self.configTab.notebook1.__dict__[i].nbook.__dict__[ c].__dict__[n][v].widget.setChecked(True) elif c_ is not None and len(c_) > 0: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v] = ConfigWidget(QtGui.QComboBox(), var) self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v].widget.clear() c__ = 0 for y in c_: self.configTab.notebook1.__dict__[i].nbook.__dict__[ c].__dict__[n][v].widget.addItem(y) if y == v_: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.setCurrentIndex(c__) c__ += 1 elif t == configutils.multiple: if not isinstance(v_, list): # Wut? logger.logE( self.tn, logger.E, _("Something went wrong")) self.configTab.notebook1.__dict__[i].nbook.__dict__[ c].__dict__[n][v] = MultipleValues(var) self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v].set(v_) uw = False elif t == configutils.filename: self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v] = FileName(var) self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v].set(v_) uw = False else: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v] = ConfigWidget(QtGui.QLineEdit(), var) self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v].widget.setText(v_) #self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.setSizePolicy( # QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding)) if uw: p = self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v].widget else: p = self.configTab.notebook1.__dict__[ i].nbook.__dict__[c].__dict__[n][v] p.setToolTip(d) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.addRow( self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][l], p) def addTab(self, *args): self.ui.moduleNotebook.addTab(*args) self.updateWizButtons() def showAbout(self): QtGui.QMessageBox.about(self, config.product, config.about_string) def quit(self, *args): quitProg(self.app)
class MainWindow(QtGui.QMainWindow): def __init__(self, exchangeName): QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle("PyArbitrageTrader - " + exchangeName) self.maxProfit = Decimal("-1") self.model = QtGui.QStandardItemModel() self.model.setHorizontalHeaderLabels( [ "Time", "TradeDirection", "Ask1", "Ask1 amount", "Bid1", "Bid1 amount", "Ask2", "Ask2 amount", "Bid2", "Bid2 amount", "Ask3", "Ask3 amount", "Bid3", "Bid3 amount", "ProfitPercent", "USD profit", ] ) self.ui.tableView_history.setModel(self.model) @pyqtSlot(int) def receiveLag(self, lag): self.ui.spinBox_lag.setValue(lag) @pyqtSlot(Tops, ArbData, ArbData) def receiveUpdate(self, tops, a1, a2): self.ui.doubleSpinBox_sec1_ask.setValue(float(tops.ask1)) self.ui.doubleSpinBox_sec1_bid.setValue(float(tops.bid1)) self.ui.doubleSpinBox_sec2_ask.setValue(float(tops.ask2)) self.ui.doubleSpinBox_sec2_bid.setValue(float(tops.bid2)) self.ui.doubleSpinBox_sec3_ask.setValue(float(tops.ask3)) self.ui.doubleSpinBox_sec3_bid.setValue(float(tops.bid3)) self.ui.doubleSpinBox_sec1_askAmount.setValue(float(tops.ask1_amount)) self.ui.doubleSpinBox_sec1_bidAmount.setValue(float(tops.bid1_amount)) self.ui.doubleSpinBox_sec2_askAmount.setValue(float(tops.ask2_amount)) self.ui.doubleSpinBox_sec2_bidAmount.setValue(float(tops.bid2_amount)) self.ui.doubleSpinBox_sec3_askAmount.setValue(float(tops.ask3_amount)) self.ui.doubleSpinBox_sec3_bidAmount.setValue(float(tops.bid3_amount)) self.maxProfit = max(self.maxProfit, a1.profit, a2.profit) result_text = "profit1 = %s\nprofit2 = %s\nmaxProfit = %s" % (a1.profit, a2.profit, self.maxProfit) self.ui.label_result.setText(result_text) lastItem = None if a1.profit > 0 or a2.profit > 0: a = a1 if a1.profit > 0 else a2 # print("Got arbitrage opportunity with profit %s" % a.profit) lastItem = QtGui.QStandardItem() lastItem.setText(str(a.usdProfit)) lastItem.setToolTip(str(a.usdInvestment)) self.model.appendRow( [ QtGui.QStandardItem(str(QtCore.QDateTime.currentDateTime().toString())), QtGui.QStandardItem(a.tradeDirection), QtGui.QStandardItem(str(tops.ask1)), QtGui.QStandardItem(str(tops.ask1_amount)), QtGui.QStandardItem(str(tops.bid1)), QtGui.QStandardItem(str(tops.bid1_amount)), QtGui.QStandardItem(str(tops.ask2)), QtGui.QStandardItem(str(tops.ask2_amount)), QtGui.QStandardItem(str(tops.bid2)), QtGui.QStandardItem(str(tops.bid2_amount)), QtGui.QStandardItem(str(tops.ask3)), QtGui.QStandardItem(str(tops.ask3_amount)), QtGui.QStandardItem(str(tops.bid3)), QtGui.QStandardItem(str(tops.bid3_amount)), QtGui.QStandardItem(str(a.profit * Decimal("100")) + "%"), lastItem, ] ) self.model.reset()
class GUI(QtGui.QMainWindow): def __init__(self, app): QtGui.QMainWindow.__init__(self) self.app = app self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionAbout_Qt.triggered.connect(app.aboutQt) self.ui.actionQuit.triggered.connect(self.quit) self.ui.quitBtn.clicked.connect(self.quit) self.ui.moduleNotebook.currentChanged.connect(self.updateWizButtons) self.ui.nextBtn.clicked.connect(self.nextTab) self.ui.prevBtn.clicked.connect(self.prevTab) self.welcome_container = QtGui.QWidget() self.welcomeTab = Ui_Welcome() self.welcomeTab.setupUi(self.welcome_container) self.ui.moduleNotebook.insertTab(0, self.welcome_container, "Welcome") self.createConfigTab() self.updateWizButtons() def updateWizButtons(self): if self.ui.moduleNotebook.currentIndex() <= 0: self.ui.prevBtn.setEnabled(False) else: self.ui.prevBtn.setEnabled(True) if self.isLast(): self.ui.nextBtn.setText(_("Finish")) else: self.ui.nextBtn.setText(_("Next")) if self.ui.moduleNotebook.currentIndex() < 0: self.ui.nextBtn.setEnabled(False) else: self.ui.nextBtn.setEnabled(True) def nextTab(self, *args): if self.isLast(): self.quit() else: self.chTab(1) def prevTab(self, *args): self.chTab(-1) def chTab(self, amt): self.ui.moduleNotebook.setCurrentIndex(self.ui.moduleNotebook.currentIndex() + amt) def isLast(self): return self.ui.moduleNotebook.count() - 1 <= self.ui.moduleNotebook.currentIndex() def createConfigTab(self): configs = config.Configuration self.configTab = QtGui.QWidget() self.configTab.vlayout = QtGui.QVBoxLayout(self.configTab) # Master notebook (stores the sections) self.configTab.notebook1 = QtGui.QTabWidget(self.configTab) self.configTab.vlayout.addWidget(self.configTab.notebook1) self.fillConfiguration(configs, self.configTab) self.ui.moduleNotebook.addTab(self.configTab, "Configuration") def fillConfiguration(self, configs, widget): # TODO: Clean this mess, or at least comment it l = chr(108) v = chr(118) for i in configs.keys(): # If the section is not in the notebook, add it if not i in self.configTab.notebook1.__dict__: self.configTab.notebook1.__dict__[i] = QtGui.QWidget() self.configTab.notebook1.__dict__[i].vlayout = QtGui.QVBoxLayout( self.configTab.notebook1.__dict__[i]) self.configTab.notebook1.__dict__[i].nbook = QtGui.QTabWidget( self.configTab.notebook1.__dict__[i]) self.configTab.notebook1.__dict__[i].vlayout.addWidget( self.configTab.notebook1.__dict__[i].nbook) self.configTab.notebook1.addTab(self.configTab.notebook1.__dict__[i], i) for x in configs[i].keys(): c = configutils.getValueP(configs[i][x], configutils.category) n = configutils.getValueP(configs[i][x], configutils.name) t = configutils.getValueP(configs[i][x], configutils.types) v_ = configutils.getValue(configs[i][x]) c_ = configutils.getChoices(t) var = (i, x) # If the category is not in the section's notebook, add it if not c in self.configTab.notebook1.__dict__[i].nbook.__dict__: fw = QtGui.QWidget(self.configTab.notebook1.__dict__[i].nbook) vb = QtGui.QVBoxLayout(fw) self.configTab.notebook1.__dict__[i].nbook.__dict__[c] = QtGui.QScrollArea(fw) vb.addWidget(self.configTab.notebook1.__dict__[i].nbook.__dict__[c]) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].setWidgetResizable(False) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout = QtGui.QFormLayout() self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setSizeConstraint( QtGui.QLayout.SetFixedSize) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setFieldGrowthPolicy( QtGui.QFormLayout.AllNonFixedFieldsGrow) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.setLabelAlignment( QtCore.Qt.AlignLeft) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayoutC = QtGui.QWidget() self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayoutC.setLayout( self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].setWidget( self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayoutC) self.configTab.notebook1.__dict__[i].nbook.addTab( fw, c) # Add the label self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n] = {} self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][l] = QtGui.QLabel() self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][l].setText(n) # Add the value if t == configutils.yesno: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v] = ConfigWidget(QtGui.QCheckBox(), var) if configutils.parseBoolean(v_): self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.setChecked(True) elif c_ is not None and len(c_) > 0: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v] = ConfigWidget(QtGui.QComboBox(), var) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.clear() c__ = 0 for y in c_: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.addItem(y) if y == v_: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.setCurrentIndex(c__) c__ += 1 else: self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v] = ConfigWidget(QtGui.QLineEdit(), var) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.setText(v_) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget.setSizePolicy( QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding)) self.configTab.notebook1.__dict__[i].nbook.__dict__[c].flayout.addRow( self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][l], self.configTab.notebook1.__dict__[i].nbook.__dict__[c].__dict__[n][v].widget) def addTab(self, *args): self.ui.moduleNotebook.addTab(*args) self.updateWizButtons() def quit(self, *args): quitProg(self.app)
class QmMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionShow.triggered.connect(self.toggle_mode) self.ui.actionSave.triggered.connect(self.save_note) self.ui.actionLoadShelf.triggered.connect(self.download_shelf) self.ui.actionLoadHot.triggered.connect(self.show_hot_note) self.ui.actionLoadNotes.triggered.connect(self.download_notes) self.ui.statusBar.hide() self.pbar = QProgressBar(self) self.pbar.setFixedWidth(500) self.ui.statusBar.addWidget(self.pbar) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(os.path.join(root_path, "static/icon.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.setWindowIcon(icon) self.browser = QWebEngineView(self) self.browser.setGeometry( 0, self.ui.menubar.height(), self.width(), self.height() - self.ui.menubar.height(), ) self.ui.actionback.triggered.connect(self.browser.back) self.ui.actionforward.triggered.connect(self.browser.forward) self.ui.actionShelf.triggered.connect(self.view_shelf) self.ui.actionLibrary.triggered.connect(self.view_library) # 加载外部的web页面 self.cache_path = os.path.join(root_path, "cache") if not os.path.exists(self.cache_path): os.mkdir(self.cache_path) # 设置缓存目录 default_profile = QWebEngineProfile.defaultProfile() default_profile.setCachePath(self.cache_path) default_profile.setPersistentStoragePath(self.cache_path) # 记录上次阅读位置 self.history_url_file = os.path.join(self.cache_path,"history.txt") if not os.path.exists(self.history_url_file): url = QUrl("https://weread.qq.com/") else: with open(self.history_url_file,'r') as f: url = QUrl(f.read().strip()) self.browser.urlChanged.connect(self.update_lastpage) # 每次改变都更新还是退出的时候更新 self.browser.load(url) self.model = QStringListModel(self) self.item_model = QStandardItemModel(self) self.select_model = QItemSelectionModel(self.item_model) self.ui.tableView.setModel(self.item_model) self.ui.tableView.setSelectionModel(self.select_model) self.ui.tableView.setAlternatingRowColors(True) self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.is_reading_mode = True self.note_dir = os.path.join(root_path, "notes") if not os.path.exists(self.note_dir): os.mkdir(self.note_dir) try: self.update_cookies() self.booklist = wereader.get_bookshelf(self.cookies) self.books = itertools.cycle(self.booklist) self.curBook = self.booklist[0] except Exception: self.curBook = None self.booklist = None def update_cookies(self): self.cookies = read_cookie_from_path(self.cache_path + "/Cookies") def update_lastpage(self): with open(self.history_url_file,'w') as f: f.write(self.browser.history().currentItem().url().toString()) def resizeEvent(self, a0): self.browser.resize( self.width(), self.height() - self.ui.menubar.height(), ) self.ui.splitter_2.resize( self.width() - 10, self.height() - self.ui.menubar.height(), ) self.ui.tableView.resize( self.ui.splitter.width(), self.ui.splitter.height() // 2 ) def on_listView_clicked(self, index): self.curBook = self.booklist[index.row()] self.on_curBook_changed() def on_tableView_clicked(self, index): self.curBook = self.booklist[index.row()] self.on_curBook_changed() def on_curBook_changed(self): self.ui.noteEdit.clear() note = self.get_note(self.curBook.bookId) self.ui.noteEdit.setText(note) def show_hot_note(self): self.ui.noteEdit.clear() note = self.get_hot_note(self.curBook.bookId) self.ui.noteEdit.setText(note) def get_note(self, id): note_name = os.path.join(self.note_dir, "%s.md" % id) if os.path.exists(note_name): with open(note_name, "r", encoding="utf-8") as f: return f.read() else: return wereader.get_bookmarklist(id, cookies=self.cookies) def get_hot_note(self, id): note_name = os.path.join(self.note_dir, "%s_hot.md" % id) if os.path.exists(note_name): with open(note_name, "r", encoding="utf-8") as f: return f.read() else: return wereader.get_bestbookmarks(id, cookies=self.cookies) def on_nextButton_clicked(self): self.curBook = next(self.books) self.on_curBook_changed() def save_note(self): text = self.ui.noteEdit.toPlainText() note_name = os.path.join(self.note_dir, "%s.md" % self.curBook.bookId) with open(note_name, "w", encoding="utf-8") as f: f.write(text) def toggle_mode(self): if self.is_reading_mode: self.browser.setVisible(False) self.ui.actionShow.setText("切换至阅读模式") self.is_reading_mode = False else: self.browser.setVisible(True) self.ui.actionShow.setText("切换至笔记模式") self.is_reading_mode = True def download_shelf(self): """加载书架时默认已经登录,重新获取cookie""" if not self.booklist: self.update_cookies() self.booklist = wereader.get_bookshelf(self.cookies) self.books = itertools.cycle(self.booklist) self.init_model() def init_model(self): self.model.setStringList([b.title for b in self.booklist]) self.ui.listView.setModel(self.model) self.ui.listView.setEditTriggers(QAbstractItemView.NoEditTriggers) rows = len(self.booklist) cols = 3 self.item_model.setRowCount(rows) self.item_model.setColumnCount(cols) for i in range(rows): try: self.item_model.setItem(i, 0, QStandardItem(self.booklist[i].bookId)) self.item_model.setItem(i, 1, QStandardItem(self.booklist[i].title)) self.item_model.setItem(i, 2, QStandardItem(self.booklist[i].author)) except Exception as e: print(e) self.ui.tableView.setModel(self.item_model) w = self.ui.splitter.width() // 10 self.ui.tableView.setColumnWidth(0, 1 * w) self.ui.tableView.setColumnWidth(1, 6 * w) self.ui.tableView.setColumnWidth(2, 3 * w) self.ui.tableView.setSelectionModel(self.select_model) # def view(self): # img = cv2.imread(next(self.images)) # 读取图像 # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换图像通道 # w, h = self.ui.graphicsView.width(), self.ui.graphicsView.height() # img = cv2.resize(img, (w, h)) # frame = QImage(img, w, h, QImage.Format_RGB888) # pix = QPixmap.fromImage(frame) # self.item = QGraphicsPixmapItem(pix) # 创建像素图元 # # self.item.setScale(self.zoomscale) # self.scene = QGraphicsScene() # 创建场景 # self.scene.addItem(self.item) # self.ui.graphicsView.setScene(self.scene) # 将场景添加至视图 def download_notes(self): self.ui.actionLoadNotes.setDisabled(True) self.ui.statusBar.show() self.pbar.show() self.pbar.setMaximum(len(self.booklist)) for i, book in enumerate(self.booklist): self.pbar.setValue(i) try: note_name = os.path.join(self.note_dir, "%s.md" % book.bookId) if os.path.exists(note_name): continue note = self.get_note(book.bookId) if note.strip(): with open(note_name, 'w', encoding='utf-8') as f: f.write(note) except Exception as e: print(e) self.pbar.hide() self.ui.statusBar.hide() def view_library(self): self.browser.load(QUrl("https://weread.qq.com/web/category")) def view_shelf(self): self.browser.load(QUrl("https://weread.qq.com/web/shelf"))
class MainWindow(QMainWindow): def __init__(self, parent=None): """ Инициализируем интерфейс и задаём начальные значения внутренних переменных """ QMainWindow.__init__(self, parent) self._alreadyShown = False self.setupUi() self._feedName = 'feed/http://habrahabr.ru/rss/' self._filters = { 'Все' : '.*' } self._categorizer = self.categorizeByDate file = QFile(':/templates/content.html') if file.open(QIODevice.ReadOnly | QIODevice.Text): s = QTextStream(file) self._entryTemplate = Template(s.readAll()) else: self._entryTemplate = Template('') self._curCategory = None self._curEntryId = -1 self._loadingData = False self._reader = libgreader.GoogleReader(None) self._loggedIn = False def _initToolBar(self): """ Добавляем нужные действия на тулбар """ tb = self._ui.toolBar l = QLabel('Категории') l.setMargin(settings.toolBarLabelMargin()) tb.addWidget(l) self._cbCategories = QComboBox() self._cbCategories.addItem('Даты') self._cbCategories.addItem('Блоги') self._cbCategories.addItem('Интересные') self._cbCategories.addItem('Скучные') self._cbCategories.addItem('Все') self._cbCategories.currentIndexChanged.connect(self.changeCategoryType) tb.addWidget(self._cbCategories) def setupUi(self): """ Инициализируем всё, что относится к интерфейсу """ self._ui = Ui_MainWindow() self._ui.setupUi(self) self._ui.twEntries.setContextMenuPolicy(Qt.CustomContextMenu) self._ui.twEntries.customContextMenuRequested.connect(self.showEntryListContextMenu) self._initToolBar() self._createEntryContextMenu() self._ui.wvEntryContent.settings().setAttribute(QWebSettings.PluginsEnabled, True) self._ui.wvEntryContent.setTextSizeMultiplier(settings.entryTextSizeMultiplier()) self._itemDelegate = EntryItemDelegate(self._ui.twEntries) self._ui.twEntries.setItemDelegate(self._itemDelegate) def showEvent(self, event): QMainWindow.showEvent(self, event) if not self._alreadyShown: splitter = self._ui.splitter splitter.setSizes((0.75 * splitter.height(), 0.25 * splitter.height())) self._alreadyShown = True def _createEntryContextMenu(self): self._entryMenu = QMenu('Context menu', self) self._entryMenu.addAction(self._ui.actMarkCurrentAsRead) self._entryMenu.addAction(self._ui.actMarkAllPreviousAsRead) self._entryMenu.addSeparator() self._entryMenu.addAction(self._ui.actReadArticle) self._entryMenu.addSeparator() starMenu = self._entryMenu.addMenu('Оценка') self._ratingActions = [None] * 5 for i in range(5): self._ratingActions[i] = QAction('*'*(i + 1), None) self._ratingActions[i].triggered.connect(self.setItemRating) starMenu.addAction(self._ratingActions[i]) def setItemRating(self): """ Устанавливаем рейтинг текущей записи """ a = self.sender() rating = len(a.text()) id = self._currentEntry().id.split("/")[-1] connection = sqlite3.connect(settings.entriesDb()) cursor = connection.cursor() try: cursor.execute('UPDATE Entries SET Rating=? WHERE ID=?', (rating, id)) connection.commit() if settings.markAsReadWhenGivingStars(): self.markCurrentAsRead() finally: connection.close() def showEntryListContextMenu(self, pos): item = self._ui.twEntries.itemAt(pos) if item and item.childCount() == 0: self._entryMenu.exec_(self._ui.twEntries.mapToGlobal(pos)) @pyqtSlot() def itemDataChanged(self, item, column): """ Обновляем статус Интересено/Скучно для изменённой записи """ if self._loadingData or column != 0: return id = item.data(0, Qt.UserRole) self._feed.getItem(id).interesting = (item.checkState(0) == Qt.Checked) @pyqtSlot() def quit(self): """ Выход из приложения """ self.saveEntries() qApp.exit() def _getUserAndPassword(self, user, password): """ Получаем логин и пароль через соответствующий диалог """ d = LoginDialog(user, password, self) if d.exec_() == QDialog.Accepted: settings.setUser(d.login()) if d.storePassword(): settings.setPassword(d.password()) return (True, d.login(), d.password()) else: return (False, '', '') @pyqtSlot() def login(self): """ Логинимся в GoogleReader """ if self._loggedIn: return True user = settings.user() password = settings.password() res = True if not user or not password: (res, user, password) = self._getUserAndPassword(user, password) if not res: return False auth = libgreader.ClientAuth(user, password) self._reader.auth = auth self._reader.fetchCount = 100 self._loggedIn = True return True def _switchToBoring(self): """ Переключаемся на категории "Скучные" """ self._cbCategories.setCurrentIndex(3) self._categorizer = self.categorizeBoring def _switchToDates(self): """ Переключаемся на категории "Даты" """ self._cbCategories.setCurrentIndex(0) self._categorizer = self.categorizeByDate @pyqtSlot() def getEntries(self): """ Получаем содержимое фида с Хабра """ if not self.login(): return self._feed = self._reader.getFeed(self._feedName) self._feed.clearItems() self._feed.loadItems(excludeRead=True) cnt = 0 while len(self._feed.getItems()) > 0: before = len(self._feed.getItems()) self._feed.loadMoreItems(excludeRead=True) cnt += 1 if len(self._feed.getItems()) - before == 0: break if settings.autoSwitchCategories(): self._switchToBoring() self.processEntries() def _updateWindowTitle(self): """ Обновляем заголовок окна """ unreadCount = len([i for i in self._feed.getItems() if not i.isRead()]) self.setWindowTitle(WINDOW_TITLE_TEMPLATE.format(unreadCount)) @pyqtSlot() def processEntries(self): """ Обрабатываем полученные из фида записи """ self.upadteFeedItemsWithDBInfo() self.splitItemsIntoCategories() self._updateWindowTitle() @pyqtSlot() def onEntryChanged(self, current, previous): """ Пользователь выбрал какую-то запись, загружаем её содержимое и заголовок """ if current == None or current.childCount() != 0: return item = self._ui.twEntries.currentItem() if item: self._curEntryId = item.data(0, Qt.UserRole) self.loadContentForCurrentEntry() @pyqtSlot() def saveEntries(self): """ Сохранение записей в БД """ connection = sqlite3.connect(settings.entriesDb()) try: cursor = connection.cursor() cursor.execute('SELECT ID FROM Entries') known_ids = tuple(i[0] for i in cursor.fetchall()) for item in self._feed.getItems(): dbId = item.id.split('/')[-1] if dbId in known_ids: # Обновляем запись, если она уже есть sql = 'UPDATE Entries SET IsInteresting=? WHERE ID=?' cursor.execute(sql, (item.interesting, dbId)) else: # Добавляем запись, если её ещё нет (blog, title) = item.title.split('/', 1) values = (dbId, title.strip(), item.data['author'], blog.strip(), item.data['updated'], item.data['published'], item.isRead(), item.interesting, 0, json.dumps(item.data)) sql = 'INSERT INTO Entries VALUES ({})'.format(','.join(['?']*10)) cursor.execute(sql, values) connection.commit() finally: connection.close() @pyqtSlot() def loadEntries(self): """" Загрузка записей из БД """ connection = sqlite3.connect(settings.entriesDb()) self._feed = libgreader.Feed(self._reader, 'Хабрахабр', 'feed/http://habrahabr.ru/rss/') self._reader.feedsById['feed/http://habrahabr.ru/rss/'] = self._feed self._categories = {} try: cursor = connection.cursor() file = QFile(':/sql/DbScheme.sql') if file.open(QIODevice.ReadOnly | QIODevice.Text): s = QTextStream(file) cursor.executescript(s.readAll()) cursor.execute('SELECT Data, IsInteresting FROM Entries WHERE IsRead=?', (False,)) for (data, interesting) in cursor.fetchall(): item = libgreader.Item(self._reader, json.loads(data), self._feed) item.interesting = interesting finally: connection.close() self.splitItemsIntoCategories() self._updateWindowTitle() @pyqtSlot() def markAllAsRead(self): """" Отмечаем, как прочитанные, все записи, кроме отмеченных чекбоксом """ count = self._currentCategory().childCount() protectionMessage = 'Вы действительно хотите отметить все записи в текущей категории, как прочитанные?' self.markFirstCountItemsAsRead(count, protectionMessage) def userReallyWantsToMarkAsRead(self, protectionMessage): msgBox = QMessageBox(self) msgBox.setWindowTitle('Подтверждение операции') msgBox.setText(protectionMessage) msgBox.setIcon(QMessageBox.Warning) msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel) if msgBox.exec_() == QMessageBox.Yes: return True else: return False def _currentCategory(self) -> QTreeWidgetItem: """ Текущая выбранная категория """ item = self._ui.twEntries.currentItem() if not item: return None return item if (item.parent() == None) else item.parent() @pyqtSlot() def selectAllEntries(self): """ Выделяем все записи в списке """ cat = self._currentCategory() if not cat: return for i in range(cat.childCount()): cat.child(i).setCheckState(0, Qt.Checked) @pyqtSlot() def deselectAllEntries(self): """ Снимаем выделение со всех записей в списке """ cat = self._currentCategory() if not cat: return for i in range(cat.childCount()): cat.child(i).setCheckState(0, Qt.Unchecked) def closeEvent(self, event): self.saveEntries() def _setToolTipForItem(self, entry, item): """ Устанавливаем всплывающую подсказку для записи, если это разрешено настройками """ if not settings.showToolTip(): return toolTip = "ID: {}\nБлог: {}\nЗаголовок: {}\nАвтор: {}\nОбновлена: {}\nОпубликована: {}" (blog, title) = tuple(i.strip() for i in entry.title.split("/", 1)) updated = time.strftime("%H:%M %d.%m.%Y", time.localtime(entry.data['updated'])) published = time.strftime("%H:%M %d.%m.%Y", time.localtime(entry.data['published'])) toolTip = toolTip.format(entry.id.split("/")[-1], blog, title, entry.author, updated, published) item.setToolTip(0, toolTip) def fillTreeWidget(self): """ Заполняем tree widget записями, на основе разбиения на категории""" self._loadingData = True self._ui.twEntries.clear() for key in self._categories: self._categories[key] = sorted(self._categories[key], key=attrgetter('title')) item = DateTreeWidgetItem(self._ui.twEntries) font = item.font(0) font.setPointSize(11) font.setBold(True) item.setFont(0, font) if settings.showEntryCountInCategory(): item.setText(0, "{} ({})".format(key, len(self._categories[key]))) else: item.setText(0, key) item.setData(0, Qt.UserRole, self._keyForCategory[key]) for e in self._categories[key]: entryItem = QTreeWidgetItem(item) font = entryItem.font(0) font.setPointSize(12) entryItem.setCheckState(0, Qt.Checked if e.interesting else Qt.Unchecked) entryItem.setText(0, e.title) entryItem.setFont(0, font) entryItem.setData(0, Qt.UserRole, e.id) self._setToolTipForItem(e, entryItem) self._ui.twEntries.sortItems(0, Qt.AscendingOrder) self._ui.twEntries.expandAll() self._loadingData = False def splitItemsIntoCategories(self): """ Разделяем записи по нашим категориям """ self._categories = {} self._keyForCategory = {} for item in self._feed.getItems(): if item.isRead(): continue (cat, key) = self._categorizer(item) if cat is None: continue if not cat in self._categories: self._categories[cat] = [] if not cat in self._keyForCategory: self._keyForCategory[cat] = key self._categories[cat].append(item) self.fillTreeWidget() def categorizeByDate(self, item): updated = time.localtime(item.data['updated']) res = "{} {} {} г." months = ('января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентябра', 'октября', 'ноября', 'декабря') return (res.format(updated.tm_mday, months[updated.tm_mon - 1], updated.tm_year), item.data['updated']) def categorizeByBlog(self, item): """ Делим записи на категории по блогам (блог идёт в заголовке до первого символа '|') """ cat = item.title.split('/', 1)[0] return (cat, cat) def categorizeAllInOne(self, item): """ Сваливаем все записи в кучу """ for f in self._filters: if re.match(self._filters[f], item.title): return (f, f) def categorizeInteresting(self, item): """ Отбираем только интересные записи """ if item.interesting: return ('Интересные', 'Интересные') else: return (None, None) def categorizeBoring(self, item): """ Отбираем только скучные записи """ if not item.interesting: return ('Скучные', 'Скучные') else: return (None, None) def changeCategoryType(self, categoryTypeIndex): if (categoryTypeIndex == 0): self._categorizer = self.categorizeByDate elif (categoryTypeIndex == 1): self._categorizer = self.categorizeByBlog elif (categoryTypeIndex == 2): self._categorizer = self.categorizeInteresting elif (categoryTypeIndex == 3): self._categorizer = self.categorizeBoring elif (categoryTypeIndex == 4): self._categorizer = self.categorizeAllInOne self.splitItemsIntoCategories() self._updateWindowTitle() @pyqtSlot() def loadContentForCurrentEntry(self, checked=True): """ Пользователь выбрал какую-то запись, загружаем её содержимое и заголовок """ if not checked: return e = self._currentEntry() (blog, title) = tuple(i.strip() for i in e.title.split("/", 1)) html = self._entryTemplate.substitute(title=title, blog=blog, author=e.author, content=e.content) self._ui.wvEntryContent.setHtml(html) self._ui.statusbar.showMessage('Показываем содержание записи...', 2000) @pyqtSlot() def loadArticleForCurrentEntry(self, checked=True): """" Загружаем саму статью для текущей выбранной записи """ self._ui.statusbar.showMessage('Показываем статью...', 2000) data = urllib.request.urlopen(self._currentEntry().url).read().decode('utf8') parser = HabraParser() parser.feed(data) d = ArticleViewDialog(self) d.setContent(parser.getArticleWithComments(), self._currentEntry().url) width = min(self.width()*settings.allowedWidthRatio(), settings.articleViewWidth()) height = min(self.height()*settings.allowedHeightRatio(), settings.articleViewHeight()) d.resize(QSize(width, height)) d.exec_() def _currentEntry(self): """ Текущая (выделенная в TreeView) запись """ return self._feed.getItem(self._curEntryId) @pyqtSlot() def markCurrentAsRead(self): """ Отмечаем текущую запись, как прочитанную """ if not self.login(): return e = self._currentEntry() e.markRead() self.updateDb() self.splitItemsIntoCategories() self._updateWindowTitle() @pyqtSlot() def showAboutQt4(self): QMessageBox.aboutQt(self, 'О Qt4') @pyqtSlot() def showAbout(self): text = """ <b>ГуглоХабраРидер 0.9.00</b><br> <br> Автор: Борис Кучин <[email protected]><br> <br> Приложение для чтения новостей c сайта <a href="http://habrahabr.ru">habrahabr.ru</a> с синхронизацией информации о прочитанном через Google Reader<br> <br> В приложении использованы следующие сторонние наработки: <ul> <li><a href="https://github.com/askedrelic/libgreader">libgreader</a> (форк twidi) — библиотека для работы c Google Reader API (портирована с помощью 2to3) <li>Иконки <a href="http://www.fatcow.com/free-icons">Fat Cow</a> от gasyoun <li>favicon сайта <a href="http://habrahabr.ru">habrahabr.ru</a> </ul> """ QMessageBox.about(self, 'О программе', text) @pyqtSlot() def markAllPreviousAsRead(self): """ Отмечаем, как прочитанные, все записи, которые находятся в списке выше выбранной записи """ cat = self._currentCategory() item = self._ui.twEntries.currentItem() if not cat or not item: return count = cat.indexOfChild(item) + 1 protectionMessage = 'Вы действительно хотите отметить все записи выше, как прочитанные?' self.markFirstCountItemsAsRead(count, protectionMessage) def updateDb(self): """ Обновляет информацию о текущих записях в БД """ connection = sqlite3.connect(settings.entriesDb()) cursor = connection.cursor() try: for i in self._feed.getItems(): id = i.id.split('/')[-1] if i.isRead(): cursor.execute('UPDATE Entries SET IsRead=? WHERE ID=?', (True, id)) if i.interesting: cursor.execute('UPDATE Entries SET IsInteresting=? WHERE ID=?', (True, id)) connection.commit() finally: connection.close() def progressDialog(self, count): """ Создаёт QProgressDialog с нужными параметрами для индикации процесса общения с сервером """ # Добавление пробелов в начало и конец позволяет задать нужный размер диалога. По-другому # не нашёл как label = "{}{}{}".format(' '*20, 'Отмечаем записи, как прочитанные', ' '*20) progress = QProgressDialog(label, 'Отмена', 0, count, self) progress.setWindowModality(Qt.WindowModal) progress.setWindowTitle('Общение с сервером') return progress def markFirstCountItemsAsRead(self, count, protectionMessage): """ Отмечаем первые count записей в текущей категории, как прочитанные. Перед этим показываем 'защитное сообщение' protectionMessage """ if not self.login(): return if not self.userReallyWantsToMarkAsRead(protectionMessage): return progress = self.progressDialog(count) progress.show() for row in range(count): item = self._currentCategory().child(row) progress.setValue(row) id = item.data(0, Qt.UserRole) if item.checkState(0) == Qt.Checked: self._feed.getItem(id).interesting = True continue try: self._feed.getItem(id).markRead() except HTTPException as e: # Вообще, здесь нужно попытаться получить токен или auth заново text = 'При попытке отметить записи, как прочитанные возникла ошибка: ' + str(e) QMessageBox.warning(self, 'Ошибка', text) break if progress.wasCanceled(): break qApp.processEvents() progress.setValue(count) self._ui.twEntries.setCurrentItem(None) self.updateDb() shouldReturnToDates = (settings.autoSwitchCategories() and self._cbCategories.currentIndex() == 3) if shouldReturnToDates: self._switchToDates() self.splitItemsIntoCategories() self._updateWindowTitle() def upadteFeedItemsWithDBInfo(self): """ Обновляет информацию об интересности и рейтинги записи для записей фида на основании информации из БД. Используется после загрузки записей из сети для правильного отображения информации """ EntryInfo = collections.namedtuple('EntryInfo', 'ID, interesting, rating, data') connection = sqlite3.connect(settings.entriesDb()) cursor = connection.cursor() unreadEntries = {} try: cursor.execute("SELECT ID, IsInteresting, Rating, Data FROM Entries WHERE IsRead=0") unreadEntries = {ei.ID:ei for ei in map(EntryInfo._make, cursor.fetchall())} finally: connection.close() for item in self._feed.getItems(): id = item.id.split("/")[-1] if id in unreadEntries: item.interesting = unreadEntries[id].interesting item.rating = unreadEntries[id].rating id_prefix = 'tag:google.com,2005:reader/item/' missingIds = [] for entryId in unreadEntries: id = id_prefix + entryId if not id in self._feed.itemsById: missingIds.append(entryId) for id in missingIds: item = libgreader.Item(self._reader, json.loads(unreadEntries[id].data), self._feed) item.interesting = unreadEntries[id].interesting item.rating = unreadEntries[id].rating @pyqtSlot() def expandCategories(self): """ Разворачиваем все категории в tree view """ self._ui.twEntries.expandAll() @pyqtSlot() def collapseCategories(self): """ Сворачиваем все категории в tree view """ self._ui.twEntries.collapseAll() @pyqtSlot() def showHelp(self): """ Показываем окошко с краткой справкой """ howToUse = """ <b>Краткая инструкция по использованию:</b><br><br> Для получения записей нужно нажать на кнопку "Получить записи". При этом появится форма для ввода логина и пароля для доступа к Google Reader. Кнопка "Логин" служит для обновления соединения с Google Reader, если оно было потеряно. В общем случае, нажимать на неё необходимости нет. Приложение само попробует подсоединиться к серверу, когда это будет необходимо.<br><br> Иконки "интересно"/"скучно" работают как простые чекбоксы. То есть нажатие на них мышкой переключает статус записи.<br><br> Кроме того, можно (и нужно) это делать с клавиатуры пробелом. В этом режиме удобно просматривать много записей, перемещаясь между ними клавишами вверх/вниз. <br><br> На записях можно позвать контекстное меню для отметки текущей записи, как прочитанной, чтения полной версии статьи и отметки всех скучных записей в категории выше как прочитанных. То есть как прочитанные будут отмечены все записи, которые принадлежат той же категории, что и выделенная и которые лежат выше неё. """ QMessageBox.information(self, 'Справка', howToUse)
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self)
class MainWindow(QMainWindow): def setupUi(self): self.__initActions() self.ui.statusLabel = QLabel() self.ui.statusLabel.setText("Not running") self.ui.statusbar.addPermanentWidget(self.ui.statusLabel) self.ui.statusIcon = QLabel() self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_not_running.png")) self.ui.statusbar.addPermanentWidget(self.ui.statusIcon) #def setupGraph(self): #self.scene = QGraphicsScene() #self.c2 = Composite() #self.c1 = Composite() #self.c1.addItem(LeafEntry("exp1", "val11")) #self.c1.addItem(LeafEntry("exp2 long", "val22")) #self.c2.addItem(LeafEntry("exp2 even longer", "val22")) #self.c2.addItem(CompositeEntry("subcomp", self.c1)) #self.c2.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable) #self.scene.addItem(self.c2) def __initActions(self): self.act = Actions(self) # debug actions self.ui.menuDebug.addAction(self.act.actions[Actions.Run]) self.ui.menuDebug.addAction(self.act.actions[Actions.Continue]) self.ui.menuDebug.addAction(self.act.actions[Actions.Interrupt]) self.ui.menuDebug.addAction(self.act.actions[Actions.Next]) self.ui.menuDebug.addAction(self.act.actions[Actions.Step]) self.ui.menuDebug.addAction(self.act.actions[Actions.Finish]) self.ui.menuDebug.addAction(self.act.actions[Actions.RunToCursor]) # file actions self.ui.menuFile.insertAction(self.ui.actionSaveSession, self.act.actions[Actions.Open]) self.ui.menuFile.addAction(self.act.actions[Actions.SaveFile]) self.ui.menuFile.addAction(self.act.actions[Actions.Exit]) # add them to menubar and also menuView to respect order self.ui.menubar.addAction(self.ui.menuFile.menuAction()) self.ui.menubar.addAction(self.ui.menuView.menuAction()) self.ui.menubar.addAction(self.ui.menuDebug.menuAction()) self.ui.menubar.addAction(self.ui.menuHelp.menuAction()) # now make toolbar actions self.ui.Main.addAction(self.act.actions[Actions.Open]) self.ui.Main.addAction(self.act.actions[Actions.SaveFile]) self.ui.Main.addSeparator() self.ui.Main.addAction(self.act.actions[Actions.Run]) self.ui.Main.addAction(self.act.actions[Actions.Continue]) self.ui.Main.addAction(self.act.actions[Actions.Interrupt]) self.ui.Main.addAction(self.act.actions[Actions.Next]) self.ui.Main.addAction(self.act.actions[Actions.Step]) self.ui.Main.addAction(self.act.actions[Actions.Finish]) self.ui.Main.addAction(self.act.actions[Actions.RunToCursor]) self.ui.Main.addSeparator() self.ui.Main.addAction(self.act.actions[Actions.Exit]) # connect actions self.__connectActions() def __connectActions(self): # file menu self.connect(self.act.actions[Actions.Open], SIGNAL('activated()'), self.showOpenExecutableDialog) self.connect(self.act.actions[Actions.Exit], SIGNAL('activated()'), self.close) self.connect(self.act.actions[Actions.SaveFile], SIGNAL('activated()'), self.signalproxy.emitSaveCurrentFile) # debug menu self.connect(self.act.actions[Actions.Run], SIGNAL('activated()'), self.debugController.run) self.connect(self.act.actions[Actions.Next], SIGNAL('activated()'), self.debugController.next_) self.connect(self.act.actions[Actions.Step], SIGNAL('activated()'), self.debugController.step) self.connect(self.act.actions[Actions.Continue], SIGNAL('activated()'), self.debugController.cont) self.connect(self.act.actions[Actions.Interrupt], SIGNAL('activated()'), self.debugController.interrupt) self.connect(self.act.actions[Actions.Finish], SIGNAL('activated()'), self.debugController.finish) self.connect(self.act.actions[Actions.RunToCursor], SIGNAL('activated()'), self.debugController.inferiorUntil) QObject.connect(self.ui.actionRestoreSession, SIGNAL('activated()'), self.distributedObjects.sessionManager.showRestoreSessionDialog) QObject.connect(self.ui.actionSaveSession, SIGNAL('activated()'), self.distributedObjects.sessionManager.showSaveSessionDialog) def __init__(self, parent=None): """ init UI """ QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.actionSaveSession.setEnabled(False) self.distributedObjects = DistributedObjects() self.debugController = self.distributedObjects.debugController self.settings = self.debugController.settings self.signalproxy = self.distributedObjects.signalProxy self.pluginloader = PluginLoader(self.distributedObjects) #init RecentFileHandler nrRecentFiles = 5 self.initRecentFileHandler(nrRecentFiles) QObject.connect(self.debugController, SIGNAL('executableOpened'), self.showExecutableName) # signal proxy QObject.connect(self.signalproxy, SIGNAL('inferiorIsRunning(PyQt_PyObject)'), self.targetStartedRunning, Qt.QueuedConnection) QObject.connect(self.signalproxy, SIGNAL('inferiorStoppedNormally(PyQt_PyObject)'), self.targetStopped, Qt.QueuedConnection) QObject.connect(self.signalproxy, SIGNAL('inferiorReceivedSignal(PyQt_PyObject)'), self.targetStopped, Qt.QueuedConnection) QObject.connect(self.signalproxy, SIGNAL('inferiorHasExited(PyQt_PyObject)'), self.targetExited, Qt.QueuedConnection) QObject.connect(self.signalproxy, SIGNAL('addDockWidget(PyQt_PyObject, QDockWidget, PyQt_PyObject)'), self.addPluginDockWidget) QObject.connect(self.signalproxy, SIGNAL('removeDockWidget(QDockWidget)'), self.removeDockWidget) QObject.connect(self.pluginloader, SIGNAL('insertPluginAction(PyQt_PyObject)'), self.addPluginAction) QObject.connect(self.ui.actionSavePlugins, SIGNAL('activated()'), self.showSavePluginsDialog) QObject.connect(self.ui.actionLoadPlugins, SIGNAL('activated()'), self.showLoadPluginsDialog) # Add editor to main window. self.ui.gridLayout.addWidget(self.distributedObjects.editorController.editor_view, 0, 0, 1, 1) self.pluginloader.addAvailablePlugins() # Tell everyone to insert their dock widgets into the main window self.distributedObjects.signalProxy.insertDockWidgets() # get filelist dockwidget self.filelist_dockwidget = self.findChild(QDockWidget, "FileListView") self.setWindowFilePath("<none>") self.setupUi() self.createInitialWindowPlacement() self.readSettings() self.quickwatch = QuickWatch(self, self.distributedObjects) def addPluginDockWidget(self, area, widget, addToggleViewAction): self.addDockWidget(area, widget) if addToggleViewAction: self.ui.menuShow_View.addAction(widget.toggleViewAction()) def addPluginAction(self, Action): """ show plugin as menu entry """ self.ui.menuPlugins.addAction(Action) def createInitialWindowPlacement(self): """ Saves the window and widget placement after first start of program. """ #check if settings do not exist initExists = self.settings.contains("InitialWindowPlacement/geometry") if not initExists: self.breakpointWidget = self.findChild(QDockWidget, "BreakpointView") self.fileListWidget = self.findChild(QDockWidget, "FileListView") self.dataGraphWidget = self.findChild(QDockWidget, "DataGraphView") self.watchWidget = self.findChild(QDockWidget, "WatchView") self.localsWidget = self.findChild(QDockWidget, "LocalsView") self.stackWidget = self.findChild(QDockWidget, "StackView") self.tracepointWidget = self.findChild(QDockWidget, "TracepointView") self.gdbIoWidget = self.findChild(QDockWidget, "GdbIoView") self.pyIoWidget = self.findChild(QDockWidget, "PyIoView") self.inferiorIoWidget = self.findChild(QDockWidget, "InferiorIoView") #tabify widgets to initial state and save settings self.tabifyDockWidget(self.fileListWidget, self.dataGraphWidget) self.tabifyDockWidget(self.watchWidget, self.localsWidget) self.tabifyDockWidget(self.localsWidget, self.stackWidget) self.tabifyDockWidget(self.stackWidget, self.breakpointWidget) self.tabifyDockWidget(self.breakpointWidget, self.tracepointWidget) self.tabifyDockWidget(self.gdbIoWidget, self.pyIoWidget) self.tabifyDockWidget(self.pyIoWidget, self.inferiorIoWidget) self.settings.setValue("InitialWindowPlacement/geometry", self.saveGeometry()) self.settings.setValue("InitialWindowPlacement/windowState", self.saveState()) def initRecentFileHandler(self, nrRecentFiles): """ Create menu entries for recently used files and connect them to the RecentFileHandler """ # create menu entries and connect the actions to the debug controller recentFileActions = [0] * nrRecentFiles for i in range(nrRecentFiles): recentFileActions[i] = OpenRecentFileAction(self) recentFileActions[i].setVisible(False) self.ui.menuRecentlyUsedFiles.addAction(recentFileActions[i]) QObject.connect(recentFileActions[i], SIGNAL('executableOpened'), self.distributedObjects.debugController.openExecutable) self.RecentFileHandler = RecentFileHandler(recentFileActions, nrRecentFiles, self.distributedObjects) QObject.connect(self.debugController, SIGNAL('executableOpened'), self.RecentFileHandler.addToRecentFiles) def restoreInitialWindowPlacement(self): """ Restores the window placement created by createInitialWindowPlacement(). """ self.restoreGeometry(self.settings.value("InitialWindowPlacement/geometry").toByteArray()) self.restoreState(self.settings.value("InitialWindowPlacement/windowState").toByteArray()) def showOpenExecutableDialog(self): filename = str(QFileDialog.getOpenFileName(self, "Open Executable")) if (filename != ""): self.debugController.openExecutable(filename) def showLoadPluginsDialog(self): dialog = QFileDialog() dialog.setNameFilter("*.xml") filename = str(dialog.getOpenFileName(self, "Load plugin configuration")) if (filename != ""): self.pluginloader.getActivePlugins(filename) def showSavePluginsDialog(self): dialog = QFileDialog() dialog.setNameFilter("*.xml") filename = str(dialog.getSaveFileName(self, "Save plugin configuration")) if (filename != ""): self.pluginloader.savePluginInfo(filename) def showExecutableName(self, filename): self.ui.actionSaveSession.setEnabled(True) # enable saving session self.setWindowFilePath(filename) def targetStartedRunning(self): self.ui.statusLabel.setText("Running") self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_running.png")) def targetStopped(self, rec): self.ui.statusLabel.setText("Stopped") self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_stopped.png")) def targetExited(self): self.ui.statusLabel.setText("Not running") self.ui.statusIcon.setPixmap(QPixmap(":/icons/images/inferior_not_running.png")) def closeEvent(self, event): if not self.distributedObjects.editorController.closeOpenedFiles(): event.ignore() # closing source files may be canceled by user else: self.settings.setValue("geometry", self.saveGeometry()) self.settings.setValue("windowState", self.saveState()) QMainWindow.closeEvent(self, event) self.pluginloader.savePluginInfo() def readSettings(self): self.restoreGeometry(self.settings.value("geometry").toByteArray()) self.restoreState(self.settings.value("windowState").toByteArray())
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.libreria = Libreria() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.agregar_final_pushButton.clicked.connect(self.click_agregar) self.ui.agregar_inicio_pushButton.clicked.connect( self.click_agregar_inicio) self.ui.mostrar_pushButton.clicked.connect(self.click_mostrar) self.ui.actionAbrir.triggered.connect(self.action_abrir_archivo) self.ui.actionGuardar.triggered.connect(self.action_guardar_archivo) @Slot() def action_abrir_archivo(self): #print('abrir_archivo') ubicacion = QFileDialog.getOpenFileName(self, 'Abrir archivo', '.', 'JSON (*.json)')[0] if self.libreria.abrir(ubicacion): QMessageBox.information(self, "Éxito", "Se abrió el archivo " + ubicacion) else: QMessageBox.critical(self, "Error", "Error al abrir el archivo" + ubicacion) @Slot() def action_guardar_archivo(self): #print('guardar_archivo') ubicacion = QFileDialog.getSaveFileName( self, 'Guardar archivo' '.' 'JSON (*.json)')[0] print(ubicacion) if self.libreria.guardar(ubicacion): QMessageBox.information(self, "Éxito", "Se pudo crear el archivo" + ubicacion) else: QMessageBox.critical(self, "Error", "No se pudo crear el archivo " + ubicacion) @Slot() def click_mostrar(self): #self.libreria.mostrar() self.ui.salida.clear() self.ui.salida.insertPlainText(str(self.libreria)) @Slot() def click_agregar(self): id = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_lineEdit.text() red = self.ui.red_spinBox.value() green = self.ui.green_spinBox.value() blue = self.ui.blue_spinBox.value() particula = Particula(id, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.libreria.agregar_inicio(particula) # print(id, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) # self.ui.salida.insertPlainText(id + str(origen_x) + str(origen_y) + str(destino_x) + str(destino_y) + velocidad + str(red) + str(green) + str(blue)) @Slot() def click_agregar_inicio(self): id = self.ui.id_lineEdit.text() origen_x = self.ui.origen_x_spinBox.value() origen_y = self.ui.origen_y_spinBox.value() destino_x = self.ui.destino_x_spinBox.value() destino_y = self.ui.destino_y_spinBox.value() velocidad = self.ui.velocidad_lineEdit.text() red = self.ui.red_spinBox.value() green = self.ui.green_spinBox.value() blue = self.ui.blue_spinBox.value() particula = Particula(id, origen_x, origen_y, destino_x, destino_y, velocidad, red, green, blue) self.libreria.agregar_inicio(particula)
class MainWindow(QtGui.QMainWindow): def __init__(self,parent=None): super(MainWindow,self).__init__(parent) self.ui = Ui_MainWindow(self) self.ui.setupUi(self) self.boundsbox = BoundsBox(self) self.boundsbox.hide() self.data = {} #data self.fn = None #filename self.xdata = None #temperature self.ydata = None #strainrate self.zdata = None #strain self.kdata = None #stress self.model = None #model self.fc = None #flowcurve self.params = None #parameters self.ue = None #uniform elongation self.yl = None #yieldloci self.criterion = None #yieldcriterion self.ui.actionOpen.triggered.connect(self.openfile) self.ui.action.triggered.connect(self.about) self.connect(self.ui.actionExit,QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()')) self.ui.pushButton_FC.clicked.connect(self.on_pushButton_FC_clicked_) self.ui.pushButton_YL.clicked.connect(self.on_pushButton_YL_clicked_) def about(self): message = QtGui.QMessageBox.about(self,"About","This is a GUI of FlowCurve and Yield Loci in Sheet Metal Forming. --Hui Zhou") def openfile(self): filenames = QtGui.QFileDialog.getOpenFileNames(self, 'Open file', '/home') for fn in filenames: try: data = File(fn) print "Import %s \n" %(fn) print "Check Temperature:" if data.temp_exp() is not None: temp_n = len(data.temp_exp()) print temp_n else: temp_n = 0 print None print "Check Strain Rate:" if data.rate_exp() is not None: rate_n = len(data.rate_exp()) print rate_n else: rate_n = 0 print None print "Check Strain:" if data.strainT_exp() is not None: strain_n = len(data.strainT_exp()) print strain_n else: strain_n = 0 print None print "Check Stress:" if data.stressT_exp() is not None: stress_n = len(data.stressT_exp()) print stress_n else: stress_n = 0 print None if strain_n !=0 and stress_n !=0 and strain_n == stress_n: if temp_n == rate_n == 0: self.data.setdefault(fn,data) self.ui.comboBox_FN.addItem(fn) if temp_n == rate_n == strain_n: self.data.setdefault(fn,data) self.ui.comboBox_FN.addItem(fn) except IOError: message = QtGui.QMessageBox.warning(self,"Warning","Read File:%s Failed!" %(fn)) def on_comboBox_FN_activated(self): self.fn = self.ui.comboBox_FN.currentText() self.ui.comboBox_FN.setToolTip(self.fn) self.ui.comboBox_FN.setStatusTip(self.fn) def on_comboBox_FC_activated(self): self.model = str(self.ui.comboBox_FC.currentText()) self.ui.pushButton_FC.setToolTip(self.model) self.ui.pushButton_FC.setStatusTip(self.model) if self.model != u'Modified_Zener_Hollomon': self.xdata = None self.ydata = None self.zdata = self.data[self.fn].strainT() self.kdata = self.data[self.fn].stressT() else: self.xdata = self.data[self.fn].temp_exp() self.ydata = self.data[self.fn].rate_exp() self.zdata = self.data[self.fn].strainT_exp() self.kdata = self.data[self.fn].stressT_exp() def on_checkBox_Bounds_clicked(self): flag = self.ui.checkBox_Bounds.isChecked() if flag == True: self.boundsbox.show() if flag == False: self.boundsbox.hide() def on_checkBox_UE_clicked(self): self.on_comboBox_FN_activated() flag = self.ui.checkBox_UE.checkState() if flag == QtCore.Qt.Checked: self.ue = True if flag == QtCore.Qt.Unchecked: self.ue = False ## if flag == QtCore.Qt.Checked: ## try: ## self.xdata = self.data[self.fn].temp() ## self.ydata = self.data[self.fn].rate() ## except: ## self.xdata = None ## self.ydata = None ## self.zdata = self.data[self.fn].strainT() ## self.kdata = self.data[self.fn].stressT() ## return True ## if flag == QtCore.Qt.Unchecked: ## try: ## self.xdata = self.data[self.fn].temp_exp() ## self.ydata = self.data[self.fn].rate_exp() ## except: ## self.xdata = None ## self.ydata = None ## self.zdata = self.data[self.fn].strainT_exp() ## self.kdata = self.data[self.fn].stressT_exp() ## return False def on_pushButton_FC_clicked(self): pass def on_pushButton_FC_clicked_(self): self.ui.graphicsView_FC.clear() self.ui.graphicsView_FC.showGrid(True,True,alpha=0.7) self.on_checkBox_UE_clicked() self.on_comboBox_FC_activated() self.Line = pg.InfiniteLine(movable=True) self.Line.sigPositionChanged.connect(self.LineEdit) self.ui.graphicsView_FC.addItem(self.Line) self.ui.lineEdit_Xval.setText(str(self.Line.value())) self.ui.lineEdit_Xval.textChanged.connect(self.Xval) self.ui.graphicsView_FC.plot(self.zdata,self.kdata) try: bounds = {'Swift':[(float(self.boundsbox.ui.lineEdit_A_Swift_L.text()),float(self.boundsbox.ui.lineEdit_A_Swift_U.text())), (float(self.boundsbox.ui.lineEdit_B_Swift_L.text()),float(self.boundsbox.ui.lineEdit_B_Swift_U.text())), (float(self.boundsbox.ui.lineEdit_C_Swift_L.text()),float(self.boundsbox.ui.lineEdit_C_Swift_U.text()))], 'Voce':[(float(self.boundsbox.ui.lineEdit_A_Voce_L.text()),float(self.boundsbox.ui.lineEdit_A_Voce_U.text())), (float(self.boundsbox.ui.lineEdit_B_Voce_L.text()),float(self.boundsbox.ui.lineEdit_B_Voce_U.text())), (float(self.boundsbox.ui.lineEdit_C_Voce_L.text()),float(self.boundsbox.ui.lineEdit_C_Voce_U.text()))], 'Gosh':[(float(self.boundsbox.ui.lineEdit_A_Gosh_L.text()),float(self.boundsbox.ui.lineEdit_A_Gosh_U.text())), (float(self.boundsbox.ui.lineEdit_B_Gosh_L.text()),float(self.boundsbox.ui.lineEdit_B_Gosh_U.text())), (float(self.boundsbox.ui.lineEdit_C_Gosh_L.text()),float(self.boundsbox.ui.lineEdit_C_Gosh_U.text())), (float(self.boundsbox.ui.lineEdit_D_Gosh_L.text()),float(self.boundsbox.ui.lineEdit_D_Gosh_U.text()))], 'Hockett_Sherby':[(float(self.boundsbox.ui.lineEdit_A_HS_L.text()),float(self.boundsbox.ui.lineEdit_A_HS_U.text())), (float(self.boundsbox.ui.lineEdit_B_HS_L.text()),float(self.boundsbox.ui.lineEdit_B_HS_U.text())), (float(self.boundsbox.ui.lineEdit_C_HS_L.text()),float(self.boundsbox.ui.lineEdit_C_HS_U.text())), (float(self.boundsbox.ui.lineEdit_D_HS_L.text()),float(self.boundsbox.ui.lineEdit_D_HS_U.text()))], 'SwiftVoce':[(float(self.boundsbox.ui.lineEdit_A_Swift_L.text()),float(self.boundsbox.ui.lineEdit_A_Swift_U.text())), (float(self.boundsbox.ui.lineEdit_B_Swift_L.text()),float(self.boundsbox.ui.lineEdit_B_Swift_U.text())), (float(self.boundsbox.ui.lineEdit_C_Swift_L.text()),float(self.boundsbox.ui.lineEdit_C_Swift_U.text())), (float(self.boundsbox.ui.lineEdit_A_Voce_L.text()),float(self.boundsbox.ui.lineEdit_A_Voce_U.text())), (float(self.boundsbox.ui.lineEdit_B_Voce_L.text()),float(self.boundsbox.ui.lineEdit_B_Voce_U.text())), (float(self.boundsbox.ui.lineEdit_C_Voce_L.text()),float(self.boundsbox.ui.lineEdit_C_Voce_U.text())), (0.0,1.0)], } except ValueError: message = QtGui.QMessageBox.warning(self,"Warning","Bounds Setting Type Error!") models = ["Swift","Voce","Gosh","Hockett_Sherby","SwiftVoce","Modified_Zener_Hollomon"] if self.model != u'Modified_Zener_Hollomon': fc = FC(self.zdata,self.kdata,ue=self.ue)#self.on_checkBox_UE_clicked) ans = fc.params(self.model,bounds[self.model]) self.ui.label_FCErrorShow.setText(str(ans[1])) Y = fc.values(self.model,ans[0],self.zdata) y = fc.values(self.model,ans[0],float(self.Line.value())) self.ui.lineEdit_Yval.setText(str(y)) self.ui.graphicsView_FC.plot(self.zdata,Y,pen='r') i = models.index(self.model) for j,p in enumerate(ans[0]): self.ui.treeWidget_FC.topLevelItem(i).child(j).setText(1,str(p)) elif self.xdata and self.ydata is not None: fc = FC(self.zdata,self.kdata) ans = fc.Modified_Zener_HollomonFit(self.xdata,self.ydata,self.zdata,self.kdata) self.ui.label_FCErrorShow.setText(str(ans[1])) Y = fc.values('Modified_Zener_Hollomon',ans[0],self.zdata) y = fc.Modified_Zener_Hollomon(ans[0],sum(self.xdata)/len(self.xdata),sum(self.ydata)/len(self.ydata),float(self.Line.value())) self.ui.lineEdit_Yval.setText(str(y)) self.ui.graphicsView_FC.plot(self.zdata,Y,pen='r') i = models.index(self.model) for j,p in enumerate(ans[0]): self.ui.treeWidget_FC.topLevelItem(i).child(j).setText(1,str(p)) self.fc = fc self.params = ans[0] def LineEdit(self): self.ui.lineEdit_Xval.setText(str(self.Line.value())) def Xval(self): self.Line.setValue(float(self.ui.lineEdit_Xval.text())) if self.model != u'Modified_Zener_Hollomon': y = self.fc.values(self.model,self.params,float(self.ui.lineEdit_Xval.text())) else: y = self.fc.Modified_Zener_Hollomon(self.params,sum(self.xdata)/len(self.xdata),sum(self.ydata)/len(self.ydata),float(self.ui.lineEdit_Xval.text())) self.ui.lineEdit_Yval.setText(str(y)) def on_comboBox_YL_activated(self): criterions = ["Vonmises","Hill48","Yld2000_2d","CPB"] self.criterion = str(self.ui.comboBox_YL.currentText()) self.ui.tabWidget_Input.setCurrentIndex(criterions.index(self.criterion)) self.ui.pushButton_YL.setToolTip(self.criterion) self.ui.pushButton_YL.setStatusTip(self.criterion) def on_pushButton_YL_clicked(self): pass def on_pushButton_YL_clicked_(self): self.ui.graphicsView_YL.clear() self.ui.graphicsView_YL.showGrid(True,True,alpha=0.7) self.ui.graphicsView_YL.setAspectLocked() self.on_comboBox_YL_activated() criterions = ["Vonmises","Hill48","Yld2000_2d","CPB"] try: Inputs = {"Vonmises": [float(self.ui.lineEdit_Vonmises_ay.text())], "Hill48": [float(self.ui.lineEdit_Hill_a0.text()), float(self.ui.lineEdit_Hill_r0.text()), float(self.ui.lineEdit_Hill_r90.text())], "Yld2000_2d": [float(self.ui.lineEdit_Yld_a0.text()), float(self.ui.lineEdit_Yld_a45.text()), float(self.ui.lineEdit_Yld_a90.text()), float(self.ui.lineEdit_Yld_ab.text()), float(self.ui.lineEdit_Yld_r0.text()), float(self.ui.lineEdit_Yld_r45.text()), float(self.ui.lineEdit_Yld_r90.text()), float(self.ui.lineEdit_Yld_rb.text()), float(self.ui.lineEdit_Yld_a.text())], "CPB": [float(self.ui.lineEdit_CPB_a0_T.text()), float(self.ui.lineEdit_CPB_a0_C.text()), float(self.ui.lineEdit_CPB_a90_T.text()), float(self.ui.lineEdit_CPB_a90_C.text()), float(self.ui.lineEdit_CPB_aN_C.text()), float(self.ui.lineEdit_CPB_ab_T.text()), float(self.ui.lineEdit_CPB_ab_C.text()), float(self.ui.lineEdit_CPB_a.text())], } except ValueError: message = QtGui.QMessageBox.warning(self,"Warning","Inputs Setting Type Error!") yl = YL() if self.criterion == "Vonmises" and Inputs["Vonmises"] is not None: point = yl.Vonmises(Inputs["Vonmises"][0]) self.ui.label_YLErrorShow.setText(str(0)) coefficients = yl.params("Vonmises") self.ui.graphicsView_YL.plot(point['X'],point['Y']) if self.criterion == "Hill48" and Inputs["Hill48"] is not None: [a0,r0,r90] = Inputs["Hill48"] point = yl.Hill48(a0,None,r0,r90) self.ui.label_YLErrorShow.setText(str(0)) coefficients = yl.params("Hill48") self.ui.graphicsView_YL.plot(point['X'],point['Y']) i = criterions.index(self.criterion) for j,p in enumerate(coefficients): self.ui.treeWidget_YL.topLevelItem(i).child(j).setText(1,str(p)) if self.criterion == "Yld2000_2d" and Inputs["Yld2000_2d"] is not None: [a0,a45,a90,ab,r0,r45,r90,rb,a]=Inputs["Yld2000_2d"] point = yl.Yld2000_plot(a0,a45,a90,ab,r0,r45,r90,rb,a) coefficients = yl.params("Yld2000") #Yld2000 err = yl.Yld2000_err(coefficients,a0,a45,a90,ab,r0,r45,r90,rb,a) error = np.sqrt(sum(np.square(err))/len(err)) self.ui.label_YLErrorShow.setText(str(error)) self.ui.graphicsView_YL.plot(point['X'],point['Y']) i = criterions.index(self.criterion) for j,p in enumerate(coefficients): self.ui.treeWidget_YL.topLevelItem(i).child(j).setText(1,str(p)) if self.criterion == "CPB" and Inputs["CPB"] is not None: [a0_T,a0_C,a90_T,a90_C,aN_C,ab_T,ab_C,a] = Inputs["CPB"] point = yl.CPB_plot(a0_T,a0_C,a90_T,a90_C,aN_C,ab_T,ab_C,a) coefficients = yl.params("CPB") err = yl.CPB_err(coefficients,a0_T,a0_C,a90_T,a90_C,aN_C,ab_T,ab_C,a) error = np.sqrt(sum(np.square(err))/len(err)) self.ui.label_YLErrorShow.setText(str(error)) self.ui.graphicsView_YL.plot(point['X'],point['Y']) i = criterions.index(self.criterion) for j,p in enumerate(coefficients): self.ui.treeWidget_YL.topLevelItem(i).child(j).setText(1,str(p))
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.capturador = Capturador() self.ui.pushButton.clicked.connect(self.click) self.ui.pushButton_2.clicked.connect(self.mostrar) self.ui.actionGuardar.triggered.connect(self.guardar) @Slot() def guardar(self): file = QFileDialog.getSaveFileName(self, 'Guardar Archivo...', '.', 'TXT (*.txt)') print(file) self.capturador.guardar(file[0]) @Slot() def mostrar(self): self.capturador.mostrar() @Slot() def click(self): id = self.ui.lineEdit.text() origenX = self.ui.lineEdit_2.text() origenY = self.ui.lineEdit_6.text() destinoX = self.ui.lineEdit_3.text() destinoY = self.ui.lineEdit_7.text() velocidad = self.ui.lineEdit_4.text() red = self.ui.lineEdit_5.text() green = self.ui.lineEdit_8.text() blue = self.ui.lineEdit_9.text() print(id, origenX, origenY, destinoX, destinoY, velocidad, red, green, blue) partiula = Particula() partiula.id = id partiula.origenX = int(origenX) partiula.origenY = int(origenY) partiula.destinoX = int(destinoX) partiula.destinoY = int(destinoY) partiula.distancia = math.sqrt( pow((int(destinoX) - int(origenX)), 2) + pow((int(destinoY) - int(origenY)), 2)) partiula.red = int(red) partiula.green = int(green) partiula.blue = int(blue) partiula.velocidad = int(velocidad) self.capturador.agregar(partiula) msg = QMessageBox.information( self, 'Exito', 'Se agrego paquete con exito' ) #Ventana de mensaje de la libreria QMessageBox self.ui.lineEdit.clear() #Limpiar campos self.ui.lineEdit_2.clear() self.ui.lineEdit_3.clear() self.ui.lineEdit_4.clear() self.ui.lineEdit_5.clear() self.ui.lineEdit_6.clear() self.ui.lineEdit_7.clear() self.ui.lineEdit_8.clear() self.ui.lineEdit_9.clear()