class ImageView(QtGui.QScrollArea): """The actual image view widget.""" def __init__(self, parent=None, mainwindow=None): """Initialize.""" QtGui.QScrollArea.__init__(self, parent) # Define the image self.image = QLabel() self.image.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored) self.image.setScaledContents(True) self.image.adjustSize() self.image.setHidden(True) self.setWidget(self.image) self.setBackgroundRole(QtGui.QPalette.Dark) # Variables to store self.parent = parent self.mainwindow = mainwindow self.panning = None self.scanning = None def update_image(self, pixmap): """Update the image.""" self.image.setHidden(False) self.image.setPixmap(pixmap) self.image.adjustSize() self.image.setCursor(QCursor(Qt.CrossCursor)) self.image.update() def wheelEvent(self, wheel): """Handle mouse wheels.""" # This passes the wheel event to MainViewer() wheel.ignore()
def fileOpen(self): """ open a HDF5 file, show pictures as tabs """ fname = QFileDialog.getOpenFileName(self, "Open data file", ".", "HDF5 files (*.h5, *.hdf5)") if not fname: return import h5py f = h5py.File(str(fname), "r") for grp in f.keys(): for img in f[grp].keys(): ds1 = f[grp][img] # if ds1.get('attr', None) is None: continue if ds1.attrs.get("CLASS", None) != "IMAGE": continue # the fourth alpha, needs be 255. d1 = np.ones(ds1.shape[:2] + (4,), dtype=np.uint8) * 255 d1[:, :, :3] = np.asarray(ds1) wid = QWidget() l = QVBoxLayout(wid) imageLabel = QLabel(self) imageLabel.setText("Text") # imageLabel im1 = Image.fromarray(d1) pxm = QPixmap.fromImage(ImageQt.ImageQt(im1)) # pxm.save("j.png") imageLabel.setPixmap(pxm) imageLabel.adjustSize() l.addWidget(imageLabel) self.widtab.addTab(wid, "%s:%s" % (grp, img)) f.close()
def fileOpen(self): """ open a HDF5 file, show pictures as tabs """ fname = QFileDialog.getOpenFileName(self, "Open data file", '.', "HDF5 files (*.h5, *.hdf5)") if not fname: return import h5py f = h5py.File(str(fname), 'r') for grp in f.keys(): for img in f[grp].keys(): ds1 = f[grp][img] #if ds1.get('attr', None) is None: continue if ds1.attrs.get('CLASS', None) != 'IMAGE': continue # the fourth alpha, needs be 255. d1 = np.ones(ds1.shape[:2] + (4, ), dtype=np.uint8) * 255 d1[:, :, :3] = np.asarray(ds1) wid = QWidget() l = QVBoxLayout(wid) imageLabel = QLabel(self) imageLabel.setText("Text") #imageLabel im1 = Image.fromarray(d1) pxm = QPixmap.fromImage(ImageQt.ImageQt(im1)) #pxm.save("j.png") imageLabel.setPixmap(pxm) imageLabel.adjustSize() l.addWidget(imageLabel) self.widtab.addTab(wid, "%s:%s" % (grp, img)) f.close()
class ImageView(Window): def __init__(self, base): Window.__init__(self, base, i18n.get('image_preview')) self.loader = BarLoadIndicator() self.view = QLabel() self.view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.view.setScaledContents(True) scroll_area = QScrollArea() scroll_area.setBackgroundRole(QPalette.Dark) scroll_area.setWidget(self.view) scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.error_label = QLabel(i18n.get('error_loading_image')) self.error_label.setAlignment(Qt.AlignHCenter) self.error_label.setStyleSheet("QLabel {background-color: #ffecec;}") layout = QVBoxLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.loader) layout.addWidget(self.error_label) layout.addWidget(scroll_area) self.setLayout(layout) self.__clear() def __clear(self): self.resize(350, 350) self.view.setPixmap(QPixmap()) def closeEvent(self, event): event.ignore() self.__clear() self.hide() def start_loading(self): self.loader.setVisible(True) self.error_label.setVisible(False) self.show() def loading_finished(self, url): self.loader.setVisible(False) pix = self.base.load_image(url, True) self.view.setPixmap(pix) self.view.adjustSize() self.resize(pix.width() + 2, pix.height() + 2) self.show() def error(self): self.loader.setVisible(False) self.error_label.setVisible(True)
class VentanaMenu(QMainWindow): def __init__(self): super(VentanaMenu, self).__init__() self.inicializar() def inicializar(self): self.titulo = QLabel("PROCESAMIENTO DIGITAL DE IMAGENES", self) self.titulo.move(50,50) self.titulo.adjustSize() self.filtrar = QPushButton("Filtrar", self) self.filtrar.move(100,100) self.filtrar.clicked.connect(self.abrirFiltrar) self.analizar = QPushButton("Analizar", self) self.analizar.move(100,150) self.analizar.clicked.connect(self.abrirAnalizar) self.invertir = QPushButton("Invertir", self) self.invertir.move(100,200) self.invertir.clicked.connect(self.abrirInvertir) self.setWindowTitle("Transformada de Fourier") self.resize(300,300) self.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) self.show() def abrirFiltrar(self): self.ventanaFiltrar = VentanaFiltrar(self) def abrirAnalizar(self): archivo = QFileDialog(self) ruta = archivo.getOpenFileName(self, 'Seleccionar imagen', '', "Images (*.png *.gif *.jpg *.bmp)") if not ruta.isEmpty(): try: from core import transformar img1, img2 = transformar(str(ruta)) ruta1 = archivo.getSaveFileName(self, "Guardar Magnitud", '', "Images (*.png *.gif *.jpg *.bmp)") img1.save(str(ruta1) + ".png") ruta2 = archivo.getSaveFileName(self, "Guardar Fase", '', "Images (*.png *.gif *.jpg *.bmp)") img2.save(str(ruta2) + ".png") except ImportError: resp = QMessageBox.information(self, 'Error', 'Hubo un error inesperado', QMessageBox.Ok, QMessageBox.NoButton) else: resp = QMessageBox.information(self, 'Error', 'No ha elegido imagenes', QMessageBox.Ok, QMessageBox.NoButton) def abrirInvertir(self): self.ventanaInversa = VentanaInvertir(self)
class VentanaFiltrar(QDialog): def __init__(self, padre): super(VentanaFiltrar, self).__init__(padre) self.inicializar() def inicializar(self): self.titulo = QLabel("SELECCIONE EL FILTRO A APLICAR", self) self.titulo.move(50,50) self.titulo.adjustSize() self.filtros = QComboBox(self) self.filtros.move(100,100) self.filtros.sizeAdjustPolicy() self.filtros.addItem("Low pass filter") self.filtros.addItem("High pass filter") self.filtros.addItem("Gaussian filter") self.filtros.addItem("Pyramidal filter") self.filtros.addItem("Sinc filter") self.seleccionar = QPushButton("Seleccionar imagen", self) self.seleccionar.move(100,200) self.seleccionar.clicked.connect(self.filtrar) self.setWindowTitle("Filtrar una imagen") self.resize(300,300) self.setWindowModality(1) self.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) self.show() def filtrar(self): archivo = QFileDialog(self) ruta = archivo.getOpenFileName(self, 'Seleccionar imagen', '', "Images (*.png *.gif *.jpg *.bmp)") if not ruta.isEmpty(): try: from core import filtrar img = filtrar(str(ruta), str(self.filtros.currentText())) ruta1 = archivo.getSaveFileName(self, "Guardar imagen", '', "Images (*.png *.gif *.jpg *.bmp)") img.save(str(ruta1) + ".png") except ImportError: resp = QMessageBox.information(self, 'Error', 'Hubo un error inesperado', QMessageBox.Ok, QMessageBox.NoButton) else: resp = QMessageBox.information(self, 'Error', 'No ha elegido imagenes', QMessageBox.Ok, QMessageBox.NoButton)
class VentanaInvertir(QDialog): def __init__(self, padre): super(VentanaInvertir, self).__init__(padre) self.inicializar() def inicializar(self): self.titulo = QLabel("SELECCIONE LAS IMAGENES DE MAGNITUD Y FASE", self) self.titulo.move(50,50) self.titulo.adjustSize() self.magnitud = QPushButton("magnitud", self) self.magnitud.move(100,200) self.magnitud.clicked.connect(self.seleccionar) """ self.fase = QPushButton("fase", self) self.fase.move(100,150) self.fase.clicked.connect(self.seleccionar) """ self.setWindowTitle("Transformada Inversa") self.resize(300,300) self.setWindowModality(1) self.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed) self.show() def seleccionar(self): archivo = QFileDialog(self) ruta1 = archivo.getOpenFileName(self, 'Seleccionar magnitud', '', "Images (*.png *.gif *.jpg *.bmp)") ruta2 = archivo.getOpenFileName(self, 'Seleccionar fase', '', "Images (*.png *.gif *.jpg *.bmp)") if not ruta1.isEmpty() and not ruta2.isEmpty(): from core import invertir, NoCorrespondenError try: img = invertir((str(ruta1), str(ruta2))) ruta3 = archivo.getSaveFileName(self, 'Guardar imagen', '', "Images (*.png *.gif *.jpg *.bmp)") img.save(str(ruta3) + ".png") except NoCorrespondenError: resp = QMessageBox.information(self, 'Error', 'Las imagenes no corresponden', QMessageBox.Ok, QMessageBox.NoButton) else: resp = QMessageBox.information(self, 'Error', 'No ha elegido imagenes', QMessageBox.Ok, QMessageBox.NoButton)
def _inicializar(self): self.setWindowTitle("Algoritmos de planificacion ") #------------------------------------# # ELEMENTOS DEL PANEL SUPERIOR # #------------------------------------# tituloS = QLabel("DIAGRAMA DE GANTT") tituloS.adjustSize() fila1 = QHBoxLayout() fila2 = QHBoxLayout() fila1.addWidget(tituloS) fila2.addWidget(self.tablaGantt) cajaSuperior = QVBoxLayout() cajaSuperior.addLayout(fila1) cajaSuperior.addLayout(fila2) #------------------------------------# # ELEMENTOS DEL PANEL INFERIOR # #------------------------------------# tituloI = QLabel("DATOS DE LOS PROCESOS") tituloI.adjustSize() fila3 = QHBoxLayout() fila4 = QHBoxLayout() fila5 = QHBoxLayout() fila3.addWidget(tituloI) fila4.addWidget(self.tablaDatos) fila5.addWidget(self.iniciar) fila5.addWidget(self.bloquear) cajaInferior = QVBoxLayout() cajaInferior.addLayout(fila3) cajaInferior.addLayout(fila4) cajaInferior.addLayout(fila5) #------------------------------------# #agregar el segundo nivel de layout al panel panelSuperior = QFrame(self) panelSuperior.setFrameShape(QFrame.StyledPanel) panelSuperior.setLayout(cajaSuperior) #agregar el segundo nivel de layout al panel panelInferior = QFrame(self) panelInferior.setFrameShape(QFrame.StyledPanel) panelInferior.setLayout(cajaInferior) #agregar el panel al separador separador = QSplitter(Qt.Vertical) separador.addWidget(panelSuperior) separador.addWidget(panelInferior) #agregar el separador al primer layout caja = QVBoxLayout(self) caja.addWidget(separador) #agregar el layout a la ventana self.setLayout(caja) self.setFixedSize(1200, 900) self._configurar() self.show()
class MainWindow(QtGui.QMainWindow): """Implements the main window for dame.""" def __init__(self, parent=None): """Initialize the window.""" QtGui.QMainWindow.__init__(self, parent) self.setupUi() def setupUi(self): """Create the basic UI.""" self.setWindowTitle("dame") # TODO: Set window icon self.create_actions() self.create_statusbar() self.mainview = MainViewer(parent=self) # # Connect an action now that mainview is set # self.mode_group.triggered.connect(self.mainview.toggleComparison) # TODO: This is the start of using tabbed windows # self.mdiArea = QtGui.QMdiArea(parent=self) # first = self.mdiArea.addSubWindow(self.scrollArea) # self.mdiArea.setViewMode(QtGui.QMdiArea.TabbedView) # self.mdiArea.setTabsMovable(True) # self.setCentralWidget(self.mdiArea) # first.setWindowTitle("foo") self.setCentralWidget(self.mainview) # Create popup windows (for zoomer and panner) self.zoom_win = QtGui.QWidget(self, Qt.Window | Qt.Tool) self.zoom_win.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.zoom_win_im = QLabel() self.zoom_win_im.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored) # self.zoom_win.resize(150,150) # self.zoom_win.show() zoomer_layout = QtGui.QGridLayout() zoomer_layout.setContentsMargins(0, 0, 0, 0) zoomer_layout.addWidget(self.zoom_win_im) self.zoom_win.setLayout(zoomer_layout) # TODO: panner # Create note dock widget self.note_widget = QtGui.QDockWidget("Notes", parent=self) self.note_text = QtGui.QTextEdit(parent=self.note_widget) self.note_widget.setWidget(self.note_text) self.note_widget.setFeatures( QtGui.QDockWidget.DockWidgetClosable | QtGui.QDockWidget.DockWidgetMovable | QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetVerticalTitleBar) self.addDockWidget(Qt.BottomDockWidgetArea, self.note_widget) self.note_widget.close() self.note_action = self.note_widget.toggleViewAction() self.note_action.setText("Display notes") self.note_action.setStatusTip("Show notes about the SIR image") # Create the menus self.create_menus() def create_statusbar(self): """Create the statusbar.""" self.statusBar().showMessage("Ready") # The individual info self.status_sing_pixinfo = QLabel() self.status_sing_coord = QLabel() self.status_left_pixinfo = QLabel() self.status_right_pixinfo = QLabel() self.status_comp_coord = QLabel() # The groups self.status_sing_layout = QtGui.QHBoxLayout() self.status_sing_layout.addWidget(self.status_sing_coord, 0, Qt.AlignRight) self.status_sing_layout.addWidget(self.status_sing_pixinfo, 1, Qt.AlignRight) self.status_comp_layout = QtGui.QHBoxLayout() self.status_comp_layout.addWidget(self.status_left_pixinfo, 0) self.status_comp_layout.addWidget(self.status_comp_coord, 1) self.status_comp_layout.addWidget(self.status_right_pixinfo, 0) self.status_sing_layout.setContentsMargins(0, 0, 0, 0) self.status_comp_layout.setContentsMargins(0, 0, 0, 0) self.status_sing = QtGui.QWidget() self.status_sing.setLayout(self.status_sing_layout) self.status_comp = QtGui.QWidget() self.status_comp.setLayout(self.status_comp_layout) # The stacked widget (to alternate between single and comparison modes) self.status_stacked = QtGui.QStackedWidget() self.status_stacked.addWidget(self.status_sing) self.status_stacked.addWidget(self.status_comp) self.status_stacked.setCurrentIndex(0) self.statusBar().addWidget(self.status_stacked) def create_actions(self): """Define the actions.""" self.about_action = QAction("&About", self) self.about_action.setStatusTip("About dame") self.about_action.setMenuRole(QAction.AboutRole) self.about_action.triggered.connect(self.show_about) self.open_action = QAction("&Open", self) self.open_action.setStatusTip("Open a SIR file") self.open_action.setShortcut(QtGui.QKeySequence.Open) self.open_action.triggered.connect(self.open_file) self.close_action = QAction("&Close", self) self.close_action.setStatusTip("Close current SIR file") self.close_action.setShortcut(QtGui.QKeySequence.Close) self.close_action.triggered.connect(self.close_file) self.exit_action = QAction("E&xit", self) self.exit_action.setMenuRole(QAction.QuitRole) self.exit_action.setStatusTip("Exit dame") self.exit_action.setShortcut(QtGui.QKeySequence("Ctrl+Q")) self.exit_action.triggered.connect(self.close) self.prop_action = QAction("SIR header", self) self.prop_action.setStatusTip("Display SIR header information") self.prop_action.triggered.connect(self.print_header) self.range_action = QAction("Image range", self) self.range_action.setStatusTip("Set image display range") self.range_action.triggered.connect(self.show_range) self.zoomer_action = QAction("Enable zoomer window", self) self.zoomer_action.setStatusTip(("Show zoomer window for " "magnified viewing")) self.zoomer_action.setCheckable(True) self.zoomer_action.triggered.connect(self.update_zoomer_opts) self.zoom_factor_label_action = QAction("Zoom factor", self) self.zoom_factor_label_action.setEnabled(False) self.zoom_factor_1_action = QAction("2x zoom", self) self.zoom_factor_2_action = QAction("4x zoom", self) self.zoom_factor_3_action = QAction("8x zoom", self) self.zoom_factor_4_action = QAction("16x zoom", self) self.zoom_factor_1_action.setStatusTip("Magnify zoom region by 2x") self.zoom_factor_2_action.setStatusTip("Magnify zoom region by 4x") self.zoom_factor_3_action.setStatusTip("Magnify zoom region by 8x") self.zoom_factor_4_action.setStatusTip("Magnify zoom region by 16x") self.zoom_factor_1_action.setCheckable(True) self.zoom_factor_2_action.setCheckable(True) self.zoom_factor_3_action.setCheckable(True) self.zoom_factor_4_action.setCheckable(True) self.zoom_size_label_action = QAction("Zoom region size", self) self.zoom_size_label_action.setEnabled(False) self.zoom_size_1_action = QAction("9x9 window", self) self.zoom_size_2_action = QAction("17x17 window", self) self.zoom_size_3_action = QAction("29x29 window", self) self.zoom_size_4_action = QAction("45x45 window", self) self.zoom_size_5_action = QAction("65x65 window", self) self.zoom_size_1_action.setStatusTip("Set zoom region to 9x9 pixels") self.zoom_size_2_action.setStatusTip("Set zoom region to 17x17 pixels") self.zoom_size_3_action.setStatusTip("Set zoom region to 29x29 pixels") self.zoom_size_4_action.setStatusTip("Set zoom region to 45x45 pixels") self.zoom_size_5_action.setStatusTip("Set zoom region to 65x65 pixels") self.zoom_size_1_action.setCheckable(True) self.zoom_size_2_action.setCheckable(True) self.zoom_size_3_action.setCheckable(True) self.zoom_size_4_action.setCheckable(True) self.zoom_size_5_action.setCheckable(True) # Group zoomer actions and connect slots self.zoom_factor_group = QtGui.QActionGroup(self) self.zoom_factor_group.addAction(self.zoom_factor_1_action) self.zoom_factor_group.addAction(self.zoom_factor_2_action) self.zoom_factor_group.addAction(self.zoom_factor_3_action) self.zoom_factor_group.addAction(self.zoom_factor_4_action) self.zoom_factor_group.triggered.connect(self.update_zoomer_opts) self.zoom_size_group = QtGui.QActionGroup(self) self.zoom_size_group.addAction(self.zoom_size_1_action) self.zoom_size_group.addAction(self.zoom_size_2_action) self.zoom_size_group.addAction(self.zoom_size_3_action) self.zoom_size_group.addAction(self.zoom_size_4_action) self.zoom_size_group.addAction(self.zoom_size_5_action) self.zoom_size_group.triggered.connect(self.update_zoomer_opts) # # Mode actions # self.mode_group = QtGui.QActionGroup(self) # self.mode_single_action = QAction("Single image", self.mode_group) # self.mode_dual_action = QAction("Two images", self.mode_group) # self.mode_single_action.setCheckable(True) # self.mode_dual_action.setCheckable(True) # self.mode_single_action.setStatusTip("Display a single image") # self.mode_dual_action.setStatusTip("Display two images for comparison") # self.mode_single_action.setChecked(True) # #self.mode_group.triggered.connect(self.mainview.toggleComparison) # Moved later # http://stackoverflow.com/questions/11643221/are-there-default-icons-in-pyqt-pyside # TODO: Add icons in a better way. See how Picard does it. QIcon.setThemeName("gnome") # TODO: temporary self.open_action.setIcon(QIcon.fromTheme("document-open")) self.close_action.setIcon(QIcon.fromTheme("window-close")) self.exit_action.setIcon(QIcon.fromTheme("application-exit")) self.about_action.setIcon(QIcon.fromTheme("help-about")) def create_menus(self): """Setup the menus.""" menu = self.menuBar().addMenu("&File") menu.addAction(self.open_action) menu.addAction(self.close_action) menu.addSeparator() # menu.addAction(self.mode_single_action) # menu.addAction(self.mode_dual_action) # menu.addSeparator() menu.addAction(self.exit_action) menu = self.menuBar().addMenu("Image") menu.addAction(self.prop_action) menu.addAction(self.range_action) menu.addAction(self.note_action) # submenu = menu.addMenu("Mode") # submenu.addAction(self.mode_single_action) # submenu.addAction(self.mode_split_action) # submenu.addAction(self.mode_fade_action) menu = self.menuBar().addMenu("Zoomer") menu.addAction(self.zoomer_action) menu.addSeparator() menu.addAction(self.zoom_factor_label_action) menu.addAction(self.zoom_factor_1_action) menu.addAction(self.zoom_factor_2_action) menu.addAction(self.zoom_factor_3_action) menu.addAction(self.zoom_factor_4_action) menu.addSeparator() menu.addAction(self.zoom_size_label_action) menu.addAction(self.zoom_size_1_action) menu.addAction(self.zoom_size_2_action) menu.addAction(self.zoom_size_3_action) menu.addAction(self.zoom_size_4_action) menu.addAction(self.zoom_size_5_action) menu = self.menuBar().addMenu("&Help") menu.addAction(self.about_action) # Deactivate menus by default self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def open_file(self): """Display open file dialog.""" filename = QtGui.QFileDialog.getOpenFileName(self, "Open SIR file", QtCore.QDir.homePath(), ("SIR files (*.sir *.ave)" ";;Any file (*)")) if py_binding == 'PySide': filename = filename[0] if filename: self.load_sir(filename) def load_sir(self, filename): """Load in the SIR file.""" if os.access(filename, os.F_OK | os.R_OK): self.statusBar().showMessage("Loading") self.mainview.load_sir(filename) self.statusBar().showMessage("Loaded", 2000) # Activate menus self.range_action.setEnabled(True) self.prop_action.setEnabled(True) self.close_action.setEnabled(True) else: logging.warning("Can't open {}".format(filename)) # TODO: Alert the user via GUI @QtCore.Slot() def close_file(self): """Close file.""" logging.info("Closing SIR file") self.mainview.close_file() self.statusBar().showMessage("SIR closed", 2000) # That was the last file, so disable stuff if len(self.mainview.sir_files) == 0: self.status_stacked.setVisible(False) self.zoom_win.hide() # Deactivate menus self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def show_about(self): """Display about popup.""" about_text = """ Dame {} Copyright 2014 Richard Lindsley Dame is a SIR file viewer""".format(version_string) QMessageBox.about(self, "About", dedent(about_text)) @QtCore.Slot() def show_range(self): """Display image range popup.""" win = RangeWindow() win.min_text.setText( str(self.mainview.sir_files[self.mainview.cur_tab]['vmin'])) win.max_text.setText( str(self.mainview.sir_files[self.mainview.cur_tab]['vmax'])) if win.exec_() == QtGui.QDialog.Accepted: win_range = win.getRange() self.mainview.sir_files[self.mainview.cur_tab]['vmin'] = \ win_range[0] self.mainview.sir_files[self.mainview.cur_tab]['vmax'] = \ win_range[1] self.mainview.update_image(self.mainview.cur_tab) self.mainview.update_view() @QtCore.Slot() def print_header(self): """Display SIR header info.""" sir_head = libsir.print_sir_head( self.mainview.sir_files[self.mainview.cur_tab]['header']) # TODO: Maybe make this a modeless dialog instead of modal? Use a dock # widget? box = QMessageBox() box.setText(dedent(sir_head)) box.setIcon(QMessageBox.Information) box.exec_() def update_zoomer(self): """Update the zoomer, both the image as well as the popup.""" cur_tab = self.mainview.cur_tab if 'pix_loc' not in self.mainview.sir_files[cur_tab]: return try: loc = self.mainview.sir_files[cur_tab]['pix_loc'] rect_w = self.mainview.sir_files[cur_tab]['zoomer_size'] winsize = rect_w * \ self.mainview.sir_files[cur_tab]['zoomer_factor'] if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'].copy(), self.mainview.sir_files['right']['pixmap'].copy()) else: pixmaps = \ (self.mainview.sir_files[cur_tab]['pixmap'].copy(),) for pixmap_i, pixmap in enumerate(pixmaps): # Upper left corner if loc.x() < rect_w / 2: rect_x = -0.5 elif loc.x() > pixmap.width() - rect_w / 2: rect_x = pixmap.width() - rect_w - 0.5 else: rect_x = loc.x() - rect_w / 2 if loc.y() < rect_w / 2: rect_y = -0.5 elif loc.y() > pixmap.height() - rect_w / 2: rect_y = pixmap.height() - rect_w - 0.5 else: rect_y = loc.y() - rect_w / 2 rect_x += 1 rect_y += 1 # Draw the image with the zoomer region outlined p = QtGui.QPainter() p.begin(pixmap) p.setPen(QtGui.QColor("#FFFFFF")) # White stroke p.drawRect(rect_x, rect_y, rect_w, rect_w) p.end() if cur_tab in ("left", "right", "cross"): self.mainview.single_image.image.setPixmap(pixmap) elif cur_tab in ("split", ): if pixmap_i == 0: self.mainview.left_image.image.setPixmap(pixmap) elif pixmap_i == 1: self.mainview.right_image.image.setPixmap(pixmap) else: logging.warning("pixmap_i is {}".format(pixmap_i)) # Update the zoomer window if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'], self.mainview.sir_files['right']['pixmap']) else: pixmaps = (self.mainview.sir_files[cur_tab]['pixmap'], ) if len(pixmaps) == 2: zoom_pixmap = QPixmap(2 * winsize, winsize) for pixmap_i, pixmap_src in enumerate(pixmaps): # extract the zoomer region pixmap = pixmap_src.copy(rect_x, rect_y, rect_w, rect_w) # scale it pixmap = pixmap.scaled(winsize, winsize, Qt.KeepAspectRatioByExpanding) # Add crosshair to zoomer window; note that the crosshair # won't be centered if the region is at the edges p = QtGui.QPainter() p.begin(pixmap) # Highlight selected pixel # p.setPen(QtGui.QColor("#000000")) # Black stroke p.setPen(QtGui.QColor("#FFFFFF")) # White stroke zoom_fac = self.mainview.sir_files[cur_tab]['zoomer_factor'] # Top left of magnified pixel mag_pix = (zoom_fac * (loc.x() - rect_x + 1) - zoom_fac / 2, zoom_fac * (loc.y() - rect_y + 1) - zoom_fac / 2) # Center of magnified pixel mag_pix_cen = (zoom_fac * (loc.x() - rect_x + 1), zoom_fac * (loc.y() - rect_y + 1)) p.drawRect(mag_pix[0], mag_pix[1], zoom_fac, zoom_fac) # Draw crosshairs p.setPen(QtGui.QColor("#FFFFFF")) # White stroke # vertical line, top p.drawLine(mag_pix_cen[0], 0, mag_pix_cen[0], mag_pix[1] - 1) # vertical line, bottom p.drawLine(mag_pix_cen[0], mag_pix[1] + zoom_fac, mag_pix_cen[0], winsize - 0) # horizontal line, left p.drawLine(0, mag_pix_cen[1], mag_pix[0] - 1, mag_pix_cen[1]) # horizontal line, right p.drawLine(mag_pix[0] + zoom_fac, mag_pix_cen[1], winsize - 0, mag_pix_cen[1]) p.end() if len(pixmaps) == 1: self.zoom_win_im.setPixmap(pixmap) else: p = QtGui.QPainter(zoom_pixmap) p.drawPixmap(pixmap_i * winsize, 0, pixmap) self.zoom_win_im.setPixmap(zoom_pixmap) self.zoom_win_im.setHidden(False) self.zoom_win_im.adjustSize() except KeyError as err: logging.warning("Can't find {}".format(err)) def update_statusbar(self): """Update the status bar.""" if self.mainview.cur_tab in ("left", "right"): vmin = self.mainview.sir_files[self.mainview.cur_tab]['vmin'] vmax = self.mainview.sir_files[self.mainview.cur_tab]['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(0) self.status_sing_pixinfo.setText("min: {}, max: {}".format( vmin, vmax)) self.status_sing_coord.setVisible(False) elif self.mainview.cur_tab in ("split", "fade"): vmin_l = self.mainview.sir_files['left']['vmin'] vmax_l = self.mainview.sir_files['left']['vmax'] vmin_r = self.mainview.sir_files['right']['vmin'] vmax_r = self.mainview.sir_files['right']['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(1) self.status_left_pixinfo.setText("min: {} max: {}".format( vmin_l, vmax_l)) self.status_right_pixinfo.setText("min: {} max: {}".format( vmin_r, vmax_r)) self.status_comp_coord.setVisible(False) def update_statusbar_pos(self, x_im, y_im): """Update with position at image index x, y.""" self.statusBar().clearMessage() nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy # Convert from 0-based to 1-based indexing # (I've double-checked the values returned here using sir_util2a) y = nsy - y_im # Convert image y coord to SIR y coord x = x_im + 1 if x > 0 and y > 0 and x <= nsx and y <= nsy: # Note that sir_data is 0-based indexing, but pix2latlon is 1-based cur_sir = self.mainview.sir_files[self.mainview.cur_tab] lon, lat = libsir.pix2latlon(x, y, cur_sir['header']) if self.mainview.cur_tab in ("left", "right"): self.status_sing_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "value = {:0.4f}").format( x, y, lat, lon, cur_sir['data'][y_im, x_im]) self.status_sing_coord.setText(stat_text) elif self.mainview.cur_tab in ("split", "fade"): left_sir = self.mainview.sir_files['left'] right_sir = self.mainview.sir_files['right'] self.status_comp_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "left value = {:0.4f} " "right value = {:0.4f}").format( x, y, lat, lon, left_sir['data'][y_im, x_im], right_sir['data'][y_im, x_im]) self.status_comp_coord.setText(stat_text) def sizeHint(self): """Override the suggested size.""" return QtCore.QSize(1000, 800) # Menu events @QtCore.Slot() def update_zoomer_opts(self, draw_win=True): """Given a menu change, this sets zoomer options and updates.""" file_dict = self.mainview.sir_files[self.mainview.cur_tab] # Is zoomer enabled? file_dict['zoomer_on'] = self.zoomer_action.isChecked() # Find the zoom factor zfactor = self.zoom_factor_group.checkedAction() if zfactor is self.zoom_factor_1_action: file_dict['zoomer_factor'] = 2 elif zfactor is self.zoom_factor_2_action: file_dict['zoomer_factor'] = 4 elif zfactor is self.zoom_factor_3_action: file_dict['zoomer_factor'] = 8 elif zfactor is self.zoom_factor_4_action: file_dict['zoomer_factor'] = 16 # Find the zoom size zsize = self.zoom_size_group.checkedAction() if zsize is self.zoom_size_1_action: file_dict['zoomer_size'] = 9 elif zsize is self.zoom_size_2_action: file_dict['zoomer_size'] = 17 elif zsize is self.zoom_size_3_action: file_dict['zoomer_size'] = 29 elif zsize is self.zoom_size_4_action: file_dict['zoomer_size'] = 45 elif zsize is self.zoom_size_5_action: file_dict['zoomer_size'] = 65 if draw_win: # Compute zoomer window size and show/hide it winsize = file_dict['zoomer_size'] * file_dict['zoomer_factor'] if self.mainview.cur_tab == "split": self.zoom_win.resize(2 * winsize, winsize) self.zoom_win.setFixedSize(2 * winsize, winsize) else: self.zoom_win.resize(winsize, winsize) self.zoom_win.setFixedSize(winsize, winsize) if file_dict['zoomer_on']: self.zoom_win.show() else: self.zoom_win.hide() # Update zoomer self.update_zoomer() # Keyboard events def keyPressEvent(self, key): """Handle some keypresses.""" if len(self.mainview.sir_files) == 0: key.ignore() return if 'pix_loc' not in self.mainview.sir_files[self.mainview.cur_tab]: # Don't do anything if we don't have a coord yet key.ignore() return # Increment im_pos if valid key # Note that im_pos is 0-based, so # it ranges from 0 to nsx-1/nsy-1 inclusive im_pos = self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy delta = 5 if key.modifiers() == Qt.ShiftModifier else 1 if key.key() == Qt.Key_J: # Down if im_pos.y() + delta < nsy: im_pos.setY(im_pos.y() + delta) elif key.key() == Qt.Key_K: # Up if im_pos.y() - delta >= 0: im_pos.setY(im_pos.y() - delta) elif key.key() == Qt.Key_H: # Left if im_pos.x() - delta >= 0: im_pos.setX(im_pos.x() - delta) elif key.key() == Qt.Key_L: # Right if im_pos.x() + delta < nsx: im_pos.setX(im_pos.x() + delta) else: key.ignore() return # Update stuff with our new position self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] = im_pos self.update_zoomer() self.update_statusbar_pos(im_pos.x(), im_pos.y())
class Ventana(QWidget): ''' Ventana de interfaz grafica para la aplicacion ''' def __init__(self): super(Ventana, self).__init__() self._CLIENTE = "Cliente" self._SERVIDOR = "Servidor" self.rol = "" self.pasos = [] self.mensaje = [] self.labelSemanticaT = QLabel("Semantica: ") self.labelSemanticaR = QLabel("Semantica: ") self.labelSemanticaT.adjustSize() self.labelSemanticaR.adjustSize() #campos de texto transmisor self.textoMensajeT = QLineEdit() self.textoFramesT = QLineEdit("1") self.textoIndicador1T = QLineEdit() self.textoACKT = QLineEdit() self.textoENQT = QLineEdit() self.textoCTRT = QLineEdit() self.textoDATT = QLineEdit() self.textoPPTT = QLineEdit() self.textoLPRT = QLineEdit() self.textoNUMT = QLineEdit() self.textoInfoT = QLineEdit() self.textoIndicador2T = QLineEdit() #Selectores de campos de control self.checkACK = QCheckBox() self.checkENQ = QCheckBox() self.checkCTR = QCheckBox() self.checkDAT = QCheckBox() self.checkPPT = QCheckBox() self.checkLPR = QCheckBox() #boton de transmision self.botonTransmisor = QPushButton("ENVIAR") #campos de texto receptor self.textoIndicador1R = QLineEdit() self.textoACKR = QLineEdit() self.textoENQR = QLineEdit() self.textoCTRR = QLineEdit() self.textoDATR = QLineEdit() self.textoPPTR = QLineEdit() self.textoLPRR = QLineEdit() self.textoNUMR = QLineEdit() self.textoInfoR = QLineEdit() self.textoIndicador2R = QLineEdit() self.textoMensajeR = QLineEdit() #boton de respuesta self.botonRecibir = QPushButton("RECIBIR") self.trama = Trama() self.trama_anterior = None self.transmisor = Transmisor() self._inicializar() def _inicializar(self): self.setWindowTitle("Protocolo de transmision de datos") #------------------------------------# # ELEMENTOS DEL TRANSMISOR # #------------------------------------# #Etiquetas transmisor tituloT = QLabel("TRANSMISION") labelMensajeT = QLabel("Mensaje a transmitir:") labelFramesT = QLabel("Numero de frames:") labelIndicador1T = QLabel("INDICADOR") labelACKT = QLabel("ACK") labelENQT = QLabel("ENQ") labelCTRT = QLabel("CTR") labelDATT = QLabel("DAT") labelPPTT = QLabel("PPT") labelLPRT = QLabel("LPR") labelNUMT = QLabel("NUM") labelInfoT = QLabel("INFORMACION") labelIndicador2T = QLabel("INDICADOR") tituloT.adjustSize() labelMensajeT.adjustSize() labelFramesT.adjustSize() labelIndicador1T.adjustSize() labelACKT.adjustSize() labelENQT.adjustSize() labelCTRT.adjustSize() labelDATT.adjustSize() labelPPTT.adjustSize() labelLPRT.adjustSize() labelNUMT.adjustSize() labelInfoT.adjustSize() labelIndicador2T.adjustSize() #agregar los elementos al segundo nivel de layout fila1 = QHBoxLayout() fila2 = QHBoxLayout() fila3 = QHBoxLayout() fila4 = QHBoxLayout() cajaTransmisor = QVBoxLayout() fila1.addWidget(tituloT) fila2.addWidget(labelMensajeT) fila2.addWidget(self.textoMensajeT) fila2.addWidget(labelFramesT) fila2.addWidget(self.textoFramesT) fila4.addWidget(self.labelSemanticaT) fila3_1 = QVBoxLayout() fila3_2 = QVBoxLayout() fila3_3 = QVBoxLayout() fila3_4 = QVBoxLayout() fila3_5 = QVBoxLayout() fila3_6 = QVBoxLayout() fila3_7 = QVBoxLayout() fila3_8 = QVBoxLayout() fila3_9 = QVBoxLayout() fila3_10 = QVBoxLayout() fila3_1.addWidget(labelIndicador1T) fila3_1.addWidget(self.textoIndicador1T) fila3_1.setAlignment(Qt.AlignTop) fila3_2.addWidget(labelACKT) fila3_2.addWidget(self.textoACKT) fila3_2.addWidget(self.checkACK) fila3_3.addWidget(labelENQT) fila3_3.addWidget(self.textoENQT) fila3_3.addWidget(self.checkENQ) fila3_4.addWidget(labelCTRT) fila3_4.addWidget(self.textoCTRT) fila3_4.addWidget(self.checkCTR) fila3_5.addWidget(labelDATT) fila3_5.addWidget(self.textoDATT) fila3_5.addWidget(self.checkDAT) fila3_6.addWidget(labelPPTT) fila3_6.addWidget(self.textoPPTT) fila3_6.addWidget(self.checkPPT) fila3_7.addWidget(labelLPRT) fila3_7.addWidget(self.textoLPRT) fila3_7.addWidget(self.checkLPR) fila3_8.addWidget(labelNUMT) fila3_8.addWidget(self.textoNUMT) fila3_8.setAlignment(Qt.AlignTop) fila3_9.addWidget(labelInfoT) fila3_9.addWidget(self.textoInfoT) fila3_9.setAlignment(Qt.AlignTop) fila3_10.addWidget(labelIndicador2T) fila3_10.addWidget(self.textoIndicador2T) fila3_10.setAlignment(Qt.AlignTop) fila3.addLayout(fila3_1) fila3.addLayout(fila3_2) fila3.addLayout(fila3_3) fila3.addLayout(fila3_4) fila3.addLayout(fila3_5) fila3.addLayout(fila3_6) fila3.addLayout(fila3_7) fila3.addLayout(fila3_8) fila3.addLayout(fila3_9) fila3.addLayout(fila3_10) fila3.addWidget(self.botonTransmisor) cajaTransmisor.addLayout(fila1) cajaTransmisor.addLayout(fila2) cajaTransmisor.addLayout(fila3) cajaTransmisor.addLayout(fila4) #------------------------------------# # ELEMENTOS DEL RECEPTOR # #------------------------------------# #Etiquetas receptor tituloR = QLabel("RECEPCION") labelFrameR = QLabel("Trama recibida:") labelRespuestaR = QLabel("Recibido: ") labelIndicador1R = QLabel("INDICADOR") labelACKR = QLabel("ACK") labelENQR = QLabel("ENQ") labelCTRR = QLabel("CTR") labelDATR = QLabel("DAT") labelPPTR = QLabel("PPT") labelLPRR = QLabel("LPR") labelNUMR = QLabel("NUM") labelInfoR = QLabel("INFORMACION") labelIndicador2R = QLabel("INDICADOR") labelMensajeR = QLabel("Mensaje recibido:") tituloR.adjustSize() labelFrameR.adjustSize() labelRespuestaR.adjustSize() labelIndicador1R.adjustSize() labelACKR.adjustSize() labelENQR.adjustSize() labelCTRR.adjustSize() labelDATR.adjustSize() labelPPTR.adjustSize() labelLPRR.adjustSize() labelNUMR.adjustSize() labelInfoR.adjustSize() labelIndicador2R.adjustSize() labelMensajeR.adjustSize() #agregar los elementos al segundo nivel de layout fila5 = QHBoxLayout() fila6 = QHBoxLayout() fila8 = QHBoxLayout() fila9 = QHBoxLayout() fila10 = QHBoxLayout() fila11 = QHBoxLayout() cajaReceptor = QVBoxLayout() fila5.addWidget(tituloR) fila6.addWidget(labelFrameR) fila8.addWidget(labelRespuestaR) #fila9 fila9_1 = QVBoxLayout() fila9_2 = QVBoxLayout() fila9_3 = QVBoxLayout() fila9_4 = QVBoxLayout() fila9_5 = QVBoxLayout() fila9_6 = QVBoxLayout() fila9_7 = QVBoxLayout() fila9_8 = QVBoxLayout() fila9_9 = QVBoxLayout() fila9_10 = QVBoxLayout() fila9_1.addWidget(labelIndicador1R) fila9_1.addWidget(self.textoIndicador1R) fila9_2.addWidget(labelACKR) fila9_2.addWidget(self.textoACKR) fila9_3.addWidget(labelENQR) fila9_3.addWidget(self.textoENQR) fila9_4.addWidget(labelCTRR) fila9_4.addWidget(self.textoCTRR) fila9_5.addWidget(labelDATR) fila9_5.addWidget(self.textoDATR) fila9_6.addWidget(labelPPTR) fila9_6.addWidget(self.textoPPTR) fila9_7.addWidget(labelLPRR) fila9_7.addWidget(self.textoLPRR) fila9_8.addWidget(labelNUMR) fila9_8.addWidget(self.textoNUMR) fila9_9.addWidget(labelInfoR) fila9_9.addWidget(self.textoInfoR) fila9_10.addWidget(labelIndicador2R) fila9_10.addWidget(self.textoIndicador2R) fila9.addLayout(fila9_1) fila9.addLayout(fila9_2) fila9.addLayout(fila9_3) fila9.addLayout(fila9_4) fila9.addLayout(fila9_5) fila9.addLayout(fila9_6) fila9.addLayout(fila9_7) fila9.addLayout(fila9_8) fila9.addLayout(fila9_9) fila9.addLayout(fila9_10) fila9.addWidget(self.botonRecibir) fila10.addWidget(self.labelSemanticaR) fila11.addWidget(labelMensajeR) fila11.addWidget(self.textoMensajeR) cajaReceptor.addLayout(fila5) cajaReceptor.addLayout(fila6) cajaReceptor.addLayout(fila8) cajaReceptor.addLayout(fila9) cajaReceptor.addLayout(fila10) cajaReceptor.addLayout(fila11) #------------------------------------# #agregar el segundo nivel de layout al panel panelTransmisor = QFrame(self) panelTransmisor.setFrameShape(QFrame.StyledPanel) panelTransmisor.setLayout(cajaTransmisor) #agregar el segundo nivel de layout al panel panelReceptor = QFrame(self) panelReceptor.setFrameShape(QFrame.StyledPanel) panelReceptor.setLayout(cajaReceptor) #agregar el panel al separador separador = QSplitter(Qt.Vertical) separador.addWidget(panelTransmisor) separador.addWidget(panelReceptor) #agregar el separador al primer layout caja = QVBoxLayout(self) caja.addWidget(separador) #agregar el layout a la ventana self.setLayout(caja) self.setFixedSize(800, 400) self._configurar() self.show() self.crear_conexion() def _configurar(self): self.textoIndicador1T.setEnabled(False) self.textoACKT.setEnabled(False) self.textoENQT.setEnabled(False) self.textoCTRT.setEnabled(False) self.textoDATT.setEnabled(False) self.textoPPTT.setEnabled(False) self.textoLPRT.setEnabled(False) self.textoNUMT.setEnabled(False) self.textoInfoT.setEnabled(False) self.textoIndicador2T.setEnabled(False) self.textoIndicador1R.setEnabled(False) self.textoACKR.setEnabled(False) self.textoENQR.setEnabled(False) self.textoCTRR.setEnabled(False) self.textoDATR.setEnabled(False) self.textoPPTR.setEnabled(False) self.textoLPRR.setEnabled(False) self.textoNUMR.setEnabled(False) self.textoInfoR.setEnabled(False) self.textoIndicador2R.setEnabled(False) self.textoMensajeR.setEnabled(False) self.checkACK.setEnabled(False) self.checkENQ.setEnabled(False) self.checkPPT.setEnabled(False) self.checkLPR.setEnabled(False) self.checkACK.stateChanged.connect(self._seleccionarACK) self.checkENQ.stateChanged.connect(self._seleccionarENQ) self.checkCTR.stateChanged.connect(self._seleccionarCTR) self.checkDAT.stateChanged.connect(self._seleccionarDAT) self.checkPPT.stateChanged.connect(self._seleccionarPPT) self.checkLPR.stateChanged.connect(self._seleccionarLPR) self.botonTransmisor.clicked.connect(self._enviar_mensaje) self.botonRecibir.clicked.connect(self._recibir_mensaje) self._mostrar_trama(self._SERVIDOR) def _seleccionarACK(self, estado): if estado == Qt.Checked: self.textoACKT.setText("1") self.checkPPT.setChecked(False) self.checkLPR.setChecked(False) else: self.textoACKT.setText("0") def _seleccionarENQ(self, estado): if estado == Qt.Checked: self.textoENQT.setText("1") else: self.textoENQT.setText("0") def _seleccionarCTR(self, estado): if estado == Qt.Checked: self.textoCTRT.setText("1") self.checkDAT.setChecked(False) self.checkACK.setEnabled(True) self.checkPPT.setEnabled(True) self.checkLPR.setEnabled(True) else: self.textoCTRT.setText("0") self.checkACK.setChecked(False) self.checkPPT.setChecked(False) self.checkLPR.setChecked(False) self.checkACK.setEnabled(False) self.checkPPT.setEnabled(False) self.checkLPR.setEnabled(False) self.checkENQ.setEnabled(False) def _seleccionarDAT(self, estado): if estado == Qt.Checked: self.textoDATT.setText("1") self.checkCTR.setChecked(False) self.checkENQ.setEnabled(True) else: self.textoDATT.setText("0") self.checkENQ.setChecked(False) self.checkENQ.setEnabled(False) def _seleccionarPPT(self, estado): if estado == Qt.Checked: self.textoPPTT.setText("1") self.checkACK.setChecked(False) self.checkLPR.setChecked(False) else: self.textoPPTT.setText("0") def _seleccionarLPR(self, estado): if estado == Qt.Checked: self.textoLPRT.setText("1") self.checkACK.setChecked(False) self.checkPPT.setChecked(False) else: self.textoLPRT.setText("0") def crear_conexion(self): tipo = QInputDialog.getItem(self, "Tipo de usuario", "usuario", ["" ,self._SERVIDOR, self._CLIENTE]) self.rol = str(tipo[0]) self.setWindowTitle("Protocolo de transmision de datos --" + self.rol) if self.rol == self._SERVIDOR: port = QInputDialog.getInt(self, "ingrese puerto", "Puerto", 56032) nom = self.transmisor.crear_servidor(port[0]) msg = QMessageBox.information(self, "Servidor", "El nombre del servidor es: " + nom) del msg if self.transmisor.conectar_servidor(): resp = QMessageBox.information(self, "Conectado", "Se ha establecido la conexion con el cliente") del resp elif self.rol == self._CLIENTE: host = QInputDialog.getText(self, "ingrese host", "Host") port = QInputDialog.getInt(self, "ingrese puerto", "Puerto", 56032) self.transmisor.conectar_cliente((str(host[0]), port[0])) else: self.destroy() def _enviar_mensaje(self): self.trama_anterior = self.trama if not self.pasos: if self.trama.esPPT(): self._generar_trama() if self.trama.esLPR(): self.pasos.append("LPR") self.transmisor.enviar(self.trama()) self._mostrar_trama(self._SERVIDOR) else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") self.trama = self.trama_anterior elif self.trama.esNull(): self._generar_trama() if self.trama.esPPT(): self.pasos.append("PPT") self.transmisor.enviar(self.trama()) self._mostrar_trama(self._SERVIDOR) else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") self.trama = self.trama_anterior else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") elif "PPT" in self.pasos: if self.trama.esLPR() or self.trama.esACK(): cant = int(self.textoFramesT.text()) if not self.mensaje: self._preparar_mensaje(cant) self._generar_trama() if self.trama.esDAT(): if len(self.mensaje)>1: self.trama.INFO = self.mensaje.pop(0) self.trama.NUM = str(cant - len(self.mensaje)) self.transmisor.enviar(self.trama()) self._mostrar_trama(self._SERVIDOR) else: err = QMessageBox.information(self, "Error", "Ultima trama, envie ENQ") self.trama = self.trama_anterior del err elif self.trama.esENQ(): if len(self.mensaje)>1: err = QMessageBox.information(self, "Error", "Faltan mas tramas, envie DAT") self.trama = self.trama_anterior del err else: self.trama.INFO = self.mensaje.pop(0) self.trama.NUM = str(cant) self.transmisor.enviar(self.trama()) self.pasos.append("ENQ") self.pasos.remove("PPT") self._mostrar_trama(self._SERVIDOR) else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") elif "LPR" in self.pasos: if self.trama.esDAT() or self.trama.esENQ(): self._generar_trama() if self.trama.esACK(): self.trama.INFO="" self.transmisor.enviar(self.trama()) self._mostrar_trama(self._SERVIDOR) else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") self.trama = self.trama_anterior del err else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") elif "ENQ" in self.pasos: if self.trama.esACK(): err = QMessageBox.information(self, "Terminado", "El mensaje se ha entregado por completo") self.textoMensajeT.clear() self.textoFramesT.clear() self.textoMensajeT.setEnabled(True) self.textoFramesT.setEnabled(True) self.trama = Trama() self.pasos.remove("ENQ") self._mostrar_trama(self._SERVIDOR) elif self.trama.esENQ(): self._generar_trama() if self.trama.esACK(): self.trama.INFO="" self.transmisor.enviar(self.trama()) self._mostrar_trama(self._SERVIDOR) else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") self.trama = self.trama_anterior del err else: err = QMessageBox.information(self, "Error", "Trama fuera de contexto") def _recibir_mensaje(self): self.trama_anterior = self.trama msg = self.transmisor.recibir() if len(msg)!=0: datos = list(msg.split(self.trama.INDICADOR)[1]) self.trama.ACK = datos.pop(0) self.trama.ENQ = datos.pop(0) self.trama.CTR = datos.pop(0) self.trama.DAT = datos.pop(0) self.trama.PPT = datos.pop(0) self.trama.LPR = datos.pop(0) self.trama.NUM = datos.pop(0) self.trama.INFO = "".join(datos) self._mostrar_trama(self._CLIENTE) if self.trama.esDAT(): self.textoMensajeR.setText(self.textoMensajeR.text()+self.trama.INFO) elif self.trama.esENQ(): self.textoMensajeR.setText(self.textoMensajeR.text()+self.trama.INFO) self.pasos.remove("LPR") self.pasos.append("ENQ") err = QMessageBox.information(self, "Terminado", "El mensaje se ha recibido por completo") elif self.trama.esPPT(): self.textoMensajeR.clear() elif self.trama.esACK(): if "ENQ" in self.pasos: err = QMessageBox.information(self, "Terminado", "El mensaje se ha entregado por completo") else: err = QMessageBox.information(self, "Error", "Se ha perdido la conexion") del err def _preparar_mensaje(self, cant): self.textoMensajeT.setEnabled(False) self.textoFramesT.setEnabled(False) men = str(self.textoMensajeT.text()) tam = len(men)/cant + 1 for i in range(cant): self.mensaje.append(men[(i*tam):(i+1)*tam]) def _generar_trama(self): self.trama.ACK = str(self.textoACKT.text()) self.trama.ENQ = str(self.textoENQT.text()) self.trama.CTR = str(self.textoCTRT.text()) self.trama.DAT = str(self.textoDATT.text()) self.trama.PPT = str(self.textoPPTT.text()) self.trama.LPR = str(self.textoLPRT.text()) self.trama.NUM = str(self.textoNUMT.text()) self.trama.INFO = str(self.textoInfoT.text()) def _mostrar_trama(self, tipo): if tipo == self._CLIENTE: self.textoIndicador1R.setText(self.trama.INDICADOR) self.textoACKR.setText(self.trama.ACK) self.textoENQR.setText(self.trama.ENQ) self.textoCTRR.setText(self.trama.CTR) self.textoDATR.setText(self.trama.DAT) self.textoPPTR.setText(self.trama.PPT) self.textoLPRR.setText(self.trama.LPR) self.textoNUMR.setText(self.trama.NUM) self.textoInfoR.setText(self.trama.INFO) self.textoIndicador2R.setText(self.trama.INDICADOR) elif tipo == self._SERVIDOR: self.textoIndicador1T.setText(self.trama.INDICADOR) self.textoACKT.setText(self.trama.ACK) self.textoENQT.setText(self.trama.ENQ) self.textoCTRT.setText(self.trama.CTR) self.textoDATT.setText(self.trama.DAT) self.textoPPTT.setText(self.trama.PPT) self.textoLPRT.setText(self.trama.LPR) self.textoNUMT.setText(self.trama.NUM) self.textoInfoT.setText(self.trama.INFO) self.textoIndicador2T.setText(self.trama.INDICADOR) self._actualizar_semantica(tipo) def _actualizar_semantica(self, tipo): if tipo == self._CLIENTE: if self.trama.esACK(): self.labelSemanticaR.setText("Semantica: Trama de control, recibio con exito.") elif self.trama.esPPT(): self.labelSemanticaR.setText("Semantica: Trama de control, permiso para transmitir.") elif self.trama.esLPR(): self.labelSemanticaR.setText("Semantica: Trama de control, listo para recibir.") elif self.trama.esDAT(): self.labelSemanticaR.setText("Semantica: Trama de datos.") elif self.trama.esENQ(): self.labelSemanticaR.setText("Semantica: Trama de datos, ultima trama") elif self.trama.esNull(): self.labelSemanticaR.setText("Semantica:") self.labelSemanticaR.adjustSize() elif tipo == self._SERVIDOR: if self.trama.esACK(): self.labelSemanticaT.setText("Semantica: Trama de control, recibio con exito.") elif self.trama.esPPT(): self.labelSemanticaT.setText("Semantica: Trama de control, permiso para transmitir.") elif self.trama.esLPR(): self.labelSemanticaT.setText("Semantica: Trama de control, listo para recibir.") elif self.trama.esDAT(): self.labelSemanticaT.setText("Semantica: Trama de datos.") elif self.trama.esENQ(): self.labelSemanticaT.setText("Semantica: Trama de datos, ultima trama") elif self.trama.esNull(): self.labelSemanticaT.setText("Semantica:") self.labelSemanticaT.adjustSize()
class MainWindow(QtGui.QMainWindow): """Implements the main window for dame.""" def __init__(self, parent=None): """Initialize the window.""" QtGui.QMainWindow.__init__(self, parent) self.setupUi() def setupUi(self): """Create the basic UI.""" self.setWindowTitle("dame") # TODO: Set window icon self.create_actions() self.create_statusbar() self.mainview = MainViewer(parent=self) # # Connect an action now that mainview is set # self.mode_group.triggered.connect(self.mainview.toggleComparison) # TODO: This is the start of using tabbed windows # self.mdiArea = QtGui.QMdiArea(parent=self) # first = self.mdiArea.addSubWindow(self.scrollArea) # self.mdiArea.setViewMode(QtGui.QMdiArea.TabbedView) # self.mdiArea.setTabsMovable(True) # self.setCentralWidget(self.mdiArea) # first.setWindowTitle("foo") self.setCentralWidget(self.mainview) # Create popup windows (for zoomer and panner) self.zoom_win = QtGui.QWidget(self, Qt.Window | Qt.Tool) self.zoom_win.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.zoom_win_im = QLabel() self.zoom_win_im.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored) # self.zoom_win.resize(150,150) # self.zoom_win.show() zoomer_layout = QtGui.QGridLayout() zoomer_layout.setContentsMargins(0, 0, 0, 0) zoomer_layout.addWidget(self.zoom_win_im) self.zoom_win.setLayout(zoomer_layout) # TODO: panner # Create note dock widget self.note_widget = QtGui.QDockWidget("Notes", parent=self) self.note_text = QtGui.QTextEdit(parent=self.note_widget) self.note_widget.setWidget(self.note_text) self.note_widget.setFeatures( QtGui.QDockWidget.DockWidgetClosable | QtGui.QDockWidget.DockWidgetMovable | QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetVerticalTitleBar) self.addDockWidget(Qt.BottomDockWidgetArea, self.note_widget) self.note_widget.close() self.note_action = self.note_widget.toggleViewAction() self.note_action.setText("Display notes") self.note_action.setStatusTip("Show notes about the SIR image") # Create the menus self.create_menus() def create_statusbar(self): """Create the statusbar.""" self.statusBar().showMessage("Ready") # The individual info self.status_sing_pixinfo = QLabel() self.status_sing_coord = QLabel() self.status_left_pixinfo = QLabel() self.status_right_pixinfo = QLabel() self.status_comp_coord = QLabel() # The groups self.status_sing_layout = QtGui.QHBoxLayout() self.status_sing_layout.addWidget(self.status_sing_coord, 0, Qt.AlignRight) self.status_sing_layout.addWidget(self.status_sing_pixinfo, 1, Qt.AlignRight) self.status_comp_layout = QtGui.QHBoxLayout() self.status_comp_layout.addWidget(self.status_left_pixinfo, 0) self.status_comp_layout.addWidget(self.status_comp_coord, 1) self.status_comp_layout.addWidget(self.status_right_pixinfo, 0) self.status_sing_layout.setContentsMargins(0, 0, 0, 0) self.status_comp_layout.setContentsMargins(0, 0, 0, 0) self.status_sing = QtGui.QWidget() self.status_sing.setLayout(self.status_sing_layout) self.status_comp = QtGui.QWidget() self.status_comp.setLayout(self.status_comp_layout) # The stacked widget (to alternate between single and comparison modes) self.status_stacked = QtGui.QStackedWidget() self.status_stacked.addWidget(self.status_sing) self.status_stacked.addWidget(self.status_comp) self.status_stacked.setCurrentIndex(0) self.statusBar().addWidget(self.status_stacked) def create_actions(self): """Define the actions.""" self.about_action = QAction("&About", self) self.about_action.setStatusTip("About dame") self.about_action.setMenuRole(QAction.AboutRole) self.about_action.triggered.connect(self.show_about) self.open_action = QAction("&Open", self) self.open_action.setStatusTip("Open a SIR file") self.open_action.setShortcut(QtGui.QKeySequence.Open) self.open_action.triggered.connect(self.open_file) self.close_action = QAction("&Close", self) self.close_action.setStatusTip("Close current SIR file") self.close_action.setShortcut(QtGui.QKeySequence.Close) self.close_action.triggered.connect(self.close_file) self.exit_action = QAction("E&xit", self) self.exit_action.setMenuRole(QAction.QuitRole) self.exit_action.setStatusTip("Exit dame") self.exit_action.setShortcut(QtGui.QKeySequence("Ctrl+Q")) self.exit_action.triggered.connect(self.close) self.prop_action = QAction("SIR header", self) self.prop_action.setStatusTip("Display SIR header information") self.prop_action.triggered.connect(self.print_header) self.range_action = QAction("Image range", self) self.range_action.setStatusTip("Set image display range") self.range_action.triggered.connect(self.show_range) self.zoomer_action = QAction("Enable zoomer window", self) self.zoomer_action.setStatusTip(("Show zoomer window for " "magnified viewing")) self.zoomer_action.setCheckable(True) self.zoomer_action.triggered.connect(self.update_zoomer_opts) self.zoom_factor_label_action = QAction("Zoom factor", self) self.zoom_factor_label_action.setEnabled(False) self.zoom_factor_1_action = QAction("2x zoom", self) self.zoom_factor_2_action = QAction("4x zoom", self) self.zoom_factor_3_action = QAction("8x zoom", self) self.zoom_factor_4_action = QAction("16x zoom", self) self.zoom_factor_1_action.setStatusTip("Magnify zoom region by 2x") self.zoom_factor_2_action.setStatusTip("Magnify zoom region by 4x") self.zoom_factor_3_action.setStatusTip("Magnify zoom region by 8x") self.zoom_factor_4_action.setStatusTip("Magnify zoom region by 16x") self.zoom_factor_1_action.setCheckable(True) self.zoom_factor_2_action.setCheckable(True) self.zoom_factor_3_action.setCheckable(True) self.zoom_factor_4_action.setCheckable(True) self.zoom_size_label_action = QAction("Zoom region size", self) self.zoom_size_label_action.setEnabled(False) self.zoom_size_1_action = QAction("9x9 window", self) self.zoom_size_2_action = QAction("17x17 window", self) self.zoom_size_3_action = QAction("29x29 window", self) self.zoom_size_4_action = QAction("45x45 window", self) self.zoom_size_5_action = QAction("65x65 window", self) self.zoom_size_1_action.setStatusTip("Set zoom region to 9x9 pixels") self.zoom_size_2_action.setStatusTip("Set zoom region to 17x17 pixels") self.zoom_size_3_action.setStatusTip("Set zoom region to 29x29 pixels") self.zoom_size_4_action.setStatusTip("Set zoom region to 45x45 pixels") self.zoom_size_5_action.setStatusTip("Set zoom region to 65x65 pixels") self.zoom_size_1_action.setCheckable(True) self.zoom_size_2_action.setCheckable(True) self.zoom_size_3_action.setCheckable(True) self.zoom_size_4_action.setCheckable(True) self.zoom_size_5_action.setCheckable(True) # Group zoomer actions and connect slots self.zoom_factor_group = QtGui.QActionGroup(self) self.zoom_factor_group.addAction(self.zoom_factor_1_action) self.zoom_factor_group.addAction(self.zoom_factor_2_action) self.zoom_factor_group.addAction(self.zoom_factor_3_action) self.zoom_factor_group.addAction(self.zoom_factor_4_action) self.zoom_factor_group.triggered.connect(self.update_zoomer_opts) self.zoom_size_group = QtGui.QActionGroup(self) self.zoom_size_group.addAction(self.zoom_size_1_action) self.zoom_size_group.addAction(self.zoom_size_2_action) self.zoom_size_group.addAction(self.zoom_size_3_action) self.zoom_size_group.addAction(self.zoom_size_4_action) self.zoom_size_group.addAction(self.zoom_size_5_action) self.zoom_size_group.triggered.connect(self.update_zoomer_opts) # # Mode actions # self.mode_group = QtGui.QActionGroup(self) # self.mode_single_action = QAction("Single image", self.mode_group) # self.mode_dual_action = QAction("Two images", self.mode_group) # self.mode_single_action.setCheckable(True) # self.mode_dual_action.setCheckable(True) # self.mode_single_action.setStatusTip("Display a single image") # self.mode_dual_action.setStatusTip("Display two images for comparison") # self.mode_single_action.setChecked(True) # #self.mode_group.triggered.connect(self.mainview.toggleComparison) # Moved later # http://stackoverflow.com/questions/11643221/are-there-default-icons-in-pyqt-pyside # TODO: Add icons in a better way. See how Picard does it. QIcon.setThemeName("gnome") # TODO: temporary self.open_action.setIcon(QIcon.fromTheme("document-open")) self.close_action.setIcon(QIcon.fromTheme("window-close")) self.exit_action.setIcon(QIcon.fromTheme("application-exit")) self.about_action.setIcon(QIcon.fromTheme("help-about")) def create_menus(self): """Setup the menus.""" menu = self.menuBar().addMenu("&File") menu.addAction(self.open_action) menu.addAction(self.close_action) menu.addSeparator() # menu.addAction(self.mode_single_action) # menu.addAction(self.mode_dual_action) # menu.addSeparator() menu.addAction(self.exit_action) menu = self.menuBar().addMenu("Image") menu.addAction(self.prop_action) menu.addAction(self.range_action) menu.addAction(self.note_action) # submenu = menu.addMenu("Mode") # submenu.addAction(self.mode_single_action) # submenu.addAction(self.mode_split_action) # submenu.addAction(self.mode_fade_action) menu = self.menuBar().addMenu("Zoomer") menu.addAction(self.zoomer_action) menu.addSeparator() menu.addAction(self.zoom_factor_label_action) menu.addAction(self.zoom_factor_1_action) menu.addAction(self.zoom_factor_2_action) menu.addAction(self.zoom_factor_3_action) menu.addAction(self.zoom_factor_4_action) menu.addSeparator() menu.addAction(self.zoom_size_label_action) menu.addAction(self.zoom_size_1_action) menu.addAction(self.zoom_size_2_action) menu.addAction(self.zoom_size_3_action) menu.addAction(self.zoom_size_4_action) menu.addAction(self.zoom_size_5_action) menu = self.menuBar().addMenu("&Help") menu.addAction(self.about_action) # Deactivate menus by default self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def open_file(self): """Display open file dialog.""" filename = QtGui.QFileDialog.getOpenFileName(self, "Open SIR file", QtCore.QDir.homePath(), ("SIR files (*.sir *.ave)" ";;Any file (*)") ) if py_binding == 'PySide': filename = filename[0] if filename: self.load_sir(filename) def load_sir(self, filename): """Load in the SIR file.""" if os.access(filename, os.F_OK | os.R_OK): self.statusBar().showMessage("Loading") self.mainview.load_sir(filename) self.statusBar().showMessage("Loaded", 2000) # Activate menus self.range_action.setEnabled(True) self.prop_action.setEnabled(True) self.close_action.setEnabled(True) else: logging.warning("Can't open {}".format(filename)) # TODO: Alert the user via GUI @QtCore.Slot() def close_file(self): """Close file.""" logging.info("Closing SIR file") self.mainview.close_file() self.statusBar().showMessage("SIR closed", 2000) # That was the last file, so disable stuff if len(self.mainview.sir_files) == 0: self.status_stacked.setVisible(False) self.zoom_win.hide() # Deactivate menus self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def show_about(self): """Display about popup.""" about_text = """ Dame {} Copyright 2014 Richard Lindsley Dame is a SIR file viewer""".format(version_string) QMessageBox.about(self, "About", dedent(about_text)) @QtCore.Slot() def show_range(self): """Display image range popup.""" win = RangeWindow() win.min_text.setText(str( self.mainview.sir_files[self.mainview.cur_tab]['vmin'])) win.max_text.setText(str( self.mainview.sir_files[self.mainview.cur_tab]['vmax'])) if win.exec_() == QtGui.QDialog.Accepted: win_range = win.getRange() self.mainview.sir_files[self.mainview.cur_tab]['vmin'] = \ win_range[0] self.mainview.sir_files[self.mainview.cur_tab]['vmax'] = \ win_range[1] self.mainview.update_image(self.mainview.cur_tab) self.mainview.update_view() @QtCore.Slot() def print_header(self): """Display SIR header info.""" sir_head = libsir.print_sir_head( self.mainview.sir_files[self.mainview.cur_tab]['header']) # TODO: Maybe make this a modeless dialog instead of modal? Use a dock # widget? box = QMessageBox() box.setText(dedent(sir_head)) box.setIcon(QMessageBox.Information) box.exec_() def update_zoomer(self): """Update the zoomer, both the image as well as the popup.""" cur_tab = self.mainview.cur_tab if 'pix_loc' not in self.mainview.sir_files[cur_tab]: return try: loc = self.mainview.sir_files[cur_tab]['pix_loc'] rect_w = self.mainview.sir_files[cur_tab]['zoomer_size'] winsize = rect_w * \ self.mainview.sir_files[cur_tab]['zoomer_factor'] if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'].copy(), self.mainview.sir_files['right']['pixmap'].copy()) else: pixmaps = \ (self.mainview.sir_files[cur_tab]['pixmap'].copy(),) for pixmap_i, pixmap in enumerate(pixmaps): # Upper left corner if loc.x() < rect_w/2: rect_x = -0.5 elif loc.x() > pixmap.width() - rect_w/2: rect_x = pixmap.width() - rect_w - 0.5 else: rect_x = loc.x() - rect_w/2 if loc.y() < rect_w/2: rect_y = -0.5 elif loc.y() > pixmap.height() - rect_w/2: rect_y = pixmap.height() - rect_w - 0.5 else: rect_y = loc.y() - rect_w/2 rect_x += 1 rect_y += 1 # Draw the image with the zoomer region outlined p = QtGui.QPainter() p.begin(pixmap) p.setPen(QtGui.QColor("#FFFFFF")) # White stroke p.drawRect(rect_x, rect_y, rect_w, rect_w) p.end() if cur_tab in ("left", "right", "cross"): self.mainview.single_image.image.setPixmap(pixmap) elif cur_tab in ("split", ): if pixmap_i == 0: self.mainview.left_image.image.setPixmap(pixmap) elif pixmap_i == 1: self.mainview.right_image.image.setPixmap(pixmap) else: logging.warning("pixmap_i is {}".format(pixmap_i)) # Update the zoomer window if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'], self.mainview.sir_files['right']['pixmap']) else: pixmaps = (self.mainview.sir_files[cur_tab]['pixmap'],) if len(pixmaps) == 2: zoom_pixmap = QPixmap(2*winsize, winsize) for pixmap_i, pixmap_src in enumerate(pixmaps): # extract the zoomer region pixmap = pixmap_src.copy(rect_x, rect_y, rect_w, rect_w) # scale it pixmap = pixmap.scaled(winsize, winsize, Qt.KeepAspectRatioByExpanding) # Add crosshair to zoomer window; note that the crosshair # won't be centered if the region is at the edges p = QtGui.QPainter() p.begin(pixmap) # Highlight selected pixel # p.setPen(QtGui.QColor("#000000")) # Black stroke p.setPen(QtGui.QColor("#FFFFFF")) # White stroke zoom_fac = self.mainview.sir_files[cur_tab]['zoomer_factor'] # Top left of magnified pixel mag_pix = (zoom_fac * (loc.x() - rect_x + 1) - zoom_fac/2, zoom_fac * (loc.y() - rect_y + 1) - zoom_fac/2) # Center of magnified pixel mag_pix_cen = (zoom_fac * (loc.x() - rect_x + 1), zoom_fac * (loc.y() - rect_y + 1)) p.drawRect(mag_pix[0], mag_pix[1], zoom_fac, zoom_fac) # Draw crosshairs p.setPen(QtGui.QColor("#FFFFFF")) # White stroke # vertical line, top p.drawLine(mag_pix_cen[0], 0, mag_pix_cen[0], mag_pix[1]-1) # vertical line, bottom p.drawLine(mag_pix_cen[0], mag_pix[1]+zoom_fac, mag_pix_cen[0], winsize-0) # horizontal line, left p.drawLine(0, mag_pix_cen[1], mag_pix[0]-1, mag_pix_cen[1]) # horizontal line, right p.drawLine(mag_pix[0]+zoom_fac, mag_pix_cen[1], winsize-0, mag_pix_cen[1]) p.end() if len(pixmaps) == 1: self.zoom_win_im.setPixmap(pixmap) else: p = QtGui.QPainter(zoom_pixmap) p.drawPixmap(pixmap_i * winsize, 0, pixmap) self.zoom_win_im.setPixmap(zoom_pixmap) self.zoom_win_im.setHidden(False) self.zoom_win_im.adjustSize() except KeyError as err: logging.warning("Can't find {}".format(err)) def update_statusbar(self): """Update the status bar.""" if self.mainview.cur_tab in ("left", "right"): vmin = self.mainview.sir_files[self.mainview.cur_tab]['vmin'] vmax = self.mainview.sir_files[self.mainview.cur_tab]['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(0) self.status_sing_pixinfo.setText( "min: {}, max: {}".format(vmin, vmax)) self.status_sing_coord.setVisible(False) elif self.mainview.cur_tab in ("split", "fade"): vmin_l = self.mainview.sir_files['left']['vmin'] vmax_l = self.mainview.sir_files['left']['vmax'] vmin_r = self.mainview.sir_files['right']['vmin'] vmax_r = self.mainview.sir_files['right']['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(1) self.status_left_pixinfo.setText( "min: {} max: {}".format(vmin_l, vmax_l)) self.status_right_pixinfo.setText( "min: {} max: {}".format(vmin_r, vmax_r)) self.status_comp_coord.setVisible(False) def update_statusbar_pos(self, x_im, y_im): """Update with position at image index x, y.""" self.statusBar().clearMessage() nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy # Convert from 0-based to 1-based indexing # (I've double-checked the values returned here using sir_util2a) y = nsy - y_im # Convert image y coord to SIR y coord x = x_im + 1 if x > 0 and y > 0 and x <= nsx and y <= nsy: # Note that sir_data is 0-based indexing, but pix2latlon is 1-based cur_sir = self.mainview.sir_files[self.mainview.cur_tab] lon, lat = libsir.pix2latlon(x, y, cur_sir['header']) if self.mainview.cur_tab in ("left", "right"): self.status_sing_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "value = {:0.4f}").format(x, y, lat, lon, cur_sir['data'][y_im, x_im]) self.status_sing_coord.setText(stat_text) elif self.mainview.cur_tab in ("split", "fade"): left_sir = self.mainview.sir_files['left'] right_sir = self.mainview.sir_files['right'] self.status_comp_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "left value = {:0.4f} " "right value = {:0.4f}").format( x, y, lat, lon, left_sir['data'][y_im, x_im], right_sir['data'][y_im, x_im]) self.status_comp_coord.setText(stat_text) def sizeHint(self): """Override the suggested size.""" return QtCore.QSize(1000, 800) # Menu events @QtCore.Slot() def update_zoomer_opts(self, draw_win=True): """Given a menu change, this sets zoomer options and updates.""" file_dict = self.mainview.sir_files[self.mainview.cur_tab] # Is zoomer enabled? file_dict['zoomer_on'] = self.zoomer_action.isChecked() # Find the zoom factor zfactor = self.zoom_factor_group.checkedAction() if zfactor is self.zoom_factor_1_action: file_dict['zoomer_factor'] = 2 elif zfactor is self.zoom_factor_2_action: file_dict['zoomer_factor'] = 4 elif zfactor is self.zoom_factor_3_action: file_dict['zoomer_factor'] = 8 elif zfactor is self.zoom_factor_4_action: file_dict['zoomer_factor'] = 16 # Find the zoom size zsize = self.zoom_size_group.checkedAction() if zsize is self.zoom_size_1_action: file_dict['zoomer_size'] = 9 elif zsize is self.zoom_size_2_action: file_dict['zoomer_size'] = 17 elif zsize is self.zoom_size_3_action: file_dict['zoomer_size'] = 29 elif zsize is self.zoom_size_4_action: file_dict['zoomer_size'] = 45 elif zsize is self.zoom_size_5_action: file_dict['zoomer_size'] = 65 if draw_win: # Compute zoomer window size and show/hide it winsize = file_dict['zoomer_size'] * file_dict['zoomer_factor'] if self.mainview.cur_tab == "split": self.zoom_win.resize(2*winsize, winsize) self.zoom_win.setFixedSize(2*winsize, winsize) else: self.zoom_win.resize(winsize, winsize) self.zoom_win.setFixedSize(winsize, winsize) if file_dict['zoomer_on']: self.zoom_win.show() else: self.zoom_win.hide() # Update zoomer self.update_zoomer() # Keyboard events def keyPressEvent(self, key): """Handle some keypresses.""" if len(self.mainview.sir_files) == 0: key.ignore() return if 'pix_loc' not in self.mainview.sir_files[self.mainview.cur_tab]: # Don't do anything if we don't have a coord yet key.ignore() return # Increment im_pos if valid key # Note that im_pos is 0-based, so # it ranges from 0 to nsx-1/nsy-1 inclusive im_pos = self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy delta = 5 if key.modifiers() == Qt.ShiftModifier else 1 if key.key() == Qt.Key_J: # Down if im_pos.y() + delta < nsy: im_pos.setY(im_pos.y() + delta) elif key.key() == Qt.Key_K: # Up if im_pos.y() - delta >= 0: im_pos.setY(im_pos.y() - delta) elif key.key() == Qt.Key_H: # Left if im_pos.x() - delta >= 0: im_pos.setX(im_pos.x() - delta) elif key.key() == Qt.Key_L: # Right if im_pos.x() + delta < nsx: im_pos.setX(im_pos.x() + delta) else: key.ignore() return # Update stuff with our new position self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] = im_pos self.update_zoomer() self.update_statusbar_pos(im_pos.x(), im_pos.y())
def showToolTip( text, point = None, anchor = None, parent = None, background = None, foreground = None, key = None, seconds = 5 ): """ Displays a popup widget as a tooltip bubble. :param text | <str> point | <QPoint> || None anchor | <XPopupWidget.Mode.Anchor> || None parent | <QWidget> || None background | <QColor> || None foreground | <QColor> || None key | <str> || None seconds | <int> """ if point is None: point = QCursor.pos() if parent is None: parent = QApplication.activeWindow() if anchor is None and parent is None: anchor = XPopupWidget.Anchor.TopCenter # create a new tooltip widget widget = XPopupWidget(parent) widget.setToolTipMode() widget.setResizable(False) # create the tooltip label label = QLabel(text, widget) label.setOpenExternalLinks(True) label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) label.setMargin(3) label.setIndent(3) label.adjustSize() widget.setCentralWidget(label) # update the tip label.adjustSize() widget.adjustSize() palette = widget.palette() if not background: background = palette.color(palette.ToolTipBase) if not foreground: foreground = palette.color(palette.ToolTipText) palette.setColor(palette.Window, QColor(background)) palette.setColor(palette.WindowText, QColor(foreground)) widget.setPalette(palette) widget.centralWidget().setPalette(palette) if anchor is None: widget.setAutoCalculateAnchor(True) else: widget.setAnchor(anchor) widget.setAutoCloseOnFocusOut(True) widget.setAttribute(Qt.WA_DeleteOnClose) widget.popup(point) widget.startTimer(1000 * seconds) return widget
class NetWidget(QWidget): def __init__(self,parent = None): super(NetWidget,self).__init__(parent) self.setStyleSheet("font-size : 16px")#设置整体的字体大小 self.auto = False self.pro = QProcess(self) # self.tipDlg = TipDialog() # self.tipDlg.setModal(True)#引入tipdlg,并且将这个窗口设置为最前端窗口,且后面窗口无法操作 #初始化comBox控件,并且为其添加选项 self.comBox = QComboBox() self.comBox.setFixedWidth(120) self.comBox.insertItem(0, self.tr("ping")) self.comBox.insertItem(1, self.tr("ifconfig")) self.comBox.insertItem(2, self.tr("display")) #self.comBox.insertItem(3, self.tr("traceroute")) self.comBox.insertItem(4, self.tr("top")) self.connect(self.comBox, SIGNAL('activated(QString)'),self.onActivated)#设置combBox为活动的,与函数关联 """ #初始话控件设置 #lineEdit,固定长度 #runButton,显示字符串,信号量 #pingLabel,当前显示字符 #textBrower """ self.lineEdit = QLineEdit() self.lineEdit.setContextMenuPolicy(Qt.NoContextMenu) self.lineEdit.setFixedWidth(250) self.runButton = QPushButton(self.tr("Run")) self.runButton.setStyleSheet("background: rgb(7,87,198); color: white; width: 70px; height: 20px;font-size : 16px;") self.connect(self.runButton, SIGNAL("clicked()"),self.runButton_clicked) self.pingLabel = QLabel()#初始话,之后在函数操作中会改变 self.pingLabel.setText(self.tr("Tip:please input the IP address of pinging,then get the result with clicking the button")) self.textBrowser = QTextBrowser() """ #布局一上,横向布局 #将comBox,lineEdit,runButton添加到布局中 #设置前面空为20和后面空为280 """ hLayout1 = QHBoxLayout() hLayout1.addSpacing(20) hLayout1.addWidget(self.comBox) hLayout1.addWidget(self.lineEdit) hLayout1.addWidget(self.runButton) #hLayout1.addStretch() hLayout1.addSpacing(280) #布局二中,横向布局 #将pingLabel添加到布局中,并且诶设置前面的空白为20 hLayout2 = QHBoxLayout() hLayout2.addSpacing(20) hLayout2.addWidget(self.pingLabel) #布局三下 #将textBrower添加爱到布局中,并且设置前面空白为20,后面空白为60,控件的大小自适应 hLayout3 = QHBoxLayout() hLayout3.addSpacing(20) hLayout3.addWidget(self.textBrowser) hLayout3.addSpacing(60) #主题布局总,纵向布局 #将之上的三个布局添加到总布局中,并且设置布局间空间为20,最下面的空白为40 mainLayout = QVBoxLayout() mainLayout.addSpacing(20) mainLayout.addLayout(hLayout1) mainLayout.addSpacing(20) mainLayout.addLayout(hLayout2) mainLayout.addSpacing(20) mainLayout.addLayout(hLayout3) mainLayout.addSpacing(40) self.setLayout(mainLayout) self.thread = MyThread() self.connect(self.thread,SIGNAL("getoutput"),self.append) def append(self,actionType): self.textBrowser.clear() self.textBrowser.append(actionType) #cursor = QTextCursor() #self.runButton.setText(self.tr("Stop")) cursor = self.textBrowser.textCursor() cursor.movePosition(QTextCursor.Start) self.textBrowser.setTextCursor(cursor) #changeLabel = QLabel() def onActivated(self): language = StoreInfoParser.instance().getLanguage() m_pTranslator = QTranslator() exePath = "./" if language == "chinese": QmName = "zh_CN.qm" else: QmName = "en_US.qm" if(m_pTranslator.load(QmName, exePath)): QCoreApplication.instance().installTranslator(m_pTranslator) """#comBox的相应函数,随着comBox中字符串的改变,分别控制pingLabel的显示,以及lineEdit和textBrower的显示清除和可用状态 #如果comBox当前的字符串文字为ping #pingLabel的文字设置为"提示:请在文本框中输入要ping的目标地址,然后点击执行获取结果",保持当前大小 #lineEdit中内容清除,设置为不可用 #textBrower清空""" if(self.comBox.currentText() == "Ping" or self.comBox.currentText() == "ping"): self.pingLabel.setText(self.tr("Tip:please input the IP address of pinging,then get the result with clicking the button")) self.pingLabel.adjustSize() self.lineEdit.clear() self.lineEdit.setDisabled(False) self.textBrowser.clear() #如果comBox当前的字符串文字为ifconfig #类上所说 elif(self.comBox.currentText() == "ifconfig"): self.pingLabel.setText(self.tr("Tip:get the net information")) self.pingLabel.adjustSize() self.lineEdit.clear() self.lineEdit.setEnabled(False) self.textBrowser.clear() #如果comBox当前的字符串文字为display elif(self.comBox.currentText() == "display"): self.pingLabel.setText(self.tr("Tip:get the resolution information")) self.pingLabel.adjustSize() self.lineEdit.clear() self.lineEdit.setEnabled(False) self.textBrowser.clear() elif(self.comBox.currentText() == "top"): self.pingLabel.setText(self.tr("Tip:run tom command")) self.pingLabel.adjustSize() self.lineEdit.setEnabled(False) self.lineEdit.clear() self.textBrowser.clear() #按钮的响应函数 def runButton_clicked(self): language = StoreInfoParser.instance().getLanguage() m_pTranslator = QTranslator() exePath = "./" if language == "chinese": QmName = "zh_CN.qm" else: QmName = "en_US.qm" if(m_pTranslator.load(QmName, exePath)): QCoreApplication.instance().installTranslator(m_pTranslator) #self.pro = QProcess(self)#外部程序使用声明 desktop = QApplication.desktop()#获得桌面 self.textBrowser.clear()#清除 cmdstr = QString() center = QString() goal = QString() #comBox当前text为ping if (self.comBox.currentText() == "Ping" or self.comBox.currentText() == "ping"): if (self.runButton.text() == self.tr("Run")) : center = self.lineEdit.text().trimmed() if not center: InfoHintDialog(self.tr("please input the IP address")).exec_() # self.tipDlg.setTip(self.tr("请输入ping地址!!!")) # self.tipDlg.show() # self.tipDlg.move((desktop.width()-self.tipDlg.width())/2,(desktop.height()-self.tipDlg.height())/2) self.runButton.setText(self.tr("Run")) else: self.comBox.setDisabled(True) self.pro = QProcess(self) self.runButton.setText(self.tr("stop ping")) cmdstr = "ping " +center self.textBrowser.clear() self.textBrowser.append(self.tr(" ping ")+center+self.tr(" result:")) else: self.comBox.setDisabled(False) self.runButton.setText(self.tr("Run")) self.pro.close() elif(self.comBox.currentText() == "ifconfig"): self.pro = QProcess(self) self.lineEdit.clear() self.lineEdit.setEnabled(False) self.textBrowser.clear() cmdstr = "ifconfig" # #如果comBox当前为traceroute # elif(self.comBox.currentText() == "traceroute"): # goal = self.lineEdit.text() # if (self.runButton.text() == u"执行"): # if( goal.isEmpty() or goal.isNull() ): # InfoHintDialog(u'请输入tracer地址:').exec_() # # self.tipDlg.setTip(self.tr("请输入tracer地址:")) # # self.tipDlg.show() # # self.tipDlg.move((desktop.width()-self.tipDlg.width())/2,(desktop.height()-self.tipDlg.height())/2) # # # #QMessageBox.information(self,self.tr("错误"),self.tr("请输入traceroute的目标地址")) # #return # else: # self.proc = QProcess(self) # #self.textBrowser.clear() # cmdstrc = "traceroute -n "+ goal # self.proc.start(cmdstrc) # self.connect(self.proc, SIGNAL("readyReadStandardOutput()"),self.readR) # self.connect(self.proc, SIGNAL("readyReadStandardError()"),self.readErrorR) # if self.proc.waitForStarted(10) == True: # self.comBox.setDisabled(True) # self.runButton.setText(self.tr("停止执行")) # else: # self.runButton.setText(self.tr("执行")) # self.comBox.setDisabled(False) # self.proc.close() # #如果comBox当前为display elif (self.comBox.currentText() == "display"): self.pro = QProcess(self) cmdstr = "../lib/ccr_jytcapi display" self.textBrowser.clear() #如果当前命令cmdstr不为空,则 elif (self.comBox.currentText() == "top"): if self.runButton.text() == self.tr("Run") : self.thread.start() self.comBox.setDisabled(True) self.runButton.setText(self.tr("stop top")) else: self.textBrowser.clear() self.thread.auto = False #self.thread.destroyed() self.comBox.setDisabled(False) self.runButton.setText(self.tr("Run")) if (cmdstr != ""): self.pro.start(cmdstr)#开启执行命令 self.connect(self.pro, SIGNAL("readyReadStandardOutput()"),self.read)#读取执行正常输出槽函数 self.connect(self.pro, SIGNAL("readyReadStandardError()"),self.readError)#执行异常槽函数 #读取控制台输出 def read(self): res = QString.fromLocal8Bit(self.pro.readAllStandardOutput()) self.textBrowser.append(res)#添加到text框 #读取错误 def readError(self): res = QString.fromLocal8Bit(self.pro.readAllStandardError()) self.textBrowser.append(res) def readR(self): res = QString.fromLocal8Bit(self.proc.readAllStandardOutput()) #self.textBrowser.clear() self.textBrowser.append(res) def readErrorR(self): res = QString.fromLocal8Bit(self.proc.readAllStandardError()) self.textBrowser.append(res) def updateWindow(self): if self.pro.isOpen(): self.pro.close() self.thread.auto = False self.comBox.setDisabled(False) self.comBox.setCurrentIndex(0) self.runButton.setText((self.tr("Run"))) self.pingLabel.setText(self.tr("Tip:please input the IP address of pinging,then get the result with clicking the button")) self.textBrowser.clear()
class PixmapWidget( QScrollArea ): " The pixmap widget " escapePressed = pyqtSignal() formatStrings = { QImage.Format_Invalid: "invalid", QImage.Format_Mono: "1-bit per pixel", QImage.Format_MonoLSB: "1-bit per pixel", QImage.Format_Indexed8: "8-bit indexes", QImage.Format_RGB32: "32-bit RG", QImage.Format_ARGB32: "32-bit ARGB", QImage.Format_ARGB32_Premultiplied: "32-bit ARGB", QImage.Format_RGB16: "16-bit RGB", QImage.Format_ARGB8565_Premultiplied: "24-bit ARGB", QImage.Format_RGB666: "24-bit RGB", QImage.Format_ARGB6666_Premultiplied: "24-bit ARGB", QImage.Format_RGB555: "16-bit RGB", QImage.Format_ARGB8555_Premultiplied: "24-bit ARGB", QImage.Format_RGB888: "24-bit RGB", QImage.Format_RGB444: "16-bit RGB", QImage.Format_ARGB4444_Premultiplied: "16-bit ARGB" } def __init__( self, parent = None ): QScrollArea.__init__( self, parent ) self.pixmapLabel = QLabel() self.pixmapLabel.setBackgroundRole( QPalette.Base ) self.pixmapLabel.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Ignored ) self.pixmapLabel.setScaledContents( True ) self.zoom = 1.0 self.info = "" self.formatInfo = "" self.fileSize = 0 self.setBackgroundRole( QPalette.Dark ) self.setWidget( self.pixmapLabel ) self.setAlignment( Qt.AlignCenter ) return def loadFromFile( self, fileName ): " Loads a pixmap from a file " image = QImage( fileName ) if image.isNull(): raise Exception( "Unsupported pixmap format (" + fileName + ")" ) self.pixmapLabel.setPixmap( QPixmap.fromImage( image ) ) self.pixmapLabel.adjustSize() self.fileSize = os.path.getsize( fileName ) if self.fileSize < 1024: fileSizeString = str( self.fileSize ) + "bytes" else: kiloBytes = self.fileSize / 1024 if (self.fileSize % 1024) >= 512: kiloBytes += 1 fileSizeString = str( kiloBytes ) + "kb" self.info = str( image.width() ) + "px/" + \ str( image.height() ) + "px/" + fileSizeString try: self.formatInfo = self.formatStrings[ image.format() ] except: self.formatInfo = "Unknown" return def setPixmap( self, pixmap ): " Shows the provided pixmap " pix = QPixmap.fromImage( pixmap ) self.pixmapLabel.setPixmap( pix ) self.pixmapLabel.adjustSize() self.info = str( pix.width() ) + "px/" + str( pix.height() ) + "px" self.formatInfo = str( pix.depth() ) + " bpp" return def keyPressEvent( self, event ): """ Handles the key press events """ if event.key() == Qt.Key_Escape: self.escapePressed.emit() event.accept() else: QScrollArea.keyPressEvent( self, event ) return def resetZoom( self ): " Resets the zoom " self.zoom = 1.0 self.pixmapLabel.adjustSize() return def doZoom( self, factor ): " Performs zooming " self.zoom *= factor self.pixmapLabel.resize( self.zoom * self.pixmapLabel.pixmap().size() ) self.__adjustScrollBar( self.horizontalScrollBar(), factor ) self.__adjustScrollBar( self.verticalScrollBar(), factor ) return def __adjustScrollBar( self, scrollBar, factor ): " Adjusts a scrollbar by a certain factor " scrollBar.setValue( int( factor * scrollBar.value() + ( (factor - 1) * scrollBar.pageStep()/2) ) ) return def setReadOnly( self, newValue ): " Make it similar to a text editor " return
def _label(title): label = QLabel(title) label.adjustSize() return label
class WTestPng(Document.WDocument): """ Test png widget """ def __init__(self, parent=None, path=None, filename=None, extension=None, nonameId=None, remoteFile=True, repoDest=None, project=0): """ Constructs WScript widget @param parent: @type parent: @param path: @type path: @param filename: @type filename: @param extension: @type extension: @param nonameId: @type nonameId: """ Document.WDocument.__init__(self, parent, path, filename, extension, nonameId, remoteFile, repoDest, project) self.scaleFactor = 0.0 self.rawContent = '' self.createWidgets() self.createActions() self.createToolbar() self.createConnections() def createActions(self): """ Create qt actions """ self.zoomInAct = QtHelper.createAction(self, "&Zoom &In (25%.", self.zoomIn, icon=QIcon(":/zoom-in.png")) self.zoomOutAct = QtHelper.createAction(self, "Zoom &Out (25%.", self.zoomOut, icon=QIcon(":/zoom-out.png")) self.normalSizeAct = QtHelper.createAction( self, "&Normal Size", self.normalSize, icon=QIcon(":/zoom-normal.png")) def createToolbar(self): """ Toolbar creation ||------|------||| || Open | Save ||| ||------|------||| """ self.dockToolbar.setObjectName("Test Config toolbar") self.dockToolbar.addAction(self.zoomInAct) self.dockToolbar.addAction(self.zoomOutAct) self.dockToolbar.addAction(self.normalSizeAct) self.dockToolbar.addSeparator() self.dockToolbar.setIconSize(QSize(16, 16)) def createWidgets(self): """ QtWidgets creation """ self.dockToolbar = QToolBar(self) self.dockToolbar.setStyleSheet( "QToolBar { border: 0px }") # remove 3D border self.imageLabel = QLabel(self) self.imageLabel.setBackgroundRole(QPalette.Base) self.imageLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabel.setScaledContents(True) self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.imageLabel) title = QLabel("Image:") title.setStyleSheet("QLabel { padding-left: 2px; padding-top: 2px }") font = QFont() font.setBold(True) title.setFont(font) layout = QVBoxLayout() layout.addWidget(title) layout.addWidget(self.dockToolbar) layout.addWidget(self.scrollArea) layout.setContentsMargins(2, 2, 2, 2) self.setLayout(layout) def zoomIn(self): """ Zoom in """ self.scaleImage(1.25) def zoomOut(self): """ Zoom out """ self.scaleImage(0.8) def normalSize(self): """ Normal size """ self.imageLabel.adjustSize() self.scaleFactor = 1.0 def scaleImage(self, factor): """ Scale image """ self.scaleFactor *= factor self.imageLabel.resize(self.scaleFactor * self.imageLabel.pixmap().size()) self.adjustScrollBar(self.scrollArea.horizontalScrollBar(), factor) self.adjustScrollBar(self.scrollArea.verticalScrollBar(), factor) def adjustScrollBar(self, scrollBar, factor): """ Adjust scrollbar """ scrollBar.setValue( int(factor * scrollBar.value() + ((factor - 1) * scrollBar.pageStep() / 2))) def createConnections(self): """ QtSignals connection """ pass def write(self, force=False): """ Save """ absPath = '%s/%s.%s' % (self.path, self.filename, self.extension) try: with open(absPath, mode='wb') as myfile: myfile.write(self.rawContent) except Exception as e: self.error("unable to write png file: %s" % e) return None else: self.setUnmodify() return True def load(self, content=None): """ Open file """ if content is None: absPath = '%s/%s.%s' % (self.path, self.filename, self.extension) file = QFile(absPath) if not file.open(QIODevice.ReadOnly): self.error("Error opening image file: %s" % absPath) return False else: content = file.readAll() self.rawContent = content image = QImage() image.loadFromData(content) if image.isNull(): self.error("cannot load image") return False else: self.imageLabel.setPixmap(QPixmap.fromImage(QImage(image))) self.scaleFactor = 1.0 self.imageLabel.adjustSize() return True def getraw_encoded(self): """ Returns raw data encoded """ encoded = '' try: encoded = base64.b64encode(self.rawContent) except Exception as e: self.error('unable to encode raw image: %s' % str(e)) return encoded
class App(QWidget): keyPressed = pyqtSignal(int) def __init__(self): super(App, self).__init__() self.title = "45C Robotics 2019" self.initUI() self.setStyleSheet( open('/home/robotics45c/Desktop/rov2019/Robot/Systems/style.css'). read()) self.keyPressed.connect(self.on_key) def keyReleaseEvent(self, event): super(App, self).keyReleaseEvent(event) if (event.isAutoRepeat()): print('autorepeat') return else: self.keyPressed.emit(event.key()) event.accept() @pyqtSlot(str) def setDist(self, text): self.dist_label.setText(text) self.dist_label.adjustSize() @pyqtSlot(int) def setMode(self, text): if text == 0: self.mode_label.setText('No Vision Enabled') elif text == 1: self.mode_label.setText('Benthic Species Enabled') elif text == 2: self.mode_label.setText('Live Measure Enabled') else: self.mode_label.setText('ERR') self.mode_label.adjustSize() @pyqtSlot(QImage) def setImage(self, image): self.videoCom.setPixmap(QPixmap.fromImage(image)) @pyqtSlot(QImage) def setImage2(self, image): self.videoCom2.setPixmap(QPixmap.fromImage(image)) @pyqtSlot(QImage) def setImage3(self, image): self.videoCom3.setPixmap(QPixmap.fromImage(image)) @pyqtSlot(str) def setText1(self, text): self.t_housing_in_label.setText(text) self.t_housing_in_label.adjustSize() @pyqtSlot(str) def setText2(self, text): self.t_housing_o_label.setText(text) self.t_housing_o_label.adjustSize() @pyqtSlot(str) def setText3(self, text): self.h_housing_in_label.setText(text) self.h_housing_in_label.adjustSize() @pyqtSlot(str) def setText4(self, text): self.leak_sensor_label.setText(text) self.leak_sensor_label.adjustSize() @pyqtSlot(str) def setText5(self, text): self.x_label.setText(text) self.x_label.adjustSize() @pyqtSlot(str) def setText6(self, text): self.y_label.setText(text) self.y_label.adjustSize() @pyqtSlot(str) def setNumShapes(self, text): self.n_label.setText(text) #self.n_label.adjustSize() @pyqtSlot(str) def setNumTriangles(self, text): self.t_label.setText(text) #self.t_label.adjustSize() @pyqtSlot(str) def setNumSquares(self, text): self.sq_label.setText(text) #self.sq_label.adjustSize() @pyqtSlot(str) def setNumLines(self, text): print("TEXT: " + text) self.l_label.setText(text) #self.l_label.adjustSize() @pyqtSlot(str) def setNumCircles(self, text): self.c_label.setText(text) #self.c_label.adjustSize() def initUI(self): print("Initialized serial comms") self.keyPressed.connect(self.on_key) self.setWindowTitle(self.title) self.resize(1920, 1080) # Number of shapes self.n_label = QLabel(self) self.n_label.setText('--- Number of shapes ---') self.n_label.setAlignment(Qt.AlignRight) self.n_label.adjustSize() self.n_label.move(1600, 525) # Distance self.dist_label = QLabel(self) #self.n_label.setText('--- Distance---') self.dist_label.setAlignment(Qt.AlignRight) self.dist_label.adjustSize() self.dist_label.move(1600, 525) # T Species self.t_label = QLabel(self) self.t_label.setText('--- # of Triangles ---') self.t_label.setStyleSheet('color: red') self.t_label.setAlignment(Qt.AlignRight) self.t_label.adjustSize() self.t_label.move(1705, 555) # Sq Species self.sq_label = QLabel(self) self.sq_label.setText('--- # of Squares ---') self.sq_label.setStyleSheet('color: red') self.sq_label.setAlignment(Qt.AlignRight) self.sq_label.adjustSize() self.sq_label.move(1705, 585) # Lines Species self.l_label = QLabel(self) self.l_label.setText('--- # of Lines ---') self.l_label.setStyleSheet('color: red') self.l_label.setAlignment(Qt.AlignRight) self.l_label.adjustSize() self.l_label.move(1705, 615) # Circles Species self.c_label = QLabel(self) self.c_label.setText('--- # of Circles ---') self.c_label.setStyleSheet('color: red') self.c_label.setAlignment(Qt.AlignRight) self.c_label.adjustSize() self.c_label.move(1705, 645) # Title label self.title_label = QLabel(self) self.title_label.setText('--- Operator Data ---') self.title_label.setAlignment(Qt.AlignRight) self.title_label.adjustSize() self.title_label.move(40, 495) # Mode label self.mode_label = QLabel(self) self.mode_label.setText('Operator Mode:') self.mode_label.setAlignment(Qt.AlignRight) self.mode_label.adjustSize() self.mode_label.move(40, 525) # Temperature Inside Housing self.t_housing_in_label = QLabel(self) self.t_housing_in_label.setText('Temperature inside housing:') self.t_housing_in_label.setAlignment(Qt.AlignRight) self.t_housing_in_label.adjustSize() self.t_housing_in_label.move(40, 555) # Temperature Outside Housing self.t_housing_o_label = QLabel(self) self.t_housing_o_label.setText('Temperature outside housing:') self.t_housing_o_label.setAlignment(Qt.AlignRight) self.t_housing_o_label.adjustSize() self.t_housing_o_label.move(40, 585) # Humidity inside housing self.h_housing_in_label = QLabel(self) self.h_housing_in_label.setText('Humidity inside housing:') self.h_housing_in_label.setAlignment(Qt.AlignRight) self.h_housing_in_label.adjustSize() self.h_housing_in_label.move(40, 615) # Leak Sensor self.leak_sensor_label = QLabel(self) self.leak_sensor_label.setText('Leak sensor:') self.leak_sensor_label.setAlignment(Qt.AlignRight) self.leak_sensor_label.adjustSize() self.leak_sensor_label.move(40, 645) # x self.x_label = QLabel(self) self.x_label.setText('X:') self.x_label.setAlignment(Qt.AlignRight) self.x_label.adjustSize() self.x_label.move(40, 675) # y self.y_label = QLabel(self) self.y_label.setText('Y:') self.y_label.setAlignment(Qt.AlignRight) self.y_label.adjustSize() self.y_label.move(40, 715) # Video component 1 self.videoCom = QLabel(self) self.videoCom.move(150, 0) self.videoCom.resize(925, 500) # Video component 2 self.videoCom2 = QLabel(self) self.videoCom2.move(1055, 0) self.videoCom2.resize(855, 500) # Video component 3 self.videoCom3 = QLabel(self) self.videoCom3.move(580, 540) self.videoCom3.resize(1200, 540) self.th = VideoThread(self, 0) self.s_th = TThread(self) #serial self.th.changedist.connect(self.setDist) self.th.changemode.connect(self.setMode) self.th.changePixmap.connect(self.setImage) self.th.changePixmap2.connect(self.setImage2) self.th.changePixmap3.connect(self.setImage3) self.th.changen.connect(self.setNumShapes) self.th.changet.connect(self.setNumTriangles) self.th.changesq.connect(self.setNumSquares) self.th.changel.connect(self.setNumLines) self.th.changec.connect(self.setNumCircles) self.s_th.changeText1.connect(self.setText1) self.s_th.changeText1.connect(self.setText1) self.s_th.changeText2.connect(self.setText2) self.s_th.changeText3.connect(self.setText3) self.s_th.changeText4.connect(self.setText4) self.s_th.changeText5.connect(self.setText5) self.s_th.changeText6.connect(self.setText6) self.th.start() self.s_th.start() self.history = Queue.Queue() self.history.enqueue(0) self.status = 0 self.mode_status = True # for keeping track of mode def on_key(self, event): if event == Qt.Key_Return: self.status += 1 if self.status % 2 == 0: self.th.close() print("Queue is now: {}".format(self.history.get())) if self.history.get() == [1]: self.history.dequeue() self.th = VideoThread(self, 2) self.history.enqueue(2) elif self.history.get() == [2]: self.history.dequeue() self.th = VideoThread(self, 0) self.history.enqueue(0) elif self.history.get() == [0]: self.history.dequeue() self.th = VideoThread(self, 1) self.history.enqueue(1) print("Queue is now: {}".format(self.history.get())) self.th.changedist.connect(self.setDist) self.th.changemode.connect(self.setMode) self.th.changePixmap.connect(self.setImage) self.th.changePixmap2.connect(self.setImage2) self.th.changePixmap3.connect(self.setImage3) self.th.changen.connect(self.setNumShapes) self.th.changet.connect(self.setNumTriangles) self.th.changesq.connect(self.setNumSquares) self.th.changel.connect(self.setNumLines) self.th.changec.connect(self.setNumCircles) self.th.start() def abort(self): self.close()
class PhotoViewer(QScrollArea): """ Widget for viewing images by incorporating basic navigation options. """ def __init__(self, parent=None, photo_path=""): QScrollArea.__init__(self, parent) self.setBackgroundRole(QPalette.Dark) self._printer = QPrinter() self._lbl_photo = QLabel() self._lbl_photo.setBackgroundRole(QPalette.Base) self._lbl_photo.setSizePolicy(QSizePolicy.Ignored,QSizePolicy.Ignored) self._lbl_photo.setScaledContents(True) self.setWidget(self._lbl_photo) self._photo_path = photo_path self._ph_image = None self._scale_factor = 1.0 self._aspect_ratio = -1 self._create_actions() if self._photo_path: self.load_document(self._photo_path) def _create_actions(self): """ Create actions for basic image navigation. """ self._zoom_in_act = QAction( QApplication.translate("PhotoViewer","Zoom &In (25%)"), self) self._zoom_in_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl++")) self._zoom_in_act.setEnabled(False) self._zoom_in_act.triggered.connect(self.zoom_in) self._zoom_out_act = QAction( QApplication.translate("PhotoViewer","Zoom &Out (25%)"), self) self._zoom_out_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl+-")) self._zoom_out_act.setEnabled(False) self._zoom_out_act.triggered.connect(self.zoom_out) self._normal_size_act = QAction( QApplication.translate("PhotoViewer","&Normal Size"), self) self._normal_size_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl+S")) self._normal_size_act.setEnabled(False) self._normal_size_act.triggered.connect(self.normal_size) self._fit_to_window_act = QAction( QApplication.translate("PhotoViewer","&Fit to Window"), self) self._fit_to_window_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl+F")) self._fit_to_window_act.setEnabled(False) self._fit_to_window_act.setCheckable(True) self._fit_to_window_act.triggered.connect(self.fit_to_window) self._print_act = QAction( QApplication.translate("PhotoViewer","&Print"), self) self._print_act .setShortcut( QApplication.translate("PhotoViewer","Ctrl+P")) self._print_act .setEnabled(False) self._print_act .triggered.connect(self.print_photo) def zoom_in(self): self.scale_photo(1.25) def zoom_out(self): self.scale_photo(0.8) def normal_size(self): self._lbl_photo.adjustSize() self._scale_factor = 1.0 def fit_to_window(self): fit_to_win = self._fit_to_window_act.isChecked() self.setWidgetResizable(fit_to_win) if not fit_to_win: self.normal_size() self.update_actions() def print_photo(self): print_dialog = QPrintDialog(self._printer,self) if print_dialog.exec_() == QDialog.Accepted: painter = QPainter(self._printer) rect = painter.viewport() size = self._lbl_photo.pixmap().size() size.scale(rect.size(), Qt.KeepAspectRatio) painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(self._lbl_photo.pixmap().rect()) painter.drawPixmap(0, 0, self._lbl_photo.pixmap()) def wheelEvent(self, event): """ Zoom the image based on the mouse wheel rotation action. :param event: Event containing the wheel rotation info. :type event: QWheelEvent """ degrees = event.delta() / 8 num_steps = degrees / 15 if num_steps < 0: abs_num_steps = abs(num_steps) zoom_factor = 1 + (abs_num_steps * 0.25) else: zoom_factor = 1 - (num_steps * 0.2) self.scale_photo(zoom_factor) def heightForWidth(self, width): if self._aspect_ratio != -1: return width / self._aspect_ratio else: return -1 def resizeEvent(self, event): """ Event for resizing the widget based on the pixmap's aspect ratio. :param event: Contains event parameters for the resize event. :type event: QResizeEvent """ super(PhotoViewer, self).resizeEvent(event) def update_actions(self): self._zoom_out_act.setEnabled(not self._fit_to_window_act.isChecked()) self._zoom_in_act.setEnabled(not self._fit_to_window_act.isChecked()) self._normal_size_act.setEnabled(not self._fit_to_window_act.isChecked()) def scale_photo(self,factor): """ :param factor: Value by which the image will be increased/decreased in the view. :type factor: float """ if not self._lbl_photo.pixmap().isNull(): self._scale_factor *= factor self._lbl_photo.resize(self._scale_factor * self._lbl_photo.pixmap().size()) self._adjust_scroll_bar(self.horizontalScrollBar(), factor) self._adjust_scroll_bar(self.verticalScrollBar(), factor) self._zoom_in_act.setEnabled(self._scale_factor < 3.0) self._zoom_out_act.setEnabled(self._scale_factor > 0.333) def _adjust_scroll_bar(self, scroll_bar, factor): scroll_bar.setValue(int(factor * scroll_bar.value() + ((factor - 1) * scroll_bar.pageStep()/2))) def load_document(self, photo_path): if photo_path: self._ph_image = QImage(photo_path) if self._ph_image.isNull(): return False self._photo_path = photo_path ph_pixmap = QPixmap.fromImage(self._ph_image) self._lbl_photo.setPixmap(ph_pixmap) self._scale_factor = 1.0 self._aspect_ratio = ph_pixmap.width() / ph_pixmap.height() self._fit_to_window_act.setEnabled(True) self._print_act.setEnabled(True) self._fit_to_window_act.trigger() self.update_actions() return ph_pixmap return True def photo_location(self): """ :returns: Absolute path of the photo in the central document repository. """ return self._photo_path def set_actions(self,menu): """ Add custom actions to the sub-window menu """ menu.addSeparator() menu.addAction(self._zoom_in_act) menu.addAction(self._zoom_out_act) menu.addAction(self._normal_size_act) menu.addAction(self._fit_to_window_act) menu.addSeparator() menu.addAction(self._print_act)
def showToolTip(text, point=None, anchor=None, parent=None, background=None, foreground=None, key=None, seconds=5): """ Displays a popup widget as a tooltip bubble. :param text | <str> point | <QPoint> || None anchor | <XPopupWidget.Mode.Anchor> || None parent | <QWidget> || None background | <QColor> || None foreground | <QColor> || None key | <str> || None seconds | <int> """ if point is None: point = QCursor.pos() if parent is None: parent = QApplication.activeWindow() if anchor is None and parent is None: anchor = XPopupWidget.Anchor.TopCenter # create a new tooltip widget widget = XPopupWidget(parent) widget.setToolTipMode() widget.setResizable(False) # create the tooltip label label = QLabel(text, widget) label.setOpenExternalLinks(True) label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) label.setMargin(3) label.setIndent(3) label.adjustSize() widget.setCentralWidget(label) # update the tip label.adjustSize() widget.adjustSize() palette = widget.palette() if not background: background = palette.color(palette.ToolTipBase) if not foreground: foreground = palette.color(palette.ToolTipText) palette.setColor(palette.Window, QColor(background)) palette.setColor(palette.WindowText, QColor(foreground)) widget.setPalette(palette) widget.centralWidget().setPalette(palette) if anchor is None: widget.setAutoCalculateAnchor(True) else: widget.setAnchor(anchor) widget.setAutoCloseOnFocusOut(True) widget.setAttribute(Qt.WA_DeleteOnClose) widget.popup(point) widget.startTimer(1000 * seconds) return widget
def _inicializar(self): self.setWindowTitle("Protocolo de transmision de datos") #------------------------------------# # ELEMENTOS DEL TRANSMISOR # #------------------------------------# #Etiquetas transmisor tituloT = QLabel("TRANSMISION") labelMensajeT = QLabel("Mensaje a transmitir:") labelFramesT = QLabel("Numero de frames:") labelIndicador1T = QLabel("INDICADOR") labelACKT = QLabel("ACK") labelENQT = QLabel("ENQ") labelCTRT = QLabel("CTR") labelDATT = QLabel("DAT") labelPPTT = QLabel("PPT") labelLPRT = QLabel("LPR") labelNUMT = QLabel("NUM") labelInfoT = QLabel("INFORMACION") labelIndicador2T = QLabel("INDICADOR") tituloT.adjustSize() labelMensajeT.adjustSize() labelFramesT.adjustSize() labelIndicador1T.adjustSize() labelACKT.adjustSize() labelENQT.adjustSize() labelCTRT.adjustSize() labelDATT.adjustSize() labelPPTT.adjustSize() labelLPRT.adjustSize() labelNUMT.adjustSize() labelInfoT.adjustSize() labelIndicador2T.adjustSize() #agregar los elementos al segundo nivel de layout fila1 = QHBoxLayout() fila2 = QHBoxLayout() fila3 = QHBoxLayout() fila4 = QHBoxLayout() cajaTransmisor = QVBoxLayout() fila1.addWidget(tituloT) fila2.addWidget(labelMensajeT) fila2.addWidget(self.textoMensajeT) fila2.addWidget(labelFramesT) fila2.addWidget(self.textoFramesT) fila4.addWidget(self.labelSemanticaT) fila3_1 = QVBoxLayout() fila3_2 = QVBoxLayout() fila3_3 = QVBoxLayout() fila3_4 = QVBoxLayout() fila3_5 = QVBoxLayout() fila3_6 = QVBoxLayout() fila3_7 = QVBoxLayout() fila3_8 = QVBoxLayout() fila3_9 = QVBoxLayout() fila3_10 = QVBoxLayout() fila3_1.addWidget(labelIndicador1T) fila3_1.addWidget(self.textoIndicador1T) fila3_1.setAlignment(Qt.AlignTop) fila3_2.addWidget(labelACKT) fila3_2.addWidget(self.textoACKT) fila3_2.addWidget(self.checkACK) fila3_3.addWidget(labelENQT) fila3_3.addWidget(self.textoENQT) fila3_3.addWidget(self.checkENQ) fila3_4.addWidget(labelCTRT) fila3_4.addWidget(self.textoCTRT) fila3_4.addWidget(self.checkCTR) fila3_5.addWidget(labelDATT) fila3_5.addWidget(self.textoDATT) fila3_5.addWidget(self.checkDAT) fila3_6.addWidget(labelPPTT) fila3_6.addWidget(self.textoPPTT) fila3_6.addWidget(self.checkPPT) fila3_7.addWidget(labelLPRT) fila3_7.addWidget(self.textoLPRT) fila3_7.addWidget(self.checkLPR) fila3_8.addWidget(labelNUMT) fila3_8.addWidget(self.textoNUMT) fila3_8.setAlignment(Qt.AlignTop) fila3_9.addWidget(labelInfoT) fila3_9.addWidget(self.textoInfoT) fila3_9.setAlignment(Qt.AlignTop) fila3_10.addWidget(labelIndicador2T) fila3_10.addWidget(self.textoIndicador2T) fila3_10.setAlignment(Qt.AlignTop) fila3.addLayout(fila3_1) fila3.addLayout(fila3_2) fila3.addLayout(fila3_3) fila3.addLayout(fila3_4) fila3.addLayout(fila3_5) fila3.addLayout(fila3_6) fila3.addLayout(fila3_7) fila3.addLayout(fila3_8) fila3.addLayout(fila3_9) fila3.addLayout(fila3_10) fila3.addWidget(self.botonTransmisor) cajaTransmisor.addLayout(fila1) cajaTransmisor.addLayout(fila2) cajaTransmisor.addLayout(fila3) cajaTransmisor.addLayout(fila4) #------------------------------------# # ELEMENTOS DEL RECEPTOR # #------------------------------------# #Etiquetas receptor tituloR = QLabel("RECEPCION") labelFrameR = QLabel("Trama recibida:") labelRespuestaR = QLabel("Recibido: ") labelIndicador1R = QLabel("INDICADOR") labelACKR = QLabel("ACK") labelENQR = QLabel("ENQ") labelCTRR = QLabel("CTR") labelDATR = QLabel("DAT") labelPPTR = QLabel("PPT") labelLPRR = QLabel("LPR") labelNUMR = QLabel("NUM") labelInfoR = QLabel("INFORMACION") labelIndicador2R = QLabel("INDICADOR") labelMensajeR = QLabel("Mensaje recibido:") tituloR.adjustSize() labelFrameR.adjustSize() labelRespuestaR.adjustSize() labelIndicador1R.adjustSize() labelACKR.adjustSize() labelENQR.adjustSize() labelCTRR.adjustSize() labelDATR.adjustSize() labelPPTR.adjustSize() labelLPRR.adjustSize() labelNUMR.adjustSize() labelInfoR.adjustSize() labelIndicador2R.adjustSize() labelMensajeR.adjustSize() #agregar los elementos al segundo nivel de layout fila5 = QHBoxLayout() fila6 = QHBoxLayout() fila8 = QHBoxLayout() fila9 = QHBoxLayout() fila10 = QHBoxLayout() fila11 = QHBoxLayout() cajaReceptor = QVBoxLayout() fila5.addWidget(tituloR) fila6.addWidget(labelFrameR) fila8.addWidget(labelRespuestaR) #fila9 fila9_1 = QVBoxLayout() fila9_2 = QVBoxLayout() fila9_3 = QVBoxLayout() fila9_4 = QVBoxLayout() fila9_5 = QVBoxLayout() fila9_6 = QVBoxLayout() fila9_7 = QVBoxLayout() fila9_8 = QVBoxLayout() fila9_9 = QVBoxLayout() fila9_10 = QVBoxLayout() fila9_1.addWidget(labelIndicador1R) fila9_1.addWidget(self.textoIndicador1R) fila9_2.addWidget(labelACKR) fila9_2.addWidget(self.textoACKR) fila9_3.addWidget(labelENQR) fila9_3.addWidget(self.textoENQR) fila9_4.addWidget(labelCTRR) fila9_4.addWidget(self.textoCTRR) fila9_5.addWidget(labelDATR) fila9_5.addWidget(self.textoDATR) fila9_6.addWidget(labelPPTR) fila9_6.addWidget(self.textoPPTR) fila9_7.addWidget(labelLPRR) fila9_7.addWidget(self.textoLPRR) fila9_8.addWidget(labelNUMR) fila9_8.addWidget(self.textoNUMR) fila9_9.addWidget(labelInfoR) fila9_9.addWidget(self.textoInfoR) fila9_10.addWidget(labelIndicador2R) fila9_10.addWidget(self.textoIndicador2R) fila9.addLayout(fila9_1) fila9.addLayout(fila9_2) fila9.addLayout(fila9_3) fila9.addLayout(fila9_4) fila9.addLayout(fila9_5) fila9.addLayout(fila9_6) fila9.addLayout(fila9_7) fila9.addLayout(fila9_8) fila9.addLayout(fila9_9) fila9.addLayout(fila9_10) fila9.addWidget(self.botonRecibir) fila10.addWidget(self.labelSemanticaR) fila11.addWidget(labelMensajeR) fila11.addWidget(self.textoMensajeR) cajaReceptor.addLayout(fila5) cajaReceptor.addLayout(fila6) cajaReceptor.addLayout(fila8) cajaReceptor.addLayout(fila9) cajaReceptor.addLayout(fila10) cajaReceptor.addLayout(fila11) #------------------------------------# #agregar el segundo nivel de layout al panel panelTransmisor = QFrame(self) panelTransmisor.setFrameShape(QFrame.StyledPanel) panelTransmisor.setLayout(cajaTransmisor) #agregar el segundo nivel de layout al panel panelReceptor = QFrame(self) panelReceptor.setFrameShape(QFrame.StyledPanel) panelReceptor.setLayout(cajaReceptor) #agregar el panel al separador separador = QSplitter(Qt.Vertical) separador.addWidget(panelTransmisor) separador.addWidget(panelReceptor) #agregar el separador al primer layout caja = QVBoxLayout(self) caja.addWidget(separador) #agregar el layout a la ventana self.setLayout(caja) self.setFixedSize(800, 400) self._configurar() self.show() self.crear_conexion()