class MainWidget(QWidget): def __init__(self): super(MainWidget, self).__init__() self._k_widget = KWidget() self._vol_widget = VolWidget() self._spliter = QSplitter(Qt.Vertical, self) self.init_ui() self.init_connection() def init_ui(self): self._spliter.addWidget(self._k_widget) self._spliter.addWidget(self._vol_widget) self._spliter.setStretchFactor(0, 8) self._spliter.setStretchFactor(1, 2) self._spliter.setHandleWidth(1) _layout = QHBoxLayout() _layout.addWidget(self._spliter) _layout.setContentsMargins(10, 10, 10, 10) _layout.setSpacing(0) self.setLayout(_layout) def init_connection(self): self._k_widget.view_box().setXLink(self._vol_widget.view_box()) self._k_widget.sig_y_padding_changed.connect( self._vol_widget.on_y_padding_changed) self._vol_widget.sig_y_padding_changed.connect( self._k_widget.on_y_padding_changed) self._k_widget.sig_v_pos.connect(self._vol_widget.on_v_pos) self._vol_widget.sig_v_pos.connect(self._k_widget.on_v_pos)
def __init__(self, parent=None): QMainWindow.__init__(self, parent) # self.setWindowFlags(Qt.FramelessWindowHint) # self.setAttribute(Qt.WA_TranslucentBackground) splitter = QSplitter(self) splitter.setOrientation(Qt.Horizontal) self.setCentralWidget(splitter) self.setMinimumSize(1200, 800) self.setWindowTitle('采集器') # self.showMaximized() left_widget = QWidget(self) left_widget.setMinimumWidth(200) left_widget.setStyleSheet("background:white") self.right_widget = QTabWidget() self.right_widget.currentChanged.connect(self.deal) self.right_widget.setObjectName("right") self.right_widget.setTabShape(QTabWidget.Triangular) self.right_widget.setDocumentMode(True) self.right_widget.setMovable(True) self.right_widget.setTabsClosable(True) self.right_widget.addTab(Ui_Task(self), "任务列表") self.right_widget.setStyleSheet(WidgetStyle.QTabWidget) self.right_widget.tabCloseRequested.connect(self.close_Tab) splitter.addWidget(left_widget) splitter.addWidget(self.right_widget) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 6)
def __init__(self, parent=None): super().__init__(parent) self.editor = PythonEditor(self) self.resize(650, 500) fileMenu = QMenu(self.tr("&File"), self) fileMenu.addAction(self.tr("&New…"), self.newFile, QKeySequence.New) fileMenu.addAction(self.tr("&Open…"), self.openFile, QKeySequence.Open) fileMenu.addAction(self.tr("&Save"), self.saveFile, QKeySequence.Save) fileMenu.addAction(self.tr("Save &As…"), self.saveFileAs, QKeySequence.SaveAs) fileMenu.addSeparator() fileMenu.addAction(self.tr("&Run…"), self.runScript, "Ctrl+R") fileMenu.addSeparator() fileMenu.addAction(self.tr("&Close"), self.close, platformSpecific.closeKeySequence()) self.menuBar().addMenu(fileMenu) self.fileChooser = FileChooser(self) self.fileChooser.fileOpened.connect(self.openFile) splitter = QSplitter(self) splitter.addWidget(self.fileChooser) splitter.addWidget(self.editor) splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 5) splitter.setSizes([0, 1]) self.setCentralWidget(splitter) self.newFile() self.editor.modificationChanged.connect(self.setWindowModified)
def __init__(self, parent, args): super(CentralWidget, self).__init__(parent) self.layout = QHBoxLayout() self.setLayout(self.layout) self.annotator_config = AnnotatorConfigurationModel(args.config) self.annotation = AnnotationModel(args.video, args.output, self.annotator_config) splitter = QSplitter(Qt.Horizontal) self.canvas = ImageCanvas(self, self.annotator_config, self.annotation) splitter.addWidget(self.canvas) self.sidebar = QWidget(self) self.sidebar.setMinimumWidth(450) splitter.addWidget(self.sidebar) self.sidebar_layout = QVBoxLayout() self.sidebar.setLayout(self.sidebar_layout) self.video_control = VideoControl(self, self.annotation, self.canvas) self.sidebar_layout.addWidget(self.video_control) self.config_editor = ConfigurationEditor(self, self.annotator_config) self.sidebar_layout.addWidget(self.config_editor) self.ann_editor = AnnotationEditor(self, self.annotation, self.canvas) self.sidebar_layout.addWidget(self.ann_editor) policy = QSizePolicy() policy.setHorizontalPolicy(QSizePolicy.Maximum) policy.setVerticalPolicy(QSizePolicy.Maximum) self.canvas.setSizePolicy(policy) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 0) self.layout.addWidget(splitter)
def setupViews(self): '''create main views''' # left widgets self.tabWidget = QTabWidget() self.groupsTreeView = GroupTreeView(['Group', 'Key']) # groups tree view self.tagsTableView = TagTableView(['KEY', 'TAG', 'COLOR']) # tags table view self.tabWidget.addTab(self.groupsTreeView, "Groups") self.tabWidget.addTab(self.tagsTableView, "Tags") # central widgets: reference item table widget headers = [ 'Item Title', 'Group', 'Tags', 'Path', 'Create Date', 'Notes' ] self.itemsTableView = ItemTableView(headers, self.tabWidget) # arranged views splitter = QSplitter() splitter.addWidget(self.tabWidget) splitter.addWidget(self.itemsTableView) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 1) self.setCentralWidget(splitter) # dock widgets # it has not been added to main window util called by addDockWidget() explicitly propWidget = PropertyWidget(self.itemsTableView) self.dockProperty = QDockWidget(self.tr("Properties"), self) self.dockProperty.setWidget(propWidget)
def __init__(self, parent=None, title_text: str = ''): super(NewOrder, self).__init__(parent=parent) self.title_text = title_text v_layout = QVBoxLayout(self) splitter = QSplitter(Qt.Vertical) # 运行状态监视器 self.runtime_state_monitor = QTextBrowser() self.runtime_state_monitor.setFontPointSize(18) self.runtime_state_monitor.setText("<h1>" + self.title_text + "</h1>") # 按钮区 btn_widget = QWidget() btn_widget.setMinimumHeight(150) h_layout = QHBoxLayout(self) # 主按钮 self.btn_main = QPushButton("Go") self.btn_main.clicked.connect(self.on_clicked_main_btn) self.btn_main.clicked.connect(self.handle_countdown) # 倒计时,10秒 self.countdown = QLCDNumber() self.countdown.setLineWidth(0) self.countdown.setDigitCount(3) self.countdown.display(str(self.lcd_num)) # 计时 self.timer = QTimer() self.timer.timeout.connect(self.refresh_lcd) h_layout.addWidget(self.countdown) h_layout.addWidget(self.btn_main, alignment=Qt.AlignLeft) btn_widget.setLayout(h_layout) splitter.addWidget(self.runtime_state_monitor) splitter.addWidget(btn_widget) splitter.setStretchFactor(0, 5) splitter.setStretchFactor(1, 5) v_layout.addWidget(splitter) self.setLayout(v_layout)
def init_UI(self): # Centers window to provide consistent launch of app self.statusBar().showMessage('Ready') self.setWindowTitle('PMR Insight Collective Knowledge') self.setWindowIcon( QIcon('../Source/Backend/Resources/Images/logo_small.png')) self.resize(1900, 1030) frame = self.frameGeometry() center_point = QDesktopWidget().availableGeometry().center() frame.moveCenter(center_point) self.move(frame.topLeft()) self.init_toolbar() splitV = QSplitter(Qt.Vertical) splitV.addWidget(self.vectors) splitV.addWidget(NodeTableFrame()) splitV.setStretchFactor(1, 1) splitV.setSizes([600, 900]) self.layout.addWidget(splitV) self.setCentralWidget(QWidget(self)) self.centralWidget().setLayout(self.layout) self.show()
class LmrManager(QWidget): def __init__(self): super(LmrManager, self).__init__() self.h_layout = QHBoxLayout() self.left_frame = LeftFrame() self.middle_frame = MiddleFrame() self.right_frame = RightFrame() self.mr_splitter = QSplitter() # 缩小三个框直接的缝隙 self.mr_splitter.setHandleWidth(1) self.mr_splitter.insertWidget(0, self.middle_frame) self.mr_splitter.insertWidget(1, self.right_frame) self.mr_splitter.setStretchFactor( 0, 1) # 全屏后保持1:4的比例,但是之前设置的最小宽度此时可能就比较小了 self.mr_splitter.setStretchFactor(1, 4) # 设置为不可拖动至隐藏 self.mr_splitter.setCollapsible(0, False) self.mr_splitter.setCollapsible(1, False) self.h_layout.addWidget(self.left_frame) self.h_layout.addWidget(self.mr_splitter) self.setLayout(self.h_layout)
def __init__(self): super().__init__() # information widget self.plotWidget = VariantPlotWidget() self.infoWidget = VariantInfoWidget() # splitter settings splitter = QSplitter(Qt.Horizontal) splitter.addWidget(self.plotWidget) splitter.addWidget(self.infoWidget) splitter.setStretchFactor(0, 3) splitter.setStretchFactor(1, 1) # layout layout = QBoxLayout(QBoxLayout.TopToBottom) layout.addWidget(splitter) self.setLayout(layout) # connect signals self.plotWidget.curvePlotted.connect(self.infoWidget.updateResults) self.plotWidget.plotReady.connect(self.infoWidget.showResults) self.plotWidget.cleared.connect(self.infoWidget.clear) self.infoWidget.legendChanged.connect(self.plotWidget.paintCalculation) # translate the graphical user interface self.retranslateUi()
def __init__(self, parent=None, project_path=None): super().__init__() self.parent = parent mono = MonoPanel(parent) node_list = NodeTree() self.scene = mono.view.scene() left_panel = QWidget() config_button = QPushButton('Global\nConfiguration') config_button.setMinimumHeight(40) config_button.clicked.connect(self.global_config) vlayout = QVBoxLayout() vlayout.addWidget(config_button) vlayout.addWidget(node_list) vlayout.setContentsMargins(0, 0, 0, 0) left_panel.setLayout(vlayout) splitter = QSplitter() splitter.addWidget(left_panel) splitter.addWidget(mono) splitter.setHandleWidth(10) splitter.setCollapsible(0, False) splitter.setCollapsible(1, False) splitter.setStretchFactor(1, 1) mainLayout = QHBoxLayout() mainLayout.addWidget(splitter) self.setLayout(mainLayout) if project_path is not None: self.scene.load(project_path) self.scene.run_all()
def build_central_content(self): main_panel = QSplitter(self) main_panel.setHandleWidth(1) main_panel.setOrientation(Qt.Vertical) main_panel.setContentsMargins(0, 0, 0, 0) from ui.panel_registers import RegistersPanel self.registers_panel = RegistersPanel(self.app, 0, 0) main_panel.addWidget(self.registers_panel) box = QVBoxLayout() box.setContentsMargins(0, 0, 0, 0) from ui.panel_memory import MemoryPanel self.memory_panel = MemoryPanel(self.app) box.addWidget(self.memory_panel) from ui.panel_java_explorer import JavaExplorerPanel self.java_explorer_panel = JavaExplorerPanel(self.app) self.java_explorer_panel.hide() box.addWidget(self.java_explorer_panel) q = QWidget() q.setLayout(box) main_panel.addWidget(q) from ui.panel_log import LogPanel self.log_panel = LogPanel(self.app) main_panel.addWidget(self.log_panel) main_panel.setStretchFactor(0, 1) main_panel.setStretchFactor(1, 3) main_panel.setStretchFactor(2, 1) return main_panel
def initUI(self): """Override.""" self._monitor_tb.setTabPosition(QTabWidget.TabPosition.South) self._monitor_tb.addTab(self._avail_src_view, "Available sources") self._monitor_tb.addTab(self._process_mon_view, "Process monitor") splitter = QSplitter(Qt.Vertical) splitter.setHandleWidth(self.SPLITTER_HANDLE_WIDTH) splitter.setChildrenCollapsible(False) splitter.addWidget(self._con_view) splitter.addWidget(self._src_view) splitter.addWidget(self._monitor_tb) splitter.setStretchFactor(0, 3) splitter.setStretchFactor(1, 1) h = splitter.sizeHint().height() splitter.setSizes([0.1 * h, 0.6 * h, 0.3 * h]) layout = QVBoxLayout() layout.addWidget(splitter) self.setLayout(layout) self._con_view.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self._src_view.expandToDepth(1) self._src_view.resizeColumnToContents(0) self._src_view.resizeColumnToContents(1)
def init_ui(self): self.init_menus() self.init_toolbar(QSize(40, 40)) mainWidget = QWidget(self) mainbox = QHBoxLayout(mainWidget) # self.setLayout(mainbox) topFrame = QFrame(mainWidget) topFrame.setFrameShape(QFrame.StyledPanel) btmFrame = QFrame(mainWidget) btmFrame.setFrameShape(QFrame.StyledPanel) splitter = QSplitter(Qt.Vertical) splitter.addWidget(topFrame) splitter.addWidget(btmFrame) # logText 30%, Plot 70% splitter.setStretchFactor(0, 4) splitter.setStretchFactor(1, 1) mainbox.addWidget(splitter) self.init_plot_area(topFrame) vboxLog = QVBoxLayout(btmFrame) self.logTextEdit = QPlainTextEdit("") self.logTextEdit.appendHtml("""<font size='4'>欢迎使用{}</font><p>""".format(progname)) self.logTextEdit.setReadOnly(True) vboxLog.addWidget(self.logTextEdit) mainWidget.setFocus() self.setCentralWidget(mainWidget) self.statusBar().showMessage("Ready") self.setWindowIcon(QIcon('res/load_network.png')) self.show()
def setupWidget(self, **kwargs): # create the frame self.frame = QFrame() # add the pv interactor object self.plotter = pv.QtInteractor(**kwargs) vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) self.statusbar = QStatusBar() self.setStatusBar(self.statusbar) self.toolbar = GToolBar() splitter = QSplitter(Qt.Horizontal) splitter.addWidget(self.toolbar) splitter.addWidget(self.plotter.interactor) splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 5) vlayout.addWidget(splitter) self.frame.setLayout(vlayout) self.setCentralWidget(self.frame) self.setWindowTitle("pyGIMLi 3D Viewer") # set the icon for the window ipath = os.path.dirname(__file__) icon = os.path.join(ipath, 'favicon.ico') self.setWindowIcon(QIcon(icon))
def buildUI(self): self.fig = Figure() self.zoom = 1 self.mapCanvas = FigureCanvas(self.fig) self.mapCanvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) main_splitter = QSplitter(Qt.Vertical) self.map_settings_widget = IPMapSettingsWidget() main_splitter.addWidget(self.map_settings_widget) main_splitter.addWidget(self.mapCanvas) main_splitter.setStretchFactor(0, 0) main_splitter.setStretchFactor(1, 1) # I want to make sure the splitter handle is easily seen... main_splitter.setStyleSheet( "QSplitter::handle{ background-color: #444444}") main_splitter.setHandleWidth(2) main_layout = QVBoxLayout() main_layout.addWidget(main_splitter) self.setLayout(main_layout) self.compute_initial_figure() self.connect_signals_and_slots()
class CentralWidget(QWidget): def __init__(self, communicator): super().__init__() self.initUI(communicator) self.setStyleSheet("QWidget {border: 0;}") def initUI(self, communicator): self.questionBlock = Questions(communicator) self.lectionBlock = Lection(communicator) layout = QHBoxLayout() layout.setSpacing(0) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(self.lectionBlock) self.splitter.addWidget(self.questionBlock) self.splitter.setHandleWidth(0) self.splitter.setStretchFactor(0, 5) self.splitter.setStretchFactor(1, 2) self.splitter.setStyleSheet( "QWidget {background-color: #78aef9;border:0;}") layout.addWidget(self.splitter) self.setContentsMargins(-10, -10, -10, -10) self.setLayout(layout) QApplication.setStyle(QStyleFactory.create('Cleanlooks')) def closeEvent(self, event): os.exit(0)
class MainWidget(QWidget): """ 主界面,用来包含柱形图和蜡烛图, 使用QGraphicscene来管理 """ def __init__(self): super(MainWidget, self).__init__() self.setAttribute(Qt.WA_StyledBackground, True) self.setWindowTitle('多图表展示') self.initUi() def initUi(self): self.candlestickChart = CandlestickChartView() self.volChart = VolChartView() self._splitter = QSplitter(Qt.Vertical, self) self._splitter.addWidget(self.candlestickChart) self._splitter.addWidget(self.volChart) self._splitter.setStretchFactor(7, 3) vlayout = QVBoxLayout(self) vlayout.addWidget(self._splitter) self.setLayout(vlayout)
class MainView(QWidget): """ 主页面 """ def __init__(self): super(MainView, self).__init__() self.k_view = KLineChartView() self.v_view = VLineChartView() # self.resize(800, 600) self.showMaximized() self.v_splitter = QSplitter(Qt.Vertical, self) self.v_splitter.addWidget(self.k_view) self.v_splitter.addWidget(self.v_view) self.v_splitter.setStretchFactor(0, 3) self.v_splitter.setStretchFactor(1, 1) layout = QVBoxLayout() # layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.v_splitter) self.setLayout(layout) def resizeEvent(self, event): super(MainView, self).resizeEvent(event) margin_k = self.k_view.chart().margins() margin_v = self.v_view.chart().margins() width_k = self.k_view.chart().plotArea().width() width_v = self.v_view.chart().plotArea().width() sub = width_k - width_v if sub > 0: self.k_view.chart().setMargins( QMargins(margin_k.left() + sub, margin_k.top(), margin_k.right(), margin_k.bottom())) else: self.v_view.chart().setMargins( QMargins(margin_v.left() - sub, margin_v.top(), margin_v.right(), margin_v.bottom()))
def initSplit(self): hbox3 = QHBoxLayout(self) self.topleft = TopLeft(self) self.bottomleft = BottomLeft(self) self.right = Right(self) splitter1 = QSplitter(Qt.Vertical) splitter1.addWidget(self.topleft) splitter1.addWidget(self.bottomleft) splitter1.setStretchFactor(1, 2) index = splitter1.indexOf(self.topleft) splitter1.setCollapsible(index, False) index3 = splitter1.indexOf(self.bottomleft) splitter1.setCollapsible(index3, False) splitter2 = QSplitter(Qt.Horizontal) splitter2.addWidget(splitter1) splitter2.addWidget(self.right) splitter2.setStretchFactor(1, 10) index2 = splitter2.indexOf(splitter1) splitter2.setCollapsible(index2, False) hbox3.addWidget(splitter2) self.setLayout(hbox3)
def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) #tabbed view that displays the design hierarchy in tree form self.folderView = QTabWidget() self.constraintView = FileTree(self, None, None) self.hierarchy = Hierarchy(self) self.fileTree = FileTree(self, self.hierarchy, self.constraintView) self.folderView.addTab(self.fileTree, "Files") self.folderView.addTab(self.hierarchy, "Hierarchy") self.folderView.addTab(self.constraintView, "Constraints") #parts of the search bar to search for certain files in the tabbed view searchBarLabel = QLabel() searchBarLabel.setText("Search modules:") self.searchBar = QLineEdit() self.searchBar.setStatusTip('Search modules') self.searchBar.textChanged.connect(self.fileTree.searchModule) #tabbed view to view and edit files self.fileView = QTabWidget() self.fileView.tabBarClicked.connect(self.openTab) self.fileView.tabCloseRequested.connect(self.closeTab) self.fileView.setTabsClosable(True) self.fileView.setMovable(True) #helpers to keep track of which editor is being viewed by the user self.textEdit = CodeEditor("verilog") self.editors = {} self.filePaths = {} #creates the basic layout for the user interface wid = QWidget(self) self.setCentralWidget(wid) rightSide = QWidget(self) leftSide = QWidget(self) hbox = QHBoxLayout(wid) vrbox = QVBoxLayout(rightSide) vrbox.addWidget(self.fileView) vlbox = QVBoxLayout(leftSide) vlbox.addWidget(searchBarLabel) vlbox.addWidget(self.searchBar) vlbox.addWidget(self.folderView) rightSide.setLayout(vrbox) leftSide.setLayout(vlbox) main_splitter = QSplitter(Qt.Horizontal) main_splitter.addWidget(leftSide) main_splitter.addWidget(rightSide) main_splitter.setStretchFactor(0, 1) main_splitter.setStretchFactor(1, 6) hbox.addWidget(main_splitter) wid.setLayout(hbox) # set up the status bar and file menus self.statusBar() self.setUpMenus() self.center() self.show()
def __init__(self): QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("application main window") self.createActions() self.createMenus() #> the main layout: left part (for the hdf5 tree view) and right part (for the figures and data) self.main_widget = QWidget(self) #> if not putting splitter into a layout, the widgets in splitter do not fill the main windows #> (may exceed the app windows, so that the figures are partially shown ). layout = QVBoxLayout(self.main_widget) hSplitter = QSplitter(self.main_widget) layout.addWidget(hSplitter) #number of space dimension self.n_dim = 1 #> the left part: the hdf5 tree view self.filename_data = "data/data0.h5" self.filename_grid = "data/grid.h5" self.tree_widget = HDFTreeWidget(self.main_widget) self.tree_model = HDFTreeModel([]) if os.path.exists(self.filename_data): self.tree_model.openFile(self.filename_data, 'r+') h5_file = h5.File(self.filename_data) self.n_dim = h5_file.attrs['n_dim'] print("data file n_dim: ", self.n_dim) if os.path.exists(self.filename_grid): self.tree_model.openFile(self.filename_grid, 'r+') h5_file = h5.File(self.filename_grid) self.n_dim = h5_file.attrs['n_dim'] print("grid file n_dim: ", self.n_dim) self.tree_widget.setModel(self.tree_model) hSplitter.addWidget(self.tree_widget) self.tree_widget.doubleClicked.connect(self.reload) self.sigOpen.connect(self.tree_widget.openFiles) #> plotWidget if self.n_dim == 1: self.plot_widget = PlotWidget1D(self.main_widget) elif self.n_dim == 2: self.plot_widget = PlotWidget2D(self.main_widget) elif self.n_dim == 3: self.plot_widget = PlotWidget3D(self.main_widget) hSplitter.addWidget(self.plot_widget) hSplitter.setStretchFactor(0, 2) hSplitter.setStretchFactor(1, 3) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) self.statusBar().showMessage("All hail matplotlib!", 2000)
def _init_ui(self): layout = QGridLayout(self) q_splitter = QSplitter(Qt.Horizontal, self) q_splitter.setStretchFactor(0, 0.2) q_splitter.setStretchFactor(2, 0.7) q_splitter.addWidget(self.database_window) q_splitter.addWidget(self.selected_window) q_splitter.addWidget(self.crystal_3d) layout.addWidget(q_splitter)
def create_layout(self): figure = Figure((8.0, 6.0), dpi=100) self.canvas = FigureCanvas(figure) main_view = QWidget() self.canvas.setParent(main_view) self.axes = figure.add_subplot(111) mpl_toolbar = NavigationToolbar(self.canvas, main_view) self.qcb_show_points.setChecked(DISPLAY_POINTS) self.qcb_show_points.stateChanged.connect(self.on_show) self.qcb_show_legend.setChecked(DISPLAY_LEGEND) self.qcb_show_legend.stateChanged.connect(self.on_show) self.qpb_show.clicked.connect(self.on_show) qvb_graph = QVBoxLayout() qvb_graph.addWidget(self.canvas) qvb_graph.addWidget(mpl_toolbar) qw_graph = QWidget() qw_graph.setLayout(qvb_graph) qf_separator = QFrame() qf_separator.setFrameShape(QFrame.HLine) qhb_time_unit = QHBoxLayout() for unit in TIME_UNITS.keys(): qrb_unit = QRadioButton(unit) if self.parent.time_unit == unit: qrb_unit.setChecked(True) else: qrb_unit.setChecked(False) self.qbg_time_unit.addButton(qrb_unit) qhb_time_unit.addWidget(qrb_unit) self.qbg_time_unit.buttonClicked.connect(self.time_unit_changed) self.qvb_options.addStretch(1) self.qvb_options.addWidget(qf_separator) self.qvb_options.addStretch(1) self.qvb_options.addLayout(qhb_time_unit) self.qvb_options.addWidget(self.qcb_show_points) self.qvb_options.addWidget(self.qcb_show_legend) self.qvb_options.addWidget(self.qpb_show) qw_options = QWidget() qw_options.setLayout(self.qvb_options) splitter = QSplitter() splitter.addWidget(qw_options) splitter.addWidget(qw_graph) splitter.setHandleWidth(10) splitter.setCollapsible(0, False) splitter.setCollapsible(1, False) splitter.setStretchFactor(1, 1) main_layout = QHBoxLayout() main_layout.addWidget(splitter) self.setLayout(main_layout)
def __init__(self, filename=None): super(App, self).__init__() self.is_write = False self.backup_file = os.path.join(os.getcwd(), '.tmp.json') self.setWindowTitle(GUI_NAME) self.filedialog = FileDialog(self) # self.table = Table(self) self.address_space = {} self.info = InfoDialog(title=GUI_NAME, parent=self) self.threadpool = QThreadPool() self.data = {'project': '', 'top_module': '', 'blocks': []} self.undoStack = QUndoStack() self.treeUndoStack = QUndoStack() self.treeUndoStack.setUndoLimit(50) self.tree = BlockView(parent=self, cols=register_columns, blocks=self.data['blocks'], undoStack=self.treeUndoStack) self.table = FieldView(parent=self, cols=field_columns, items=[], undoStack=self.undoStack) self.tree.selectionChanged.connect(self.createTable) self.hbox = QHBoxLayout() splitter = QSplitter(Qt.Horizontal) splitter.addWidget(self.tree) splitter.addWidget(self.table) splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 5) self.hbox.addWidget(splitter) self.setCentralWidget(QWidget(self)) self.tabs = TabLayout(self) self.tabs.setContentsMargins(0, 0, 0, 0) tab1 = QWidget(self) tab1.setLayout(self.hbox) self.analyzer = AnalyzerWapper(parent=self, cols=field_columns, address_space=self.address_space, reload=self.reload_address) self.tabs.setTab(tab1, title='RegisterProfile') self.tabs.setTab(self.analyzer, title='RegisterAnalyzer') self.setCentralWidget(self.tabs) self.menubar = self.menuBar() self.create_ui() if self.check_backup(): self.loadFiles([self.backup_file]) else: if filename: self.loadFiles([filename]) # self.table.tableSaved.connect(self.backUpFile) self.tree.addAnalyzerTrigger.connect(self.analyzer.add_analyzer) self.undoStack.indexChanged.connect(self.backUpFile)
def __init__(self, widgets): super(QResizableWidget, self).__init__() layout = QVBoxLayout() splitter = QSplitter(QtCore.Qt.Horizontal) splitter.setStretchFactor(1, 1) for widget in widgets: splitter.addWidget(widget) splitter.setSizes([200, 200]) layout.addWidget(splitter) self.setLayout(layout)
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle('Syntax Highlighter') self.currentFilepath = None self.setupFileMenu() self.setupHelpMenu() self.setupEditor() splitter = QSplitter() splitter.setOrientation(Qt.Horizontal) tocPane = TocView() googleDriveExplorer = GoogleDriveExplorerView() quoteBar = QuoteBar() statusBar = StatusBar() dictPane = DictPane() leftPaneTabs = QTabWidget() leftPaneTabs.addTab(tocPane, 'Índice') googleDriveIcon = QIcon('controls/google-drive.svg') leftPaneTabs.addTab(googleDriveExplorer, googleDriveIcon, 'Google Drive') centerPaneLayoutWrapper = QWidget() centerPaneLayout = QVBoxLayout(centerPaneLayoutWrapper) rightPaneTabs = QTabWidget() rightPaneTabs.addTab(dictPane.getWrapper(), 'Diccionario') rightPaneTabs.addTab(QWidget(), 'Notas') rightPaneTabs.addTab(QWidget(), 'Estadísticas') # Avoid weird spacing between layout and it's wrapper centerPaneLayout.setSpacing(0) centerPaneLayout.setContentsMargins(QMargins(0, 0, 0, 0)) centerPaneLayout.addWidget(quoteBar.getWrapper()) centerPaneLayout.addWidget(self.editor) centerPaneLayout.addWidget(statusBar.getWrapper()) splitter.addWidget(leftPaneTabs) splitter.addWidget(centerPaneLayoutWrapper) splitter.addWidget(rightPaneTabs) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 2) splitter.setStretchFactor(2, 1) self.setCentralWidget(splitter) self.openFile('/Users/mohedano/Downloads/30.md')
def init_ui(self): glay_lup = QHBoxLayout() glay_lup.addWidget(self.btn_fo) glay_lup.addWidget(self.btn_pid) glay_lup.addWidget(self.btn_uid) glay_lup.addWidget(self.btn_snao) glay_ldown = QGridLayout() glay_ldown.addWidget(QLabel('画廊ID'), 0, 0, 1, 1) glay_ldown.addWidget(self.ledit_pid, 0, 1, 1, 5) glay_ldown.addWidget(QLabel('用户ID'), 1, 0, 1, 1) glay_ldown.addWidget(self.ledit_uid, 1, 1, 1, 5) glay_ldown.addWidget(QLabel('数量'), 2, 0, 1, 1) glay_ldown.addWidget(self.ledit_num, 2, 1, 1, 1) glay_ldown.setColumnStretch(1, 1) glay_ldown.setColumnStretch(2, 5) vlay_left = QVBoxLayout() vlay_left.addLayout(glay_lup) vlay_left.addLayout(glay_ldown) hlay_thumb = QHBoxLayout() hlay_thumb.addLayout(vlay_left) hlay_thumb.addWidget(self.thumbnail) left_wid = QWidget() left_wid.setLayout(hlay_thumb) self.thumbnail.setFixedHeight(left_wid.sizeHint().height()) self.thumbnail.setFixedWidth(150) self.thumbnail.setPixmap(self.thumb_default) if self.show_thumb_flag: self.thumbnail.show() else: self.thumbnail.hide() vlay_right = QVBoxLayout() vlay_right.addWidget(self.user_info, alignment=Qt.AlignHCenter) vlay_right.addWidget(self.btn_logout) vlay_right.addWidget(self.btn_get) vlay_right.addWidget(self.btn_dl) right_wid = QWidget() right_wid.setLayout(vlay_right) splitter = QSplitter(Qt.Horizontal) splitter.setHandleWidth(3) splitter.addWidget(left_wid) splitter.addWidget(right_wid) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 0) splitter.handle(1).setDisabled(True) vlay_main = QVBoxLayout() vlay_main.addWidget(splitter) vlay_main.addWidget(self.table_viewer) self.setLayout(vlay_main)
def __init__(self, app, *__args): super().__init__(*__args) self.app = app self.handle_history = [] box = QVBoxLayout() box.setContentsMargins(0, 0, 0, 0) self.clazz = QLabel() font = QFont() font.setBold(True) font.setPixelSize(19) self.clazz.setMaximumHeight(40) self.clazz.setFont(font) self.clazz.setStyleSheet('margin: 5px 10px;') box.addWidget(self.clazz) splitter = QSplitter() splitter.setHandleWidth(1) left_col = QWidget() left_layout = QVBoxLayout() left_layout.setContentsMargins(0, 0, 0, 0) left_layout.addWidget(QLabel('methods')) self.methods = JavaMethodsWidget(self) left_layout.addWidget(self.methods) left_col.setLayout(left_layout) splitter.addWidget(left_col) central_col = QWidget() central_layout = QVBoxLayout() central_layout.setContentsMargins(0, 0, 0, 0) central_layout.addWidget(QLabel('native fields')) self.native_fields = JavaFieldsWidget(self, ['name', 'value'], True) central_layout.addWidget(self.native_fields) central_col.setLayout(central_layout) splitter.addWidget(central_col) right_col = QWidget() right_layout = QVBoxLayout() right_layout.setContentsMargins(0, 0, 0, 0) right_layout.addWidget(QLabel('fields')) self.fields = JavaFieldsWidget(self, ['name', 'class'], False) right_layout.addWidget(self.fields) right_col.setLayout(right_layout) splitter.addWidget(right_col) splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 1) splitter.setStretchFactor(2, 1) box.addWidget(splitter) self.setLayout(box)
def loadSplitter(self): w1 = QWidget() w2 = QWidget() w1.setLayout(self.firstLayout) w2.setLayout(self.secondLayout) s = QSplitter(Qt.Horizontal) s.addWidget(w1) s.addWidget(w2) s.setCollapsible(0, False) s.setCollapsible(1, False) s.setStretchFactor(1, 1) self.setCentralWidget(s)
def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setWindowTitle("Maze and pc editor") self.setAcceptDrops(True) # add main widget and create its layout widget_main = QWidget() self.setCentralWidget(widget_main) # layout = QHBoxLayout() # widget_main.setLayout(layout) # create splitter widget to hold edit and view panes splitter = QSplitter(Qt.Horizontal) # splitter.setSizes([600, 600]) # layout.addWidget(splitter) pane_edit = QTabWidget() pane_plot = PanelDataPlotting() self.pane_plot = pane_plot splitter.addWidget(pane_edit) splitter.addWidget(pane_plot) splitter.setStretchFactor(1, 1) # create and add tab widget for pc and maze editting self.tab_pcs = tab_pcs = PanelPCEdit() self.tab_maze = tab_maze = PanelMazeEdit() pane_edit.addTab(tab_pcs, "PCs") pane_edit.addTab(tab_maze, "maze") self.pane_edit = pane_edit # create and set main widget's layout self.setCentralWidget(splitter) self.setMinimumSize(800, 450) self.createMenus() # connect signals and slots: tab_maze.wall_added.connect(pane_plot.gview.add_wall) tab_maze.feeder_added.connect(pane_plot.gview.add_feeder) tab_maze.start_pos_added.connect(pane_plot.gview.add_start_pos) tab_maze.signal_clear_paths.connect(pane_plot.gview.clear_paths) tab_maze.signal_paths_added.connect(pane_plot.gview.add_paths) tab_pcs.pc_added.connect(pane_plot.gview.add_pc) self.action_do_path_planner.triggered.connect( tab_maze.perform_path_planning) self.action_create_maze_metrics.triggered.connect( tab_maze.create_all_maze_metrics) self.action_create_layers.triggered.connect(tab_pcs.create_layers) self.action_create_layer_metrics.triggered.connect( tab_pcs.create_layer_metrics)
def build_splitter( parent: QWidget, widgets: list[tuple[int, QWidget]], orientation: Qt.Orientation, ) -> QSplitter: splitter = QSplitter(parent) splitter.setOrientation(orientation) for i, item in enumerate(widgets): stretch_factor, widget = item splitter.addWidget(widget) splitter.setStretchFactor(i, stretch_factor) return splitter
def __init__(self): QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("application main window") self.createActions() self.createMenus() #> the main layout: left part (for the hdf5 tree view) and right part (for the figures and data) self.main_widget = QWidget(self) #> if not putting splitter into a layout, the widgets in splitter do not fill the main windows #> (may exceed the app windows, so that the figures are partially shown ). layout = QVBoxLayout(self.main_widget) hSplitter = QSplitter(self.main_widget) layout.addWidget(hSplitter) #> the left part: the hdf5 tree view self.filename = "data_global.h5" self.f = h5.File(self.filename) try: dset = self.f["/Fields/Phi_global_avg"] except: dset = self.f["/Fields/Rho_global"] print("the data is 2d !!!") print("Attention: the dataset must be 4 dimensions") self.tree_widget = HDFTreeWidget(self.main_widget) self.tree_model = HDFTreeModel([]) self.tree_model.openFile(self.filename, 'r+') self.tree_widget.setModel(self.tree_model) hSplitter.addWidget(self.tree_widget) self.tree_widget.doubleClicked.connect(self.reload) self.sigOpen.connect(self.tree_widget.openFiles) #> the right part (a TabWidget): figures and data tab_widget = QTabWidget(self.main_widget) hSplitter.addWidget(tab_widget) hSplitter.setStretchFactor(0, 4) hSplitter.setStretchFactor(1, 3) #> figures tab self.plot_widget = PlotWidget(self.main_widget, dset) tab_widget.addTab(self.plot_widget, "Figures") #> data tab self.data_widget = HDFDatasetWidget(dataset=dset) tab_widget.addTab(self.data_widget, "data") self.main_widget.setFocus() self.setCentralWidget(self.main_widget) self.statusBar().showMessage("All hail matplotlib!", 2000)
def setup_layout(self): main_widget = QWidget() main_layout = QHBoxLayout() main_layout_splitter = QSplitter(Qt.Horizontal, self) main_widget.setLayout(main_layout) main_layout.addWidget(main_layout_splitter) main_layout_splitter.addWidget(self.selection_list) main_layout_splitter.addWidget(self.view_tabs) main_layout_splitter.setStretchFactor(0, 1) main_layout_splitter.setStretchFactor(1, 10) self.setCentralWidget(main_widget)
def setupViews(self): splitter = QSplitter() table = QTableView() self.pieChart = PieView() splitter.addWidget(table) splitter.addWidget(self.pieChart) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 1) table.setModel(self.model) self.pieChart.setModel(self.model) self.selectionModel = QItemSelectionModel(self.model) table.setSelectionModel(self.selectionModel) self.pieChart.setSelectionModel(self.selectionModel) table.horizontalHeader().setStretchLastSection(True) self.setCentralWidget(splitter)
class NetWorthView(AccountSheetView): def _setup(self): self._setupUi() self.sheet = self.nwsheet = NetWorthSheet(self.model.bsheet, view=self.treeView) self.graph = self.nwgraph = Chart(self.model.nwgraph, view=self.graphView) self.piechart = Chart(self.model.pie, view=self.pieChart) def _setupUi(self): self.resize(558, 447) self.mainLayout = QVBoxLayout(self) self.mainLayout.setSpacing(0) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.splitterView = QSplitter() self.splitterView.setChildrenCollapsible(False) self.splitterView.setOrientation(Qt.Vertical) self.subSplitterView = QSplitter() self.subSplitterView.setChildrenCollapsible(False) self.treeView = TreeView(self) self.treeView.setAcceptDrops(True) self.treeView.setFrameShape(QFrame.NoFrame) self.treeView.setFrameShadow(QFrame.Plain) self.treeView.setEditTriggers(QAbstractItemView.EditKeyPressed|QAbstractItemView.SelectedClicked) self.treeView.setDragEnabled(True) self.treeView.setDragDropMode(QAbstractItemView.InternalMove) self.treeView.setUniformRowHeights(True) self.treeView.setAllColumnsShowFocus(True) self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.treeView.header().setStretchLastSection(False) self.subSplitterView.addWidget(self.treeView) self.pieChart = PieChartView(self) self.pieChart.setMinimumSize(300, 0) self.subSplitterView.addWidget(self.pieChart) self.splitterView.addWidget(self.subSplitterView) self.graphView = LineGraphView(self) self.graphView.setMinimumSize(0, 200) self.splitterView.addWidget(self.graphView) self.splitterView.setStretchFactor(0, 1) self.splitterView.setStretchFactor(1, 0) self.subSplitterView.setStretchFactor(0, 1) self.subSplitterView.setStretchFactor(1, 0) self.mainLayout.addWidget(self.splitterView)
def setupViews(self): splitter = QSplitter() splitter.setHandleWidth(5) browsers = QTabWidget() label = QLabel('Placeholder') label.setAlignment(Qt.AlignCenter|Qt.AlignHCenter|Qt.AlignVCenter) layout = QHBoxLayout() layout.addWidget(label) rightPane = QWidget() rightPane.setLayout(layout) splitter.addWidget(browsers) splitter.addWidget(rightPane) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 1) self.setCentralWidget(splitter)
def setupViews(self): splitter = QSplitter() self.table = QTableView() self.pieChart = PieView() splitter.addWidget(self.pieChart) splitter.addWidget(self.table) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 0) self.table.setModel(self.model) self.pieChart.setModel(self.model2) self.selectionModel = QItemSelectionModel(self.model2) self.table.setSelectionModel(self.selectionModel) #self.pieChart.setSelectionModel(self.selectionModel) #table.setColumnWidth(0,100) self.setCentralWidget(splitter) self.table.doubleClicked.connect(self.ClickAction_table)
def __init__(self, parent=None): super().__init__(parent) self.editor = PythonEditor(self) self.fileChooser = FileChooser(self) self.fileChooser.fileOpened.connect(self.openFile) self.outputEdit = OutputEdit(self) splitter = QSplitter(self) self.vSplitter = QSplitter(Qt.Vertical, splitter) self.vSplitter.addWidget(self.editor) self.vSplitter.addWidget(self.outputEdit) self.vSplitter.setStretchFactor(0, 1) self.vSplitter.setStretchFactor(1, 0) splitter.addWidget(self.fileChooser) splitter.addWidget(self.vSplitter) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 1) statusBar = ScriptingStatusBar(self) self.setCentralWidget(splitter) self.setStatusBar(statusBar) self.newFile() self.editor.modificationChanged.connect(self.setWindowModified) statusBar.setPosition(self.editor.textCursor()) self.editor.cursorPositionChanged.connect( lambda: statusBar.setPosition(self.sender().textCursor())) statusBar.setIndent(self.editor.indent()) self.editor.indentChanged.connect(statusBar.setIndent) statusBar.indentModified.connect(self.editor.setIndent) statusBar.positionClicked.connect(self.gotoLine) statusBar.clearButtonClicked.connect(self.outputEdit.clear) statusBar.runButtonClicked.connect(self.runScript) gotoLineShortcut = QShortcut(QKeySequence("Ctrl+G"), self) gotoLineShortcut.activated.connect(self.gotoLine) self.readSettings() splitter.splitterMoved.connect(self.writeSettings) self.vSplitter.splitterMoved.connect(self.writeSettings)
class WindowUI(object): def widgetTraining(self): return TrainingWidget(self.classes_tree_view) def widgetRecognition(self): return RecognitionWidget(self.classes_tree_view) def widgetDataset(self): return DatasetWidget(self.classes_tree_view) def setupUI(self): """Create User Interface. """ mainWidget = QWidget() mainLayout = QHBoxLayout() tabs = QTabWidget() self.classes_tree_view = ClassesTreeView(self) tabs.addTab(self.widgetDataset(), self.tr("Dataset")) tabs.addTab(self.widgetTraining(), self.tr("Training")) tabs.addTab(self.widgetRecognition(), self.tr("Recognition")) leftLayout, rightLayout = QHBoxLayout(), QHBoxLayout() leftLayout.addWidget(self.classes_tree_view) rightLayout.addWidget(tabs) left, right = QWidget(), QWidget() left.setLayout(leftLayout) right.setLayout(rightLayout) self.hsplitter = QSplitter(QtCore.Qt.Horizontal) self.hsplitter.addWidget(left) self.hsplitter.addWidget(right) self.hsplitter.setStretchFactor(1, 3) mainLayout.addWidget(self.hsplitter) mainWidget.setLayout(mainLayout) self.setCentralWidget(mainWidget)
def __initUI__(self): # ---- TAB WIDGET # download weather data : splash.showMessage("Initializing download weather data...") self.tab_dwnld_data = DwnldWeatherWidget(self) self.tab_dwnld_data.set_workdir(self.projectdir) # gapfill weather data : splash.showMessage("Initializing gapfill weather data...") self.tab_fill_weather_data = GapFillWeatherGUI(self) self.tab_fill_weather_data.set_workdir(self.projectdir) # hydrograph : splash.showMessage("Initializing plot hydrograph...") self.tab_hydrograph = HydroPrint.HydroprintGUI(self.dmanager) splash.showMessage("Initializing analyse hydrograph...") self.tab_hydrocalc = HydroCalc.WLCalc(self.dmanager) self.tab_hydrocalc.sig_new_mrc.connect( self.tab_hydrograph.mrc_wl_changed) self.tab_hydrocalc.rechg_eval_widget.sig_new_gluedf.connect( self.tab_hydrograph.glue_wl_changed) # ---- TABS ASSEMBLY self.tab_widget = TabWidget() self.tab_widget.addTab(self.tab_dwnld_data, 'Download Weather') self.tab_widget.addTab(self.tab_fill_weather_data, 'Gapfill Weather') self.tab_widget.addTab(self.tab_hydrograph, 'Plot Hydrograph') self.tab_widget.addTab(self.tab_hydrocalc, 'Analyze Hydrograph') self.tab_widget.setCornerWidget(self.pmanager) self.tab_widget.currentChanged.connect(self.sync_datamanagers) # ---- Main Console splash.showMessage("Initializing main window...") self.main_console = QTextEdit() self.main_console.setReadOnly(True) self.main_console.setLineWrapMode(QTextEdit.NoWrap) style = 'Regular' family = StyleDB().fontfamily size = self.whatPref.fontsize_console fontSS = ('font-style: %s;' 'font-size: %s;' 'font-family: %s;' ) % (style, size, family) self.main_console.setStyleSheet("QWidget{%s}" % fontSS) msg = '<font color=black>Thanks for using %s.</font>' % __appname__ self.write2console(msg) self.write2console('<font color=black>' 'Please report any bug or wishful feature at' ' [email protected].' '</font>') # ---- Signal Piping issuer = self.tab_dwnld_data issuer.ConsoleSignal.connect(self.write2console) issuer = self.tab_fill_weather_data issuer.ConsoleSignal.connect(self.write2console) issuer = self.tab_hydrograph issuer.ConsoleSignal.connect(self.write2console) # ---- Splitter Widget splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.tab_widget) splitter.addWidget(self.main_console) splitter.setCollapsible(0, True) splitter.setStretchFactor(0, 100) # Forces initially the main_console to its minimal height: splitter.setSizes([100, 1]) # ---- Main Grid main_widget = QWidget() self.setCentralWidget(main_widget) mainGrid = QGridLayout(main_widget) mainGrid.addWidget(splitter, 0, 0) mainGrid.addWidget(self.tab_fill_weather_data.pbar, 1, 0) mainGrid.addWidget(self.tab_dwnld_data.pbar, 2, 0) mainGrid.addWidget( self.tab_hydrocalc.rechg_eval_widget.progressbar, 3, 0)
class RunWidget(QWidget): running = False device_list_signal = pyqtSignal(list, name="device_list_signal") cases = [] def __init__(self, tester, *args, **kwargs): super().__init__(*args, **kwargs) ui_dir_path = os.path.dirname(__file__) ui_file_path = os.path.join(ui_dir_path, 'case_run.ui') uic.loadUi(ui_file_path, self) # set icon run_icon = QIcon() self.tester = tester self.config = self.tester.get_config() run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off) self.run_stop_btn.setIcon(run_icon) add_icon = QIcon() add_icon.addPixmap(QPixmap(self.config.images + '/add.png'), QIcon.Normal, QIcon.Off) self.addbtn.setIcon(add_icon) self.message_box = QMessageBox() self.dBCommandLineHelper = DBCommandLineHelper() self.addbtn.clicked.connect(self.click_add_case) self.run_stop_btn.clicked.connect(self.click_run_stop_btn) self.add_case_widget = None self.add_device_widget = None self.splitter = None self.case_widget = RunnerTableWidget([], [0]) self.log_area = Console() self.splitter_setting() self.status_listener = CaseRunStatusListener() self.status_listener.listener_msg_signal.connect(self.update_case_name_color, Qt.QueuedConnection) self.tester.add_run_status_listener(self.status_listener) def splitter_setting(self): """ set splitter :return: """ if self.splitter: self.splitter = None self.splitter = QSplitter(Qt.Vertical) self.splitter.setHandleWidth(1) # add "case_widget" and "log_area" to splitter self.splitter.addWidget(self.case_widget) self.splitter.addWidget(self.log_area) # set the initial scale: 4:1 self.splitter.setStretchFactor(0, 4) self.splitter.setStretchFactor(1, 1) self.case_table_layout.addWidget(self.splitter) def click_add_case(self): """ click the button to show add case widget :return: """ self.add_case_widget = AddCaseWidget() self.add_case_widget.select_case_signal.connect(self.show_cases, Qt.QueuedConnection) self.add_case_widget.setWindowModality(Qt.ApplicationModal) self.add_case_widget.show() def click_run_stop_btn(self): """ start or stop to run case :return: """ devices = [] if self.running: self.stop_case() return if not self.cases: # cases is null self.message_box.warning(self, "Message", "Please add cases first.", QMessageBox.Ok) return try: devices = self.tester.devices() except Exception as e: self.add_log("<font color='red'>" + str(e) + "</font>") if not devices: # There is no device connected self.message_box.warning(self, "Message", "Please connect the device to your computer.", QMessageBox.Ok) return self.add_device_widget = AddDeviceWidget() self.add_device_widget.setWindowModality(Qt.ApplicationModal) self.add_device_widget.add_log_signal.connect(self.add_log, Qt.QueuedConnection) self.add_device_widget.run_case_signal.connect(self.run_case, Qt.QueuedConnection) self.device_list_signal.connect(self.add_device_widget.add_radio_to_widget, Qt.QueuedConnection) self.add_device_widget.show() try: self.device_list_signal.emit(devices) except Exception as e: self.add_log("<font color='red'><pre>" + str(e) + "</pre></font>") def add_log(self, log_info): """ add log to log_area :return: """ if self.log_area is None: return self.log_area.append(log_info) def update_case_name_color(self, msg, is_passed): """ update case's font color according to the case's result pass: green; fail: red :param is_passed: :param msg: :return: """ if msg.status == 601: self.add_log("<font color='green'> Start to install agent.</font>") elif msg.status == 602: self.add_log("<font color='green'> Install agent success.</font>") elif msg.status == 603: self.add_log("<font color='red'> Install agent Fail." + "\r Error Info:\r<pre>" + msg.message + "</pre></font>") elif msg.status == 701: self.add_log("<font color='green'> Start agent.</font>") elif msg.status == 702: self.add_log("<font color='green'> Stop agent.</font>") elif msg.status == 703: self.add_log("<font color='red'> Agent error." + "\r Error Info:\r<pre>" + msg.message + "</pre></font>") for row_index in range(self.case_widget.dataTableWidget.rowCount()): case_id_item = self.case_widget.dataTableWidget.item(row_index, 1) # get case id from dataTableWidget if msg.status == 2: # test end if is_passed: self.add_log("<font color='green'> All cases are Passed.</font>") self.stop_case() break if case_id_item.text() != str(msg.case_id): continue self.case_widget.dataTableWidget.selectRow(row_index) if msg.status == 101: # default: case pass self.update_green(row_index) elif msg.status == 500: self.update_red(row_index) self.add_log("<font color='red'> Case Failed, case id: " + str(msg.case_id) + "</font>") self.add_log("<pre><font color='red'>" + str(msg.message) + "</font></pre>") def run_case(self, devices): kw_case_list = [] if not self.cases: return for case_id in self.cases: kw_case = KWCase() case = self.dBCommandLineHelper.query_case_by_id(case_id) kw_case.id = case.id kw_case.name = case.name kw_case.content = case.content kw_case.data = case.data kw_case_list.append(kw_case) # set icon stop_icon = QIcon() stop_icon.addPixmap(QPixmap(self.config.images + '/stop.png'), QIcon.Normal, QIcon.Off) self.run_stop_btn.setIcon(stop_icon) self.run_stop_btn.setText("Stop") self.running = True if not devices: return try: self.tester.select_devices(devices) self.tester.run(kw_case_list) except Exception as e: self.stop_case() self.add_log(str(e)) def stop_case(self): run_icon = QIcon() run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off) self.run_stop_btn.setIcon(run_icon) # change icon self.run_stop_btn.setText("Run") self.running = False try: self.tester.stop() self.tester.stop_server() except Exception as e: self.add_log(str(e)) def show_cases(self, id_list): """ show cases in RunnerTableWidget according to id list :param id_list: :return: """ self.case_table_layout.removeWidget(self.splitter) case_list = [] self.cases = id_list for case_id in id_list: case = self.dBCommandLineHelper.query_case_by_id(case_id) case_list.append(case) self.case_widget = RunnerTableWidget(case_list, [0]) self.splitter_setting() # reload splitter def update_green(self, row_index): """ update item text color to green by row number :param row_index: :return: """ brush_green_color = QBrush(QColor(55, 177, 88)) for column_index in range(self.case_widget.dataTableWidget.columnCount()): item = self.case_widget.dataTableWidget.item(row_index, column_index) item.setForeground(brush_green_color) def update_red(self, row_index): """ update item text color to red by row number :param row_index: :return: """ brush_red_color = QBrush(QColor(255, 0, 0)) for column_index in range(self.case_widget.dataTableWidget.columnCount()): item = self.case_widget.dataTableWidget.item(row_index, column_index) item.setForeground(brush_red_color)
class DatasetWidgetUI(object): def folderWidget(self): widget = QWidget() layout = QHBoxLayout() label = QLabel(self.tr("Folder")) self.datasetFolder = QLineEdit() self.selectFolderButton = QPushButton(self.tr("...")) self.selectFolderButton.setMaximumWidth(40) layout.addWidget(label) layout.addWidget(self.datasetFolder) layout.addWidget(self.selectFolderButton) widget.setLayout(layout) return widget def prefixWidget(self): widget = QWidget() layout = QHBoxLayout() prefixLabel = QLabel(self.tr("Prefix:")) self.prefixLine = QLineEdit() self.prefixLine.setPlaceholderText(self.tr("login_x-")) self.prefixLine.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum) layout.addWidget(prefixLabel) layout.addWidget(self.prefixLine) widget.setLayout(layout) return widget def sizeWidget(self): widget = QWidget() layout = QHBoxLayout() sizeLabel = QLabel(self.tr("x")) self.widthBox = QSpinBox() self.heightBox = QSpinBox() layout.addWidget(self.widthBox) layout.addWidget(sizeLabel) layout.addWidget(self.heightBox) widget.setLayout(layout) return widget def randomWidget(self): group = QGroupBox("Randomize") layout = QGridLayout() self.randomCount = QSpinBox() layout.addWidget(QLabel(self.tr("Count")), 0, 0) layout.addWidget(self.randomCount, 0, 1) self.minBrushSize = BrushSizeWidget(15) self.maxBrushSize = BrushSizeWidget(50) layout.addWidget(QLabel(self.tr("Min")), 1, 0) layout.addWidget(self.minBrushSize, 1, 1) layout.addWidget(QLabel(self.tr("Max")), 2, 0) layout.addWidget(self.maxBrushSize, 2, 1) self.xAngle = QSpinBox() self.yAngle = QSpinBox() self.zAngle = QSpinBox() layout.addWidget(QLabel(self.tr("Angle X")), 3, 0) layout.addWidget(self.xAngle, 3, 1) layout.addWidget(QLabel(self.tr("Angle Y")), 4, 0) layout.addWidget(self.yAngle, 4, 1) layout.addWidget(QLabel(self.tr("Angle Z")), 5, 0) layout.addWidget(self.zAngle, 5, 1) container = QVBoxLayout() container.addLayout(layout) container.addStretch(1) group.setLayout(container) group.setFixedWidth(150) return group def toolbarSpacer(self): spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) return spacer def toolbarWidget(self): self.brushSizeWidget = BrushSizeWidget(self.brush_size, max_size=70) self.clearAction = QAction(QIcon("assets/clear.png"), "Clear", self) self.saveAction = QAction(QIcon("assets/save.png"), "Save", self) self.removeAction = QAction(QIcon("assets/remove.png"), "Remove", self) self.previewAction = QAction(QIcon("assets/preview.png"), "Preview", self) toolbar = QToolBar() toolbar.setIconSize(QSize(30, 30)) toolbar.addWidget(self.brushSizeWidget) toolbar.addSeparator() toolbar.addAction(self.clearAction) toolbar.addAction(self.saveAction) toolbar.addAction(self.removeAction) toolbar.addAction(self.removeAction) toolbar.addAction(self.previewAction) toolbar.addSeparator() toolbar.addWidget(self.sizeWidget()) toolbar.addWidget(self.prefixWidget()) toolbar.addWidget(self.toolbarSpacer()) return toolbar def setupUI(self): layout = QVBoxLayout() self.paintArea = PaintArea(self.brush_size) self.paintArea.installEventFilter(self) self.previewWidget = PreviewWidget() layout.addWidget(self.toolbarWidget()) hbox = QHBoxLayout() hbox.addWidget(self.randomWidget()) hbox.addWidget(self.paintArea) up = QWidget() up.setLayout(hbox) down = QWidget() hbox = QHBoxLayout() hbox.addWidget(self.previewWidget) down.setLayout(hbox) self.vsplitter = QSplitter(Qt.Vertical) self.vsplitter.addWidget(up) self.vsplitter.addWidget(down) self.vsplitter.setStretchFactor(1, 3) layout.addWidget(self.vsplitter) layout.addWidget(self.folderWidget()) self.setLayout(layout)
def initUI(self): self.statusBar().showMessage('Ready') self.left_action = QAction('上一个', self) self.left_action.setShortcut(QKeySequence.MoveToPreviousChar) self.left_action.triggered.connect(self.analyze_last_one_image) self.right_action = QAction('下一个', self) self.right_action.setShortcut(QKeySequence.MoveToNextChar) self.right_action.triggered.connect(self.analyze_next_one_image) self.rename_image_action = QAction('保存e2e文件名', self) self.rename_image_action.setShortcut(QKeySequence.MoveToPreviousLine) self.rename_image_action.triggered.connect(self.rename_current_image_with_info) self.statusBar() menubar = self.menuBar() fileMenu = menubar.addMenu('&Function') fileMenu.addAction(self.left_action) fileMenu.addAction(self.right_action) fileMenu.addAction(self.rename_image_action) self.image_window_view = HyperLprImageView() table_widget_header_labels = [ "文件名", "分割识别", "置信度", "颜色", "E2E识别", "E2E置信度"] self.hyperlpr_tableview = QTableWidget( 0, len(table_widget_header_labels)) self.hyperlpr_tableview.setHorizontalHeaderLabels( table_widget_header_labels) self.hyperlpr_tableview.setSelectionBehavior( QAbstractItemView.SelectItems) self.hyperlpr_tableview.setSelectionMode( QAbstractItemView.SingleSelection) self.hyperlpr_tableview.setEditTriggers( QAbstractItemView.NoEditTriggers) self.hyperlpr_tableview.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.hyperlpr_tableview.setEditTriggers( QAbstractItemView.NoEditTriggers) self.hyperlpr_tableview.cellClicked.connect( self.recognize_one_license_plate) self.left_button = QPushButton("<") self.left_button.setFixedWidth(60) self.right_button = QPushButton(">") self.right_button.setFixedWidth(60) self.left_button.setEnabled(False) self.right_button.setEnabled(False) self.left_button.clicked.connect(self.analyze_last_one_image) self.right_button.clicked.connect(self.analyze_next_one_image) left_right_layout = QHBoxLayout() left_right_layout.addStretch() left_right_layout.addWidget(self.left_button) left_right_layout.addStretch() left_right_layout.addWidget(self.right_button) left_right_layout.addStretch() self.location_label = QLabel("车牌目录", self) self.location_text = QLineEdit(self) self.location_text.setEnabled(False) #self.location_text.setFixedWidth(300) self.location_button = QPushButton("...") self.location_button.clicked.connect(self.select_new_dir) self.location_layout = QHBoxLayout() self.location_layout.addWidget(self.location_label) self.location_layout.addWidget(self.location_text) self.location_layout.addWidget(self.location_button) self.location_layout.addStretch() self.check_box = QCheckBox("与文件名比较车牌") self.check_box.setChecked(True) self.update_file_path_button = QPushButton('批量识别') self.update_file_path_button.clicked.connect( self.batch_recognize_all_images) self.update_file_path_layout = QHBoxLayout() self.update_file_path_layout.addWidget(self.check_box) self.update_file_path_layout.addWidget(self.update_file_path_button) self.update_file_path_layout.addStretch() self.save_as_e2e_filename_button = QPushButton("保存e2e文件名") self.save_as_e2e_filename_button.setEnabled(False) self.save_as_e2e_filename_button.clicked.connect(self.rename_current_image_with_info) self.save_layout = QHBoxLayout() self.save_layout.addWidget(self.save_as_e2e_filename_button) self.save_layout.addStretch() self.top_layout = QVBoxLayout() self.top_layout.addLayout(left_right_layout) self.top_layout.addLayout(self.location_layout) self.top_layout.addLayout(self.update_file_path_layout) self.top_layout.addLayout(self.save_layout) function_groupbox = QGroupBox("功能区") function_groupbox.setLayout(self.top_layout) license_plate_image_label = QLabel("车牌图") self.license_plate_widget = QLabel("") block_image_label = QLabel("分割图") self.block_plate_widget = QLabel("") filename_label = QLabel("文件名:") self.filename_edit = QLineEdit() segmentation_recognition_label = QLabel("分割识别:") self.segmentation_recognition_edit = QLineEdit() self.segmentation_recognition_edit.setFont(QFont("黑体", 24, QFont.Bold)) # self.segmentation_recognition_edit.setStyleSheet("color:red") confidence_label = QLabel("分割识别\n置信度") self.confidence_edit = QLineEdit() #self.confidence_edit.setFont(QFont("黑体", 24, QFont.Bold)) # self.confidence_edit.setStyleSheet("color:red") plate_color_label = QLabel("车牌颜色") self.plate_color_edit = QLineEdit() self.plate_color_edit.setFont(QFont("黑体", 24, QFont.Bold)) # self.plate_color_edit.setStyleSheet("color:red") e2e_recognization_label = QLabel("e2e识别:") self.e2e_recognization_edit = QLineEdit() self.e2e_recognization_edit.setFont(QFont("黑体", 24, QFont.Bold)) # self.e2e_recognization_edit.setStyleSheet("color:red") e2e_confidence_label = QLabel("e2e置信度") self.e2e_confidence_edit = QLineEdit() #self.e2e_confidence_edit.setFont(QFont("黑体", 24, QFont.Bold)) # self.e2e_confidence_edit.setStyleSheet("color:red") info_gridlayout = QGridLayout() line_index = 0 info_gridlayout.addWidget(filename_label, line_index, 0) info_gridlayout.addWidget(self.filename_edit, line_index, 1) line_index += 1 info_gridlayout.addWidget(license_plate_image_label, line_index, 0) info_gridlayout.addWidget(self.license_plate_widget, line_index, 1) line_index += 1 info_gridlayout.addWidget(e2e_recognization_label, line_index, 0) info_gridlayout.addWidget(self.e2e_recognization_edit, line_index, 1) line_index += 1 info_gridlayout.addWidget( segmentation_recognition_label, line_index, 0) info_gridlayout.addWidget( self.segmentation_recognition_edit, line_index, 1) line_index += 1 info_gridlayout.addWidget(plate_color_label, line_index, 0) info_gridlayout.addWidget(self.plate_color_edit, line_index, 1) line_index += 1 info_gridlayout.addWidget(block_image_label, line_index, 0) info_gridlayout.addWidget(self.block_plate_widget, line_index, 1) line_index += 1 info_gridlayout.addWidget(confidence_label, line_index, 0) info_gridlayout.addWidget(self.confidence_edit, line_index, 1) line_index += 1 info_gridlayout.addWidget(e2e_confidence_label, line_index, 0) info_gridlayout.addWidget(self.e2e_confidence_edit, line_index, 1) info_widget = QGroupBox("分割识别&e2e") info_widget.setLayout(info_gridlayout) right_splitter = QSplitter(Qt.Vertical) right_splitter.addWidget(self.hyperlpr_tableview) right_splitter.addWidget(function_groupbox) right_splitter.addWidget(info_widget) right_splitter.setStretchFactor(0, 2) right_splitter.setStretchFactor(2, 1) main_splitter = QSplitter(Qt.Horizontal) main_splitter.addWidget(self.image_window_view) main_splitter.addWidget(right_splitter) main_splitter.setStretchFactor(0, 1) self.image_filename_list = [] self.hyperlpr_dir_path = "" self.segmentation_recognition_correct_number = 0 self.color_correct_number = 0 self.e2e_recognization_correct_number = 0 self.current_row = 0 self.batch_recognization_thread = LicenseRecognizationThread() self.batch_recognization_thread.recognization_done_signal.connect( self.recognization_done_slot) self.batch_recognization_thread.start() self.start_init_signal.connect(self.read_path_and_show_one_image) self.setCentralWidget(main_splitter) self.setWindowTitle("HyperLPR车牌识别软件v1.0") self.start_init_signal.emit()
class EditorWidget(QWidget): device_and_data_signal = pyqtSignal(list, int, name="device_list_signal") import_list_signal = pyqtSignal(set, name="import_list_signal") close_cancel_signal = pyqtSignal(name="close_cancel_signal") def __init__(self, refresh_signal, tester, case_id=None, *args, **kwargs): super().__init__(*args, **kwargs) ui_dir_path = os.path.dirname(__file__) ui_file_path = os.path.join(ui_dir_path, 'case_editor.ui') uic.loadUi(ui_file_path, self) self.dBCommandLineHelper = DBCommandLineHelper() self.tester = tester self.config = self.tester.get_config() self.debug_runner = self.tester.get_debug_runner() self.case_id = case_id self.refresh_signal = refresh_signal self.init_ui() self.is_log_show = True self.is_running = False self.tag_list = [] self.parsed_line_list = [] self.case = None self.high_lighter = None self.tag_manage_widget = None self.add_device_widget = None self.message_box = QMessageBox() self.add_tag_button = SearchButton() self.tag_names_line_edit = TagLineEdit("tag_names_line_edit", self.add_tag_button) self.set_tag_name_completer() self.splitter = QSplitter(Qt.Vertical) self.splitter.setHandleWidth(1) # set handle width self.editor_text_edit = TextEdit(self.debug_runner.core) # case content TextEdit self.console = Console() # Add the 'editor text edit' and 'console' to splitter self.splitter.addWidget(self.editor_text_edit) self.splitter.addWidget(self.console) # Set the initial scale: 4:1 self.splitter.setStretchFactor(0, 4) self.splitter.setStretchFactor(1, 1) self.editor_layout.addWidget(self.splitter) self.import_list_signal.connect(self.editor_text_edit.get_import_from_content, Qt.QueuedConnection) self.editor_text_edit.parse_error_info_signal.connect(self.add_info_console, Qt.QueuedConnection) self.editor_adapter() # set completer and highlighter self.set_case_edit_data() # update case # run status listener self.status_listener = EditorRunStatusListener() self.status_listener.editor_listener_msg_signal.connect(self.result_handle, Qt.QueuedConnection) self.debug_runner.listener = self.status_listener self.data_line = None # button event self.save_btn.clicked.connect(self.save_case) self.run_btn.clicked.connect(self.run_btn_event) self.console_btn.clicked.connect(self.log_show_hide_event) self.edit_data_btn.clicked.connect(self.add_case_data) self.add_tag_button.clicked.connect(self.choose_event) # case data self.case_manager = CaseManager() self.case_data_manage = CaseDataManager() self.case_data_count = 0 # init case data count self.is_case_data_modify = False def init_ui(self): """ init ui, include: resize window :return: """ screen = QDesktopWidget().screenGeometry() self.resize(screen.width() / 2, screen.height() / 2) self.init_btn_icon() self.id_line_edit.hide() # hide line_edit self.case_name_line_edit.setPlaceholderText("Case Name") def init_btn_icon(self): """ init button icon, including: save button、run button、show/hide console button :return: """ save_icon = QIcon() save_icon.addPixmap(QPixmap(self.config.images + '/save.png'), QIcon.Normal, QIcon.Off) # save icon self.save_btn.setIcon(save_icon) run_icon = QIcon() run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off) # run icon self.run_btn.setIcon(run_icon) console_icon = QIcon() console_icon.addPixmap(QPixmap(self.config.images + '/console.png'), QIcon.Normal, QIcon.Off) # console icon self.console_btn.setIcon(console_icon) edit_data_icon = QIcon() edit_data_icon.addPixmap(QPixmap(self.config.images + '/edit.png'), QIcon.Normal, QIcon.Off) # console icon self.edit_data_btn.setIcon(edit_data_icon) def add_case_data(self): """ show case data widget :return: """ if hasattr(self, 'case_data_widget'): self.case_data_widget.close() self.case_data_widget = CaseDataWidget(self.case_id) self.case_data_widget.show() def choose_event(self): """ choose tag event, show tags :return: """ self.tag_manage_widget = TagManageWidget(self.config) self.tag_manage_widget.selected_tag_names_signal.connect(self.set_selected_tag_names) self.tag_manage_widget.setWindowModality(Qt.ApplicationModal) self.tag_manage_widget.show() def set_selected_tag_names(self, tag_names): """ set tag names :param tag_names: :return: """ original_tag_names = self.tag_names_line_edit.text().strip() tag_name_set = set(original_tag_names.split(";")) # original tag name set if not tag_names: return # handle the repeat tag names tag_name_list = tag_names.split(";") for tag_name in tag_name_list: if (tag_name.strip() in original_tag_names) or (not tag_name.strip()): continue tag_name_set.add(tag_name.strip()) # add new selected tag name all_tag_names = "" for tag_name in tag_name_set: if not tag_name.strip(): continue all_tag_names += tag_name.strip() + ";" self.tag_names_line_edit.is_completer = False self.tag_names_line_edit.setText(all_tag_names) self.tag_names_line_edit.is_completer = True def log_show_hide_event(self): if self.is_log_show: self.console_btn.setText("Show Console") self.console.hide() self.is_log_show = False else: self.console_btn.setText("Hide Console") self.console.show() self.is_log_show = True def add_info_console(self, info): """ append error massage to console :param info: :return: """ self.console.append(info) def result_handle(self, msg, is_passed): """ show the debug result in console :param is_passed: :param msg: :return: """ if msg.status == 601: self.add_info_console("<font color='green'> Start to install agent.</font>") elif msg.status == 602: self.add_info_console("<font color='green'> Install agent success.</font>") elif msg.status == 603: self.add_info_console("<font color='red'> Install agent Fail." + "\r Error Info:\r<pre>" + msg.message + "</pre></font>") elif msg.status == 701: self.add_info_console("<font color='green'> Start agent.</font>") elif msg.status == 702: self.add_info_console("<font color='green'> Stop agent.</font>") elif msg.status == 703: self.add_info_console("<font color='red'> Agent error." + "\r Error Info:\r<pre>" + msg.message + "</pre></font>") if msg.status == 500: # fail self.add_info_console("<font color='red'> <pre>" + str(msg.message) + "</pre></font>") if msg.status == 102 and is_passed: self.add_info_console("<font color='green'> The case is Passed.</font>") elif msg.status == 102 and not is_passed: self.add_info_console("<font color='red'> The case is Failed.</font>") def set_case_edit_data(self): """ init data for update case :return: """ if not self.case_id: return self.case = self.dBCommandLineHelper.query_case_by_id(self.case_id) self.id_line_edit.setText(self.case_id) self.case_name_line_edit.setText(self.case.name) tags = '' for tag in self.case.tags: tags = tags + tag.name + ";" self.tag_names_line_edit.setText(tags) self.editor_text_edit.setPlainText(self.case.content) # 'import' block in the case content init_import_set = set() for cmd in self.case.content.split("\n"): if cmd.strip().find("import") == 0: init_import_set.add(cmd.strip()) # send the init import block to editor's text edit, for init the highlighter and completer self.import_list_signal.emit(init_import_set) def closeEvent(self, event): """ close window event :param event: :return: """ case_name = self.case_name_line_edit.text().strip() # Case Name content = self.editor_text_edit.toPlainText().strip() # Case Content tag_list = self.get_tag_list() # check case data widget isVisible if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible() and ( not self.case_data_widget.has_modify): self.case_data_widget.close() if not self.case_id: # new case if (not case_name) and (not content) and (not tag_list): self.close() return elif self.case_id: # update case if not self.check_modify(): self.close() return self.handle_message_box_apply(event) def handle_message_box_apply(self, event): """ message box :param event: :return: """ reply = self.message_box.question(self, "Save Changes?", "The case has been modified, save changes?", QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard) if reply == QMessageBox.Save: # update case info self.save_case(event) # check case data widget isVisible if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible(): self.case_data_widget.close() elif reply == QMessageBox.Discard: # check case data widget isVisible if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible(): self.case_data_widget.close() self.close() return else: self.close_cancel_signal.emit() event.ignore() def check_modify(self): """ check the changes of the case :return: """ is_case_modified = False case_db = self.dBCommandLineHelper.query_case_by_id(self.case_id) is_name_modified = case_db.name.strip() != self.case_name_line_edit.text().strip() is_content_modified = case_db.content.strip() != self.editor_text_edit.toPlainText().strip() # tag names in the line edit tag_list = self.get_tag_list() # tag names in db db_tag_list = case_db.tags is_tags_names_modify = set(db_tag_list).difference(set(tag_list)) != set(tag_list).difference(set(db_tag_list)) # check the case data if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible(): self.is_case_data_modify = self.case_data_widget.has_modify if is_name_modified or is_content_modified or is_tags_names_modify or self.is_case_data_modify: logger.debug('case changed. case name: {}, tags: {}, content: {}, case data: {}' .format(is_name_modified, is_tags_names_modify, is_content_modified, self.is_case_data_modify)) is_case_modified = True return is_case_modified def get_tag_list(self): """ get tag list from tag_names_line_edit :return: """ # get tag names tag_name_list = self.tag_names_line_edit.text().strip().split(";") tag_set = set() for tag_name in tag_name_list: if not tag_name.strip(): continue tag = self.dBCommandLineHelper.query_tag_by_name(tag_name.strip()) tag_set.add(tag) return list(tag_set) def run_btn_event(self): """ click run button, show add_device_widget :return: """ self.add_device_widget = AddDeviceWidget() # add device self.add_device_widget.setWindowModality(Qt.ApplicationModal) self.device_and_data_signal.connect(self.add_device_widget.add_radio_to_widget, Qt.QueuedConnection) self.add_device_widget.run_editor_signal.connect(self.run_case, Qt.QueuedConnection) devices = [] if self.is_running: self.stop_case() try: devices = self.tester.devices() except Exception as e: self.add_info_console("<font color='red'>" + str(e) + "</font>") if not devices: # There is no device connected self.message_box.warning(self, "Message", "Please connect the device to your computer.", QMessageBox.Ok) return # get case data count if self.case_id is not None: self.case_data_count = self.case_data_manage.get_case_data_count(self.case_id) self.device_and_data_signal.emit(devices, self.case_data_count) self.add_device_widget.show() def run_case(self, devices, data_line_number): # change icon stop_icon = QIcon() stop_icon.addPixmap(QPixmap(self.config.images + '/stop.png'), QIcon.Normal, QIcon.Off) self.run_btn.setIcon(stop_icon) self.run_btn.setText("Stop") self.is_running = True if not devices: return self.tester.select_devices(devices) self.data_line = data_line_number self.run() # run def stop_case(self): # set icon run_icon = QIcon() run_icon.addPixmap(QPixmap(self.config.images + '/run.png'), QIcon.Normal, QIcon.Off) self.run_btn.setIcon(run_icon) self.run_btn.setText("Run") self.is_running = False try: self.tester.stop() self.tester.stop_server() except Exception as e: self.add_info_console("<font color='red'>" + str(e) + "</font>") def run(self): """ run case content :return: """ case_content = self.editor_text_edit.toPlainText().strip() case_data = None try: if (self.case_id is not None) and (self.case_data_count > 0): # case data exist case_data = self.case_data_manage.get_run_format_data(self.case_id) # get all case data self.debug_runner.reset() self.debug_runner._data = case_data # set case data self.debug_runner.parse(case_content) logger.debug("Debug beginning") self.debug_runner.execute(case_content, self.data_line) except Exception as e: logger.exception(str(e)) self.add_info_console("<font color='red'>" + str(e) + "</font>") self.stop_case() def save_case(self, event=None): """ save case :return: """ case_name = self.case_name_line_edit.text().strip() # Case Name content = self.editor_text_edit.toPlainText() # Case Content if self.check_null(): if event: event.ignore() return tags = self.get_tag_list() if self.check_tag_name(): # check unrecognized tag names return if self.case_id: self.case.name = case_name self.case.content = content self.case.tags = tags try: # update case and case data if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible(): self.case.last_modify_time = datetime.datetime.now() # update time self.case_manager.update_case(self.case_id, self.case_data_widget.case_data_list, self.case_data_widget.delete_data_ids) del self.case_data_widget.delete_data_ids[:] self.case_data_widget.has_modify = False else: self.case.last_modify_time = datetime.datetime.now() # update time self.dBCommandLineHelper.update_case() except Exception as e: logger.exception(str(e)) self.message_box.information(self, "Update Case Error", "Update case Fail.\nError Info:\n" + str(e), QMessageBox.Ok) else: try: # insert case and save case data if hasattr(self, 'case_data_widget') and self.case_data_widget.isVisible(): case = self.case_manager.insert_case(case_name, content, tags, self.case_data_widget.case_data_list, self.case_data_widget.delete_data_ids) del self.case_data_widget.delete_data_ids[:] self.case_data_widget.has_modify = False else: case = self.dBCommandLineHelper.insert_case_with_tags(case_name, content, tags) self.id_line_edit.setText(str(case.id)) self.case_id = self.id_line_edit.text().strip() self.set_case_edit_data() except Exception as e: logger.exception(str(e)) self.message_box.information(self, "Add Case Error", "Add case Fail.\nError Info:\n" + str(e), QMessageBox.Ok) self.refresh_signal.emit() # refresh the main table def check_null(self): """ check the required options :return: """ is_none = False type_info = '' case_name = self.case_name_line_edit.text().strip() content = self.editor_text_edit.toPlainText().strip() if not case_name: is_none = True type_info += "Case Name" if not content: is_none = True if not type_info: type_info += "Content" else: type_info += ", Content" if is_none: self.message_box.warning(self, "Message", type_info + " is required.", QMessageBox.Ok) return is_none def editor_adapter(self): """ get keywords for the completer and the highlighter :return: """ if self.case_id: self.parse_import_as() func_dict = self.debug_runner.core.kw_func # get default functions cmp = Completer(self.debug_runner) self.editor_text_edit.set_completer(cmp) # highlighter kw_list = [] for func_name, func in func_dict.items(): kw_list.append(func_name) self.high_lighter = MyHighlighter(self.editor_text_edit, kw_list) self.editor_text_edit.set_highlighter(self.high_lighter) def parse_import_as(self): """ parse all the 'import' and 'as' block in the case content :return: """ self.debug_runner.core.kw_func.clear() self.debug_runner.core.kw_func = {**self.debug_runner.core.default_func} content_list = self.dBCommandLineHelper.query_case_by_id(self.case_id).content.split("\n") if not content_list: return for line in content_list: if line.strip().find("import") == 0: # parse 'import' try: self.debug_runner.core.parse_line(line) except Exception as e: self.add_info_console("<font color='red'>" + str(e) + "</font>") elif " as " in line.strip(): # parse 'as' try: self.debug_runner.core.parse_line(line) except Exception as e: self.add_info_console("<font color='red'>" + str(e) + "</font>") def set_tag_name_completer(self): """ set completer to tag_names_line_edit :return: """ # change button icon add_icon = QIcon() add_icon.addPixmap(QPixmap(self.config.images + '/add.png'), QIcon.Normal, QIcon.Off) self.add_tag_button.setIcon(add_icon) self.add_tag_button.setToolTip("add tag") self.tag_names_line_edit.setPlaceholderText("Tag Names") self.tag_layout.insertWidget(0, self.tag_names_line_edit) self.tag_list = self.dBCommandLineHelper.query_tag_all() # get all tags tag_name_list = [] for tag in self.tag_list: tag_name_list.append(tag.name) cmp = TagCompleter(tag_name_list) self.tag_names_line_edit.setCompleter(cmp) def check_tag_name(self): """ check tag name,return unrecognized tag names :return: """ tag_name_list = self.tag_names_line_edit.text().strip().split(";") unrecognized_tag_names = "" has_unrecognized = False for tag_name in tag_name_list: if not tag_name.strip(): continue tag = self.dBCommandLineHelper.query_tag_by_name(tag_name.strip()) if not tag: unrecognized_tag_names += "\"" + tag_name + "\"" + "、" if not unrecognized_tag_names: return has_unrecognized has_unrecognized = True unrecognized_tag_names = unrecognized_tag_names[:-1] self.message_box.about(self, "Warning", "Tag name: " + unrecognized_tag_names + " unrecognized, please add it first.") return has_unrecognized
def initUI(self): self.statusBar().showMessage('Ready') self.image_window_view = HyperLprImageView() table_widget_header_labels = [ "文件名", "分割识别", "置信度", "颜色", "E2E识别", "E2E置信度"] self.hyperlpr_tableview = QTableWidget( 0, len(table_widget_header_labels)) self.hyperlpr_tableview.setHorizontalHeaderLabels( table_widget_header_labels) self.hyperlpr_tableview.setSelectionBehavior( QAbstractItemView.SelectItems) self.hyperlpr_tableview.setSelectionMode( QAbstractItemView.SingleSelection) self.hyperlpr_tableview.setEditTriggers( QAbstractItemView.NoEditTriggers) self.hyperlpr_tableview.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.hyperlpr_tableview.setEditTriggers( QAbstractItemView.NoEditTriggers) self.hyperlpr_tableview.cellClicked.connect( self.recognize_one_license_plate) self.location_label = QLabel("车牌目录", self) self.location_text = QLineEdit(self) self.location_text.setEnabled(False) self.location_text.setFixedWidth(300) self.location_button = QPushButton("...") self.location_button.clicked.connect(self.select_new_dir) self.location_layout = QHBoxLayout() self.location_layout.addWidget(self.location_label) self.location_layout.addWidget(self.location_text) self.location_layout.addWidget(self.location_button) self.location_layout.addStretch() self.check_box = QCheckBox("与文件名比较车牌") self.check_box.setChecked(True) self.update_file_path_button = QPushButton('批量识别') self.update_file_path_button.clicked.connect( self.batch_recognize_all_images) self.update_file_path_layout = QHBoxLayout() self.update_file_path_layout.addWidget(self.check_box) self.update_file_path_layout.addWidget(self.update_file_path_button) self.update_file_path_layout.addStretch() self.bottom_layout = QVBoxLayout() self.bottom_layout.addLayout(self.location_layout) self.bottom_layout.addLayout(self.update_file_path_layout) bottom_widget = QWidget() bottom_widget.setLayout(self.bottom_layout) license_plate_iamge_label = QLabel("车牌图") self.license_plate_widget = QLabel("") block_image_label = QLabel("分割图") self.block_plate_widget = QLabel("") filename_label = QLabel("文件名:") self.filename_edit = QLineEdit() segmentation_recognition_label = QLabel("分割识别:") self.segmentation_recognition_edit = QLineEdit() self.segmentation_recognition_edit.setFont(QFont("黑体", 24, QFont.Bold)) self.segmentation_recognition_edit.setStyleSheet("color:red") confidence_label = QLabel("置信度") self.confidence_edit = QLineEdit() self.confidence_edit.setFont(QFont("黑体", 24, QFont.Bold)) self.confidence_edit.setStyleSheet("color:red") plate_color_label = QLabel("车牌颜色") self.plate_color_edit = QLineEdit() self.plate_color_edit.setFont(QFont("黑体", 24, QFont.Bold)) self.plate_color_edit.setStyleSheet("color:red") e2e_recognization_label = QLabel("e2e识别:") self.e2e_recognization_edit = QLineEdit() self.e2e_recognization_edit.setFont(QFont("黑体", 24, QFont.Bold)) self.e2e_recognization_edit.setStyleSheet("color:red") e2e_confidence_label = QLabel("e2e置信度") self.e2e_confidence_edit = QLineEdit() self.e2e_confidence_edit.setFont(QFont("黑体", 24, QFont.Bold)) self.e2e_confidence_edit.setStyleSheet("color:red") info_gridlayout = QGridLayout() info_gridlayout.addWidget(filename_label, 0, 0) info_gridlayout.addWidget(self.filename_edit, 0, 1) info_gridlayout.addWidget(license_plate_iamge_label, 1, 0) info_gridlayout.addWidget(self.license_plate_widget, 1, 1) info_gridlayout.addWidget(block_image_label, 2, 0) info_gridlayout.addWidget(self.block_plate_widget, 2, 1) info_gridlayout.addWidget(segmentation_recognition_label, 3, 0) info_gridlayout.addWidget(self.segmentation_recognition_edit, 3, 1) info_gridlayout.addWidget(confidence_label, 4, 0) info_gridlayout.addWidget(self.confidence_edit, 4, 1) info_gridlayout.addWidget(plate_color_label, 5, 0) info_gridlayout.addWidget(self.plate_color_edit, 5, 1) info_gridlayout.addWidget(e2e_recognization_label, 6, 0) info_gridlayout.addWidget(self.e2e_recognization_edit, 6, 1) info_gridlayout.addWidget(e2e_confidence_label, 7, 0) info_gridlayout.addWidget(self. e2e_confidence_edit, 7, 1) info_widget = QWidget() info_widget.setLayout(info_gridlayout) right_splitter = QSplitter(Qt.Vertical) right_splitter.addWidget(bottom_widget) right_splitter.addWidget(self.hyperlpr_tableview) right_splitter.addWidget(info_widget) right_splitter.setStretchFactor(1, 3) right_splitter.setStretchFactor(2, 2) main_splitter = QSplitter(Qt.Horizontal) main_splitter.addWidget(self.image_window_view) main_splitter.addWidget(right_splitter) main_splitter.setStretchFactor(0, 1) self.image_filename_list = [] self.hyperlpr_dir_path = "" self.segmentation_recognition_correct_number = 0 self.color_correct_number = 0 self.e2e_recognization_correct_number = 0 self.batch_recognization_thread = LicenseRecognizationThread() self.batch_recognization_thread.recognization_done_signal.connect( self.recognization_done_slot) self.batch_recognization_thread.start() self.start_init_signal.connect(self.read_path_and_show_one_image) self.setCentralWidget(main_splitter) self.setWindowTitle("HyperLPR车牌识别软件v1.0") self.start_init_signal.emit()
def __init__(self, persepolis_setting): super().__init__() # MainWindow self.persepolis_setting = persepolis_setting # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) icons = ':/' + \ str(self.persepolis_setting.value('settings/icons')) + '/' self.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", "Persepolis Download Manager")) self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg'))) self.centralwidget = QWidget(self) self.verticalLayout = QVBoxLayout(self.centralwidget) # enable drag and drop self.setAcceptDrops(True) # frame self.frame = QFrame(self.centralwidget) # download_table_horizontalLayout download_table_horizontalLayout = QHBoxLayout() tabels_splitter = QSplitter(Qt.Horizontal) # category_tree self.category_tree_qwidget = QWidget(self) category_tree_verticalLayout = QVBoxLayout() self.category_tree = CategoryTreeView(self) category_tree_verticalLayout.addWidget(self.category_tree) self.category_tree_model = QStandardItemModel() self.category_tree.setModel(self.category_tree_model) category_table_header = [QCoreApplication.translate("mainwindow_ui_tr", 'Category')] self.category_tree_model.setHorizontalHeaderLabels( category_table_header) self.category_tree.header().setStretchLastSection(True) self.category_tree.header().setDefaultAlignment(Qt.AlignCenter) # queue_panel self.queue_panel_widget = QWidget(self) queue_panel_verticalLayout_main = QVBoxLayout(self.queue_panel_widget) # queue_panel_show_button self.queue_panel_show_button = QPushButton(self) queue_panel_verticalLayout_main.addWidget(self.queue_panel_show_button) # queue_panel_widget_frame self.queue_panel_widget_frame = QFrame(self) self.queue_panel_widget_frame.setFrameShape(QFrame.StyledPanel) self.queue_panel_widget_frame.setFrameShadow(QFrame.Raised) queue_panel_verticalLayout_main.addWidget( self.queue_panel_widget_frame) queue_panel_verticalLayout = QVBoxLayout(self.queue_panel_widget_frame) queue_panel_verticalLayout_main.setContentsMargins(50, -1, 50, -1) # start_end_frame self.start_end_frame = QFrame(self) # start time start_verticalLayout = QVBoxLayout(self.start_end_frame) self.start_checkBox = QCheckBox(self) start_verticalLayout.addWidget(self.start_checkBox) self.start_frame = QFrame(self) self.start_frame.setFrameShape(QFrame.StyledPanel) self.start_frame.setFrameShadow(QFrame.Raised) start_frame_verticalLayout = QVBoxLayout(self.start_frame) self.start_time_qDataTimeEdit = QDateTimeEdit(self.start_frame) self.start_time_qDataTimeEdit.setDisplayFormat('H:mm') start_frame_verticalLayout.addWidget(self.start_time_qDataTimeEdit) start_verticalLayout.addWidget(self.start_frame) # end time self.end_checkBox = QCheckBox(self) start_verticalLayout.addWidget(self.end_checkBox) self.end_frame = QFrame(self) self.end_frame.setFrameShape(QFrame.StyledPanel) self.end_frame.setFrameShadow(QFrame.Raised) end_frame_verticalLayout = QVBoxLayout(self.end_frame) self.end_time_qDateTimeEdit = QDateTimeEdit(self.end_frame) self.end_time_qDateTimeEdit.setDisplayFormat('H:mm') end_frame_verticalLayout.addWidget(self.end_time_qDateTimeEdit) start_verticalLayout.addWidget(self.end_frame) self.reverse_checkBox = QCheckBox(self) start_verticalLayout.addWidget(self.reverse_checkBox) queue_panel_verticalLayout.addWidget(self.start_end_frame) # limit_after_frame self.limit_after_frame = QFrame(self) # limit_checkBox limit_verticalLayout = QVBoxLayout(self.limit_after_frame) self.limit_checkBox = QCheckBox(self) limit_verticalLayout.addWidget(self.limit_checkBox) # limit_frame self.limit_frame = QFrame(self) self.limit_frame.setFrameShape(QFrame.StyledPanel) self.limit_frame.setFrameShadow(QFrame.Raised) limit_verticalLayout.addWidget(self.limit_frame) limit_frame_verticalLayout = QVBoxLayout(self.limit_frame) # limit_spinBox limit_frame_horizontalLayout = QHBoxLayout() self.limit_spinBox = QDoubleSpinBox(self) self.limit_spinBox.setMinimum(1) self.limit_spinBox.setMaximum(1023) limit_frame_horizontalLayout.addWidget(self.limit_spinBox) # limit_comboBox self.limit_comboBox = QComboBox(self) self.limit_comboBox.addItem("") self.limit_comboBox.addItem("") limit_frame_horizontalLayout.addWidget(self.limit_comboBox) limit_frame_verticalLayout.addLayout(limit_frame_horizontalLayout) # limit_pushButton self.limit_pushButton = QPushButton(self) limit_frame_verticalLayout.addWidget(self.limit_pushButton) # after_checkBox self.after_checkBox = QtWidgets.QCheckBox(self) limit_verticalLayout.addWidget(self.after_checkBox) # after_frame self.after_frame = QtWidgets.QFrame(self) self.after_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.after_frame.setFrameShadow(QtWidgets.QFrame.Raised) limit_verticalLayout.addWidget(self.after_frame) after_frame_verticalLayout = QVBoxLayout(self.after_frame) # after_comboBox self.after_comboBox = QComboBox(self) self.after_comboBox.addItem("") after_frame_verticalLayout.addWidget(self.after_comboBox) # after_pushButton self.after_pushButton = QPushButton(self) after_frame_verticalLayout.addWidget(self.after_pushButton) queue_panel_verticalLayout.addWidget(self.limit_after_frame) category_tree_verticalLayout.addWidget(self.queue_panel_widget) # keep_awake_checkBox self.keep_awake_checkBox = QCheckBox(self) queue_panel_verticalLayout.addWidget(self.keep_awake_checkBox) self.category_tree_qwidget.setLayout(category_tree_verticalLayout) tabels_splitter.addWidget(self.category_tree_qwidget) # download table widget self.download_table_content_widget = QWidget(self) download_table_content_widget_verticalLayout = QVBoxLayout( self.download_table_content_widget) self.download_table = DownloadTableWidget(self) download_table_content_widget_verticalLayout.addWidget( self.download_table) tabels_splitter.addWidget(self.download_table_content_widget) self.download_table.setColumnCount(13) self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.download_table.verticalHeader().hide() # hide gid and download dictioanry section self.download_table.setColumnHidden(8, True) self.download_table.setColumnHidden(9, True) download_table_header = [QCoreApplication.translate("mainwindow_ui_tr", 'File Name'), QCoreApplication.translate("mainwindow_ui_tr",'Status'), QCoreApplication.translate("mainwindow_ui_tr", 'Size'), QCoreApplication.translate("mainwindow_ui_tr", 'Downloaded'), QCoreApplication.translate("mainwindow_ui_tr", 'Percentage'), QCoreApplication.translate("mainwindow_ui_tr", 'Connections'), QCoreApplication.translate("mainwindow_ui_tr", 'Transfer rate'), QCoreApplication.translate("mainwindow_ui_tr",'Estimated time left'), 'Gid', QCoreApplication.translate("mainwindow_ui_tr",'Link'), QCoreApplication.translate("mainwindow_ui_tr", 'First try date'), QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'), QCoreApplication.translate("mainwindow_ui_tr",'Category')] self.download_table.setHorizontalHeaderLabels(download_table_header) # fixing the size of download_table when window is Maximized! self.download_table.horizontalHeader().setSectionResizeMode(0) self.download_table.horizontalHeader().setStretchLastSection(True) tabels_splitter.setStretchFactor(0, 3) # category_tree width tabels_splitter.setStretchFactor(1, 10) # ratio of tables's width download_table_horizontalLayout.addWidget(tabels_splitter) self.frame.setLayout(download_table_horizontalLayout) self.verticalLayout.addWidget(self.frame) self.setCentralWidget(self.centralwidget) # menubar self.menubar = QMenuBar(self) self.menubar.setGeometry(QRect(0, 0, 600, 24)) self.setMenuBar(self.menubar) fileMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&File')) editMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Edit')) viewMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&View')) downloadMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Download')) queueMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Queue')) videoFinderMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", 'V&ideo Finder')) helpMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Help')) # viewMenu submenus sortMenu = viewMenu.addMenu(QCoreApplication.translate("mainwindow_ui_tr", 'Sort by')) # statusbar self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.statusbar.showMessage(QCoreApplication.translate("mainwindow_ui_tr", "Persepolis Download Manager")) # toolBar self.toolBar2 = QToolBar(self) self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar2) self.toolBar2.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", 'Menu')) self.toolBar2.setFloatable(False) self.toolBar2.setMovable(False) self.toolBar = QToolBar(self) self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) self.toolBar.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", 'Toolbar')) self.toolBar.setFloatable(False) self.toolBar.setMovable(False) #toolBar and menubar and actions self.videoFinderAddLinkAction = QAction(QIcon(icons + 'video_finder'), QCoreApplication.translate("mainwindow_ui_tr", 'Find Video Links'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Download video or audio from Youtube, Vimeo, etc...'), triggered=self.showVideoFinderAddLinkWindow) QShortcut(QKeySequence('Ctrl+I'), self, self.showVideoFinderAddLinkWindow) videoFinderMenu.addAction(self.videoFinderAddLinkAction) self.stopAllAction = QAction(QIcon(icons + 'stop_all'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop all active downloads'), self, statusTip='Stop all active downloads', triggered=self.stopAllDownloads) downloadMenu.addAction(self.stopAllAction) self.sort_file_name_Action = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'File name'), self, triggered=self.sortByName) sortMenu.addAction(self.sort_file_name_Action) self.sort_file_size_Action = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'File size'), self, triggered=self.sortBySize) sortMenu.addAction(self.sort_file_size_Action) self.sort_first_try_date_Action = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'First try date'), self, triggered=self.sortByFirstTry) sortMenu.addAction(self.sort_first_try_date_Action) self.sort_last_try_date_Action = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'), self, triggered=self.sortByLastTry) sortMenu.addAction(self.sort_last_try_date_Action) self.sort_download_status_Action = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'Download status'), self, triggered=self.sortByStatus) sortMenu.addAction(self.sort_download_status_Action) self.trayAction = QAction(QCoreApplication.translate("mainwindow_ui_tr", 'Show system tray icon'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Show/Hide system tray icon"), triggered=self.showTray) self.trayAction.setCheckable(True) viewMenu.addAction(self.trayAction) self.showMenuBarAction = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'), triggered=self.showMenuBar) self.showMenuBarAction.setCheckable(True) viewMenu.addAction(self.showMenuBarAction) self.showSidePanelAction = QAction( QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'), triggered=self.showSidePanel) self.showSidePanelAction.setCheckable(True) viewMenu.addAction(self.showSidePanelAction) self.minimizeAction = QAction(QIcon(icons + 'minimize'), QCoreApplication.translate("mainwindow_ui_tr", 'Minimize to system tray'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Minimize to system tray"), triggered=self.minMaxTray) QShortcut(QKeySequence('Ctrl+W'), self, self.minMaxTray) viewMenu.addAction(self.minimizeAction) self.addlinkAction = QAction(QIcon(icons + 'add'), QCoreApplication.translate("mainwindow_ui_tr", 'Add New Download Link'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Add New Download Link"), triggered=self.addLinkButtonPressed) QShortcut(QKeySequence('Ctrl+N'), self, self.addLinkButtonPressed) fileMenu.addAction(self.addlinkAction) self.addtextfileAction = QAction(QIcon(icons + 'file'), QCoreApplication.translate("mainwindow_ui_tr", 'Import links from text file'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Create a Text file and put links in it.line by line!'), triggered=self.importText) fileMenu.addAction(self.addtextfileAction) self.resumeAction = QAction(QIcon(icons + 'play'), QCoreApplication.translate("mainwindow_ui_tr", 'Resume Download'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Resume Download"), triggered=self.resumeButtonPressed) QShortcut(QKeySequence('Ctrl+R'), self, self.resumeButtonPressed) downloadMenu.addAction(self.resumeAction) self.pauseAction = QAction(QIcon(icons + 'pause'), QCoreApplication.translate("mainwindow_ui_tr", 'Pause Download'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Pause Download"), triggered=self.pauseButtonPressed) QShortcut(QKeySequence('Ctrl+C'), self, self.pauseButtonPressed) downloadMenu.addAction(self.pauseAction) self.stopAction = QAction(QIcon(icons + 'stop'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop Download'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Stop/Cancel Download"), triggered=self.stopButtonPressed) QShortcut(QKeySequence('Ctrl+S'), self, self.stopButtonPressed) downloadMenu.addAction(self.stopAction) self.propertiesAction = QAction(QIcon(icons + 'setting'), QCoreApplication.translate("mainwindow_ui_tr", 'Properties'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Properties"), triggered=self.propertiesButtonPressed) QShortcut(QKeySequence('Ctrl+P'), self, self.propertiesButtonPressed) downloadMenu.addAction(self.propertiesAction) self.progressAction = QAction(QIcon(icons + 'window'), QCoreApplication.translate("mainwindow_ui_tr", 'Progress'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Progress"), triggered=self.progressButtonPressed) QShortcut(QKeySequence('Ctrl+Z'), self, self.progressButtonPressed) downloadMenu.addAction(self.progressAction) self.openFileAction = QAction(QIcon( icons + 'file'), QCoreApplication.translate("mainwindow_ui_tr", 'Open file'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open file'), triggered=self.openFile) fileMenu.addAction(self.openFileAction) self.openDownloadFolderAction = QAction(QIcon( icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'Open download folder'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open download folder'), triggered=self.openDownloadFolder) fileMenu.addAction(self.openDownloadFolderAction) self.openDefaultDownloadFolderAction = QAction(QIcon( icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'Open default download folder'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open default download folder'), triggered=self.openDefaultDownloadFolder) fileMenu.addAction(self.openDefaultDownloadFolderAction) self.exitAction = QAction(QIcon(icons + 'exit'), QCoreApplication.translate("mainwindow_ui_tr", 'Exit'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Exit"), triggered=self.closeEvent) QShortcut(QKeySequence('Ctrl+Q'), self, self.closeEvent) fileMenu.addAction(self.exitAction) self.clearAction = QAction(QIcon(icons + 'multi_remove'), QCoreApplication.translate("mainwindow_ui_tr", 'Clear download list'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Clear all items in download list'), triggered=self.clearDownloadList) editMenu.addAction(self.clearAction) self.removeSelectedAction = QAction(QIcon(icons + 'remove'), QCoreApplication.translate("mainwindow_ui_tr", 'Remove selected downloads from list'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Remove selected downloads form list'), triggered=self.removeSelected) editMenu.addAction(self.removeSelectedAction) self.removeSelectedAction.setEnabled(False) self.deleteSelectedAction = QAction(QIcon(icons + 'trash'), QCoreApplication.translate("mainwindow_ui_tr", 'Delete selected download files'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Delete selected download files'), triggered=self.deleteSelected) editMenu.addAction(self.deleteSelectedAction) self.deleteSelectedAction.setEnabled(False) self.createQueueAction = QAction(QIcon(icons + 'add_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Create new queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Create new download queue'), triggered=self.createQueue) queueMenu.addAction(self.createQueueAction) self.removeQueueAction = QAction(QIcon(icons + 'remove_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Remove this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Remove this queue'), triggered=self.removeQueue) queueMenu.addAction(self.removeQueueAction) self.startQueueAction = QAction(QIcon( icons + 'start_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'), triggered=self.startQueue) queueMenu.addAction(self.startQueueAction) self.stopQueueAction = QAction(QIcon( icons + 'stop_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'), triggered=self.stopQueue) queueMenu.addAction(self.stopQueueAction) self.moveUpSelectedAction = QAction(QIcon(icons + 'multi_up'), QCoreApplication.translate("mainwindow_ui_tr", 'Move up selected items'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Move currently selected items up by one row'), triggered=self.moveUpSelected) queueMenu.addAction(self.moveUpSelectedAction) self.moveDownSelectedAction = QAction(QIcon(icons + 'multi_down'), QCoreApplication.translate("mainwindow_ui_tr", 'Move down selected items'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Move currently selected items down by one row'), triggered=self.moveDownSelected) queueMenu.addAction(self.moveDownSelectedAction) self.preferencesAction = QAction(QIcon(icons + 'preferences'), QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'), triggered=self.openPreferences, menuRole=5) editMenu.addAction(self.preferencesAction) self.aboutAction = QAction(QIcon( icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'About'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'About'), triggered=self.openAbout, menuRole=4) helpMenu.addAction(self.aboutAction) self.issueAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'), triggered=self.reportIssue) helpMenu.addAction(self.issueAction) self.updateAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Check for newer version'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Check for newer release'), triggered=self.newUpdate) helpMenu.addAction(self.updateAction) self.logAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Show log file'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'), triggered=self.showLog) helpMenu.addAction(self.logAction) self.helpAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Help'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'), triggered=self.persepolisHelp) helpMenu.addAction(self.helpAction) self.qmenu = MenuWidget(self) self.toolBar2.addWidget(self.qmenu) # labels self.queue_panel_show_button.setText(QCoreApplication.translate("mainwindow_ui_tr", "Hide options")) self.start_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Start Time")) self.end_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "End Time")) self.reverse_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Download bottom of\n the list first")) self.limit_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Limit Speed")) self.limit_comboBox.setItemText(0, "KiB/s") self.limit_comboBox.setItemText(1, "MiB/s") self.limit_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "Apply")) self.after_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "After download")) self.after_comboBox.setItemText(0, QCoreApplication.translate("mainwindow_ui_tr", "Shut Down")) self.keep_awake_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Keep system awake!")) self.keep_awake_checkBox.setToolTip( QCoreApplication.translate("mainwindow_ui_tr", "<html><head/><body><p>This option is preventing system from going to sleep.\ This is necessary if your power manager is suspending system automatically. </p></body></html>")) self.after_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "Apply"))
class WindowUI(): def widgetSource(self): """Create source widget. """ hbox = QHBoxLayout() sourceLabel = QLabel(self.tr('Source')) self.sourceCBox = QComboBox(self) self.sourcePath = QLineEdit(self) self.sourcePath.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Maximum) # self.sourcePath.setMinimumWidth(400) self.sourcePathButton = QPushButton('...') self.sourcePathButton.setMaximumWidth(40) self.playButton = QPushButton('') self.nextFrameButton = QPushButton('') self.refreshButton = QPushButton('') css = "QPushButton { border: none; }" \ "QPushButton:pressed { border: 1px solid #555; background-color: #222; }" size = QtCore.QSize(23, 23) self.playButton.setIcon(QIcon('assets/pause.png')) self.playButton.setIconSize(size) self.playButton.setMinimumSize(size) self.playButton.setMaximumSize(size) self.playButton.setStyleSheet(css) self.refreshButton.setIcon(QIcon('assets/refresh.png')) self.refreshButton.setIconSize(size) self.refreshButton.setMinimumSize(size) self.refreshButton.setMaximumSize(size) self.refreshButton.setStyleSheet(css) self.nextFrameButton.setIcon(QIcon('assets/next.png')) self.nextFrameButton.setIconSize(size) self.nextFrameButton.setMinimumSize(size) self.nextFrameButton.setMaximumSize(size) self.nextFrameButton.setStyleSheet(css) self.sourceCBox.setCurrentIndex(0) controlsHbox = QHBoxLayout() controlsHbox.addWidget(self.playButton) controlsHbox.addWidget(self.nextFrameButton) controlsHbox.addWidget(self.refreshButton) controlsHbox.setAlignment(QtCore.Qt.AlignRight) hbox.addWidget(sourceLabel) hbox.addWidget(self.sourceCBox) hbox.addWidget(self.sourcePath) hbox.addWidget(self.sourcePathButton) hbox.addLayout(controlsHbox) hbox.setAlignment(QtCore.Qt.AlignLeft) return hbox def widgetFrame(self): """Create main display widget. """ vbox = QVBoxLayout() scroll = QScrollArea() scroll.setAlignment(QtCore.Qt.AlignCenter) self.mediaLabel = QLabel(self) scroll.setWidget(self.mediaLabel) vbox.addWidget(scroll) return vbox def widgetTree(self): """Create selected objects tree. """ tree = QTreeView() tree.header().setHidden(True) tree.setDragEnabled(True) tree.setSelectionMode(QAbstractItemView.ExtendedSelection) tree.setDefaultDropAction(QtCore.Qt.MoveAction) tree.setDragDropMode(QAbstractItemView.InternalMove) tree.setAcceptDrops(True) tree.setDropIndicatorShown(True) return tree def widgetObjectList(self): """Create objects list widget. """ self.objectsTree = self.widgetTree() self.availableObjectsList = QListWidget(self) self.availableObjectsList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.removeButton = QPushButton(self.tr('>>')) self.addButton = QPushButton(self.tr('<<')) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addWidget(self.addButton) vbox.addWidget(self.removeButton) vbox.addStretch(1) vboxSelected = QVBoxLayout() selectedLabel = QLabel(self.tr('Selected')) selectedLabel.setAlignment(QtCore.Qt.AlignCenter) vboxSelected.addWidget(selectedLabel) vboxSelected.addWidget(self.objectsTree) vboxAvailable = QVBoxLayout() availableLabel = QLabel(self.tr('Available')) availableLabel.setAlignment(QtCore.Qt.AlignCenter) vboxAvailable.addWidget(availableLabel) vboxAvailable.addWidget(self.availableObjectsList) hbox = QHBoxLayout() hbox.addLayout(vboxSelected) hbox.addLayout(vbox) hbox.addLayout(vboxAvailable) return hbox def widgetClassifierDisplay(self): """Create classifier display widget. """ self.colorPicker = QPushButton('') self.colorPicker.setMaximumSize(QtCore.QSize(16, 16)) self.shapeCBox = QComboBox(self) self.fillCBox = QComboBox(self) self.fillPath = QPushButton('...') self.fillPath.setMaximumWidth(40) self.showName = QCheckBox(self.tr('Show Name')) hbox = QHBoxLayout() hbox.addWidget(QLabel(self.tr('Shape'))) hbox.addWidget(self.shapeCBox) hbox.addWidget(self.fillCBox) hbox.addWidget(self.fillPath) hbox.addWidget(self.colorPicker) hbox.addStretch(1) vbox = QVBoxLayout() vbox.addWidget(self.showName) vbox.addLayout(hbox) return vbox def widgetClassifierParameters(self): """Create classifier parameters widget. """ hbox = QHBoxLayout() nameLabel = QLabel(self.tr('Name')) self.classifierName = QLineEdit(self) self.classifierType = QLabel('') hbox.addWidget(nameLabel) hbox.addWidget(self.classifierName) hbox.addWidget(self.classifierType) self.stabilize = QCheckBox(self.tr('Stabilize')) self.tracking = QCheckBox(self.tr('Tracking')) htracking = QHBoxLayout() htracking.addWidget(self.stabilize) htracking.addWidget(self.tracking) vlabel = QVBoxLayout() vparam = QVBoxLayout() self.scaleFactor = QDoubleSpinBox() self.scaleFactor.setMaximumWidth(65) self.scaleFactor.setLocale(QLocale(QLocale.English, QLocale.UnitedStates)) self.scaleFactor.setSingleStep(.1) self.scaleFactor.setDecimals(2) self.scaleFactor.setMinimum(1.1) self.minNeighbors = QSpinBox() self.minNeighbors.setMaximumWidth(65) self.minNeighbors.setMaximum(1500) self.minWidth = QSpinBox() self.minWidth.setMaximum(1500) self.minHeight = QSpinBox() self.minHeight.setMaximum(1500) self.autoNeighbors = QPushButton(self.tr("Auto")) self.autoNeighborsParam = QSpinBox() self.autoNeighborsParam.setMaximum(1500) self.autoNeighborsParam.setMaximumWidth(45) hminSize = QHBoxLayout() hminSize.addWidget(self.minWidth) hminSize.addWidget(QLabel(self.tr('x'))) hminSize.addWidget(self.minHeight) hminSize.addStretch(1) vlabel.addWidget(QLabel(self.tr('Scale factor'))) vlabel.addWidget(QLabel(self.tr('Min neighbors'))) vlabel.addWidget(QLabel(self.tr('Minimum Size'))) hNeighbors = QHBoxLayout() hNeighbors.addWidget(self.minNeighbors) hNeighbors.addWidget(self.autoNeighbors) hNeighbors.addWidget(self.autoNeighborsParam) hNeighbors.addStretch(1) vparam.addWidget(self.scaleFactor) vparam.addLayout(hNeighbors) vparam.addLayout(hminSize) hparameters = QHBoxLayout() hparameters.addLayout(vlabel) hparameters.addLayout(vparam) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addLayout(htracking) vbox.addLayout(hparameters) return vbox def widgetGlobalParam(self): """Create global parameters widget. """ hbox = QHBoxLayout() self.displayCBox = QComboBox(self) self.bgCBox = QComboBox(self) self.bgColorPicker = QPushButton('') self.bgColorPicker.setMaximumSize(QtCore.QSize(16, 16)) self.bgPathButton = QPushButton('...') self.bgPathButton.setMaximumWidth(45) hbox.addWidget(QLabel(self.tr('Display'))) hbox.addWidget(self.displayCBox) hbox.addStretch(1) hbox.addWidget(QLabel(self.tr('Background'))) hbox.addWidget(self.bgCBox) hbox.addWidget(self.bgColorPicker) hbox.addWidget(self.bgPathButton) self.equalizeHist = QCheckBox(self.tr('Equalize histogram')) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget(self.equalizeHist) return vbox def widgetParameters(self): """Create parameters widget. """ globalParamBox = QGroupBox(self.tr('Global parameters')) objects = self.widgetGlobalParam() globalParamBox.setLayout(objects) detectBox = QGroupBox(self.tr('Detect')) objects = self.widgetObjectList() detectBox.setLayout(objects) self.displayBox = QGroupBox(self.tr('Classifier Display')) display = self.widgetClassifierDisplay() self.displayBox.setLayout(display) self.parametersBox = QGroupBox(self.tr('Classifier Parameters')) parameters = self.widgetClassifierParameters() self.parametersBox.setLayout(parameters) vbox = QVBoxLayout() vbox.addWidget(globalParamBox) vbox.addWidget(detectBox) vbox.addWidget(self.displayBox) vbox.addWidget(self.parametersBox) return vbox def widgetDebug(self): """Create debug infos widget. """ self.debugText = QTextEdit(self) vbox = QVBoxLayout() hbox = QHBoxLayout() self.showDetails = QPushButton(self.tr('Details >>>')) self.showDetails.setCheckable(True) self.showDetails.setChecked(1) hbox.addWidget(self.showDetails) hbox.addStretch(1) vbox.addLayout(hbox) vbox.addWidget(self.debugText) vbox.addStretch(1) return vbox def setupUI(self): """Create User Interface. """ sourceWidget = self.widgetSource() frameWidget = self.widgetFrame() parametersWidget = self.widgetParameters() leftSide = QWidget() leftSide.setLayout(parametersWidget) rightSide = QWidget() rightSide.setLayout(frameWidget) self.hsplitter = QSplitter(QtCore.Qt.Horizontal) self.hsplitter.addWidget(leftSide) self.hsplitter.addWidget(rightSide) self.hsplitter.setStretchFactor(0, 1) self.hsplitter.setStretchFactor(1, 10) downSide = QWidget() downSide.setLayout(self.widgetDebug()) self.vsplitter = QSplitter(QtCore.Qt.Vertical) self.vsplitter.addWidget(self.hsplitter) self.vsplitter.addWidget(downSide) self.vsplitter.setStretchFactor(0, 10) self.vsplitter.setStretchFactor(1, 1) mainLayout = QVBoxLayout() mainLayout.addLayout(sourceWidget) mainLayout.addWidget(self.vsplitter) self.setLayout(mainLayout) self.setGeometry(300, 300, 800, 600) self.show()
class BlockEditor(QWidget, MooseWidget): """ The complete editing widget for a Block. The input file will only change when "Apply changes" has been clicked. Until then all changes only live in the widgets. The exceptions to this are the "Clone" and "Remove" buttons which just sends out signals to let others do work. Signals: needBlockList(list): When the type of a parameter references blocks (for example it is a VariableName), this is used to update the available options since they can change based on what the user does. blockRenamed(object, str): A block has been renamed. This is emitted so that the BlockTree can update the name of the block. blockChanged(object): Apply has been clicked for this block. cloneBlock(object): The user wants to clone the block we are currently editing. removeBlock(object): The user wants to remove the block we are currently editing. editingFinished(object): The user is done editing this block. Typically done by closing the window. """ needBlockList = pyqtSignal(list) # list of paths that we need children for blockRenamed = pyqtSignal(object, str) # block with changes, old path blockChanged = pyqtSignal(object) # block that has changed cloneBlock = pyqtSignal(object) # block to clone removeBlock = pyqtSignal(object) # block to remove editingFinished = pyqtSignal() def __init__(self, block, type_to_block_map, **kwds): """ Sets up an editor for a block. Input: block[BlockInfo]: Block to be edited. """ super(BlockEditor, self).__init__(**kwds) self.block = block self.comment_edit = CommentEditor() self.comment_edit.textChanged.connect(self._blockChanged) self.splitter = None self.clone_button = None self.clone_shortcut = None self.remove_button = None self.apply_button = None self.reset_button = None self.new_parameter_button = None self.param_editor = None self.setWindowTitle(block.path) if block.types: self.param_editor = ParamsByType(block, type_to_block_map) elif block.parameters: self.param_editor = ParamsByGroup(block, block.orderedParameters(), type_to_block_map) else: self.param_editor = ParamsTable(block, block.orderedParameters(), type_to_block_map) self.param_editor.needBlockList.connect(self.needBlockList) self.param_editor.changed.connect(self._blockChanged) self.param_editor.blockRenamed.connect(self.blockRenamed) self._createButtons() self.applyChanges() self._current_commands = [] self._command_index = 0 self.user_params = [] self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.param_editor) self.splitter.addWidget(self.comment_edit) self.splitter.setStretchFactor(0,2) self.splitter.setStretchFactor(1,1) self.top_layout = WidgetUtils.addLayout(vertical=True) self.top_layout.addWidget(self.splitter) self.top_layout.addLayout(self.button_layout) self.setLayout(self.top_layout) self.setup() def _blockChanged(self, enabled=True): """ Sets the Apply and Reset buttons based on enabled. Input: enabled[bool]: Whether to set the buttons to enabled """ self.apply_button.setEnabled(enabled) self.reset_button.setEnabled(enabled) self.setWindowTitle(self.block.path) def setWatchedBlockList(self, path, children): self.param_editor.setWatchedBlockList(path, children) def _createButtons(self): """ Create allowable buttons for this Block. This will depend on whether this is a user added block. """ self.button_layout = WidgetUtils.addLayout() if self.block.user_added: self.clone_button = WidgetUtils.addButton(self.button_layout, self, "Clone Block", self._cloneBlock) self.clone_shortcut = WidgetUtils.addShortcut(self, "Ctrl+N", self._cloneBlock, shortcut_with_children=True) self.clone_button.setToolTip("Clone this block with the same parameters") self.remove_button = WidgetUtils.addButton(self.button_layout, self, "Remove Block", self._removeBlock) self.remove_button.setToolTip("Remove this block") self.apply_button = WidgetUtils.addButton(self.button_layout, self, "Apply", self.applyChanges) self.apply_button.setEnabled(False) self.apply_button.setToolTip("Apply changes made") self.reset_button = WidgetUtils.addButton(self.button_layout, self, "Reset", self.resetChanges) self.reset_button.setEnabled(False) self.reset_button.setToolTip("Reset changes to when this window was opened") self.new_parameter_button = WidgetUtils.addButton(self.button_layout, self, "Add parameter", self.addUserParamPressed) self.new_parameter_button.setToolTip("Add a non standard parameter") self.close_button = WidgetUtils.addButton(self.button_layout, self, "Close", self._applyAndClose) self.close_button.setToolTip("Apply any changes and close the window") def _findFreeParamName(self, max_params=1000): """ Find a free parameter name that can be safely added. Input: max_params[int]: Maximum number of tries before giving up. """ base = "NewParam" for i in range(max_params): param = '%s%s' % (base, i) if self.param_editor.paramValue(param) == None: return param def addUserParamPressed(self): """ The user wants to add a new user parameter to this block. """ new_name = self._findFreeParamName() self._blockChanged() self.param_editor.addUserParam(new_name) def _cloneBlock(self): """ The user wants to clone this block """ self.cloneBlock.emit(self.block) def _removeBlock(self): """ The user wants to remove this block. We ask to make sure they want to do this. """ button = QMessageBox.question(self, "Confirm remove", "Are you sure you want to delete %s" % self.block.path, QMessageBox.Yes, QMessageBox.No) if button == QMessageBox.Yes: self.removeBlock.emit(self.block) self.hide() self.editingFinished.emit() def applyChanges(self): """ Apply any changes the user has made. """ self.block.comments = self.comment_edit.getComments() self.param_editor.save() self._blockChanged(enabled=False) self.blockChanged.emit(self.block) def _applyAndClose(self): """ Apply any changes the user has made then close the window """ if self.apply_button.isEnabled(): self.applyChanges() self.close() def resetChanges(self): """ Reset any changes the user has made. """ self.comment_edit.setComments(self.block.comments) self.param_editor.reset() self._blockChanged(enabled=False) def updateWatchers(self): """ This should be called after creating a BlockEditor. This isn't called in the constructor because the caller will typically need to hook up the needBlockList signal first. """ self.param_editor.updateWatchers() def closeEvent(self, event): """ The user is done editing. """ self.editingFinished.emit()
class ScriptingWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.editor = PythonEditor(self) self.fileChooser = FileChooser(self) self.fileChooser.fileOpened.connect(self.openFile) self.outputEdit = OutputEdit(self) splitter = QSplitter(self) self.vSplitter = QSplitter(Qt.Vertical, splitter) self.vSplitter.addWidget(self.editor) self.vSplitter.addWidget(self.outputEdit) self.vSplitter.setStretchFactor(0, 1) self.vSplitter.setStretchFactor(1, 0) splitter.addWidget(self.fileChooser) splitter.addWidget(self.vSplitter) splitter.setStretchFactor(0, 0) splitter.setStretchFactor(1, 1) statusBar = ScriptingStatusBar(self) self.setCentralWidget(splitter) self.setStatusBar(statusBar) self.newFile() self.editor.modificationChanged.connect(self.setWindowModified) statusBar.setPosition(self.editor.textCursor()) self.editor.cursorPositionChanged.connect( lambda: statusBar.setPosition(self.sender().textCursor())) statusBar.setIndent(self.editor.indent()) self.editor.indentChanged.connect(statusBar.setIndent) statusBar.indentModified.connect(self.editor.setIndent) statusBar.positionClicked.connect(self.gotoLine) statusBar.clearButtonClicked.connect(self.outputEdit.clear) statusBar.runButtonClicked.connect(self.runScript) gotoLineShortcut = QShortcut(QKeySequence("Ctrl+G"), self) gotoLineShortcut.activated.connect(self.gotoLine) self.readSettings() splitter.splitterMoved.connect(self.writeSettings) self.vSplitter.splitterMoved.connect(self.writeSettings) def readSettings(self): geometry = settings.scriptingWindowGeometry() if geometry: self.restoreGeometry(geometry) sizes = settings.scriptingWindowHSplitterSizes() if sizes: splitter = self.centralWidget() splitter.setSizes(sizes) sizes = settings.scriptingWindowVSplitterSizes() if sizes: self.vSplitter.setSizes(sizes) def writeSettings(self): settings.setScriptingWindowGeometry(self.saveGeometry()) # splitters don't report a correct size until the window is visible if not self.isVisible(): return splitter = self.centralWidget() settings.setScriptingWindowHSplitterSizes(splitter.sizes()) settings.setScriptingWindowVSplitterSizes(self.vSplitter.sizes()) def setupMenu(self, menuBar): fileMenu = menuBar.fetchMenu(Entries.File) fileMenu.fetchAction(Entries.File_New, self.newFile) fileMenu.fetchAction(Entries.File_Open, self.openFile) fileMenu.fetchAction(Entries.File_Save, self.saveFile) fileMenu.fetchAction(Entries.File_Save_As, self.saveFileAs) fileMenu.addSeparator() fileMenu.fetchAction(Entries.File_Close, self.close) @property def currentPath(self): return self._currentPath @currentPath.setter def currentPath(self, currentPath): self._currentPath = currentPath if self._currentPath is None: title = self.tr("Untitled") else: title = os.path.basename(self._currentPath) self.setWindowTitle(title) def newFile(self): if not self._maybeSaveBeforeExit(): return self.editor.setPlainText(None) self.currentPath = None def openFile(self, path=None): if not self._maybeSaveBeforeExit(): return if path is None: path = self._ioDialog(QFileDialog.AcceptOpen) if path is None: return self.fileChooser.setCurrentFolder(os.path.dirname(path)) with tokenize.open(path) as inputFile: self.editor.setPlainText(inputFile.read()) self.currentPath = path def saveFile(self): if self.currentPath is None: self.saveFileAs() else: self.editor.write(self.currentPath) def saveFileAs(self): path = self._ioDialog(QFileDialog.AcceptSave) if path is not None: self.currentPath = path self.saveFile() # TODO: why not use simple dialogs? def _ioDialog(self, mode): state = settings.scriptingFileDialogState() if mode == QFileDialog.AcceptOpen: title = self.tr("Open File") else: title = self.tr("Save File") dialog = QFileDialog( self, title, None, self.tr("Python file (*.py)")) if state: dialog.restoreState(state) dialog.setAcceptMode(mode) dialog.setDirectory(self.fileChooser.currentFolder()) dialog.setFileMode(QFileDialog.ExistingFile) ok = dialog.exec_() settings.setScriptingWindowFileDialogState(state) if ok: return dialog.selectedFiles()[0] return None def gotoLine(self): newLine, newColumn, ret = GotoLineDialog.getLineColumnNumber(self) if ret and newLine: self.editor.scrollToLine(newLine, newColumn) def runScript(self): app = QApplication.instance() global_vars = app.globals() script = self.editor.toPlainText() streams = [] for channel in ("stdout", "stderr"): stream = OutputStream(channel, self) stream.forward = True stream.messagePassed.connect(self.outputEdit.write) streams.append(stream) try: code = compile(script, "<string>", "exec") exec(code, global_vars) except: traceback.print_exc() for stream in streams: stream.unregisterStream() stream.messagePassed.disconnect(self.outputEdit.write) # ---------- # Qt methods # ---------- def setWindowTitle(self, title): if platformSpecific.appNameInTitle(): title += " – TruFont" super().setWindowTitle("[*]{}".format(title)) def sizeHint(self): return QSize(650, 700) def moveEvent(self, event): self.writeSettings() resizeEvent = moveEvent def closeEvent(self, event): ok = self._maybeSaveBeforeExit() if ok: event.accept() else: event.ignore() def _maybeSaveBeforeExit(self): if self.isWindowModified(): currentFile = self.windowTitle()[3:] ret = CloseMessageBox.getCloseDocument(self, currentFile) if ret == QMessageBox.Save: self.saveFile() return True elif ret == QMessageBox.Discard: return True return False return True
class EntryView(BaseTransactionView): def _setup(self): self._setupUi() self.etable = EntryTable(self.model.etable, view=self.tableView) self.efbar = EntryFilterBar(model=self.model.filter_bar, view=self.filterBar) self.bgraph = Chart(self.model.bargraph, view=self.barGraphView) self.lgraph = Chart(self.model.balgraph, view=self.lineGraphView) self._setupColumns() # Can only be done after the model has been connected self.reconciliationButton.clicked.connect(self.model.toggle_reconciliation_mode) def _setupUi(self): self.resize(483, 423) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSpacing(0) self.filterBar = RadioBox(self) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filterBar.sizePolicy().hasHeightForWidth()) self.filterBar.setSizePolicy(sizePolicy) self.horizontalLayout.addWidget(self.filterBar) self.horizontalLayout.addItem(horizontalSpacer()) self.reconciliationButton = QPushButton(tr("Reconciliation")) self.reconciliationButton.setCheckable(True) self.horizontalLayout.addWidget(self.reconciliationButton) self.verticalLayout.addLayout(self.horizontalLayout) self.splitterView = QSplitter() self.splitterView.setOrientation(Qt.Vertical) self.splitterView.setChildrenCollapsible(False) self.tableView = TableView(self) self.tableView.setAcceptDrops(True) self.tableView.setEditTriggers(QAbstractItemView.DoubleClicked|QAbstractItemView.EditKeyPressed) self.tableView.setDragEnabled(True) self.tableView.setDragDropMode(QAbstractItemView.InternalMove) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setSortingEnabled(True) self.tableView.horizontalHeader().setHighlightSections(False) self.tableView.horizontalHeader().setMinimumSectionSize(18) self.tableView.verticalHeader().setVisible(False) self.tableView.verticalHeader().setDefaultSectionSize(18) self.splitterView.addWidget(self.tableView) self.graphView = QStackedWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.graphView.sizePolicy().hasHeightForWidth()) self.graphView.setSizePolicy(sizePolicy) self.graphView.setMinimumSize(0, 200) self.lineGraphView = LineGraphView() self.graphView.addWidget(self.lineGraphView) self.barGraphView = BarGraphView() self.graphView.addWidget(self.barGraphView) self.splitterView.addWidget(self.graphView) self.graphView.setCurrentIndex(1) self.splitterView.setStretchFactor(0, 1) self.splitterView.setStretchFactor(1, 0) self.verticalLayout.addWidget(self.splitterView) def _setupColumns(self): h = self.tableView.horizontalHeader() h.setSectionsMovable(True) # column drag & drop reorder # --- QWidget override def setFocus(self): self.etable.view.setFocus() # --- Public def fitViewsForPrint(self, viewPrinter): hidden = self.model.mainwindow.hidden_areas viewPrinter.fitTable(self.etable) if PaneArea.BottomGraph not in hidden: viewPrinter.fit(self.graphView.currentWidget(), 300, 150, expandH=True, expandV=True) def restoreSubviewsSize(self): graphHeight = self.model.graph_height_to_restore if graphHeight: splitterHeight = self.splitterView.height() sizes = [splitterHeight-graphHeight, graphHeight] self.splitterView.setSizes(sizes) # --- model --> view def refresh_reconciliation_button(self): if self.model.can_toggle_reconciliation_mode: self.reconciliationButton.setEnabled(True) self.reconciliationButton.setChecked(self.model.reconciliation_mode) else: self.reconciliationButton.setEnabled(False) self.reconciliationButton.setChecked(False) def show_bar_graph(self): self.graphView.setCurrentIndex(1) def show_line_graph(self): self.graphView.setCurrentIndex(0) def update_visibility(self): hidden = self.model.mainwindow.hidden_areas self.graphView.setHidden(PaneArea.BottomGraph in hidden)
class SubTabWidget(QWidget): _tabChanged = pyqtSignal(int, name = "tabChanged") def __init__(self, subtitleData, videoWidget, parent = None): super(SubTabWidget, self).__init__(parent) self._subtitleData = subtitleData self.__initTabWidget(videoWidget) def __initTabWidget(self, videoWidget): settings = SubSettings() mainLayout = QVBoxLayout(self) mainLayout.setContentsMargins(0, 0, 0, 0) mainLayout.setSpacing(0) #TabBar self.tabBar = QTabBar(self) # Splitter (bookmarks + pages) self.splitter = QSplitter(self) self.splitter.setObjectName("sidebar_splitter") self._toolbox = ToolBox(self._subtitleData, self) self._toolbox.setObjectName("sidebar") self._toolbox.setMinimumWidth(100) self._toolbox.addTool(Details(self._subtitleData, self)) self._toolbox.addTool(Synchronizer(videoWidget, self._subtitleData, self)) self._toolbox.addTool(History(self)) self.rightWidget = QWidget() rightLayout = QGridLayout() rightLayout.setContentsMargins(0, 0, 0, 0) self.rightWidget.setLayout(rightLayout) self._mainTab = FileList(_("Subtitles"), self._subtitleData, self) self.pages = QStackedWidget(self) rightLayout.addWidget(self.pages, 0, 0) self.tabBar.addTab(self._mainTab.name) self.pages.addWidget(self._mainTab) self.splitter.addWidget(self._toolbox) self.splitter.addWidget(self.rightWidget) self.__drawSplitterHandle(1) # Setting widgets mainLayout.addWidget(self.tabBar) mainLayout.addWidget(self.splitter) # Widgets settings self.tabBar.setMovable(True) self.tabBar.setTabsClosable(True) self.tabBar.setExpanding(False) # Don't resize left panel if it's not needed leftWidgetIndex = self.splitter.indexOf(self._toolbox) rightWidgetIndex = self.splitter.indexOf(self.rightWidget) self.splitter.setStretchFactor(leftWidgetIndex, 0) self.splitter.setStretchFactor(rightWidgetIndex, 1) self.splitter.setCollapsible(leftWidgetIndex, False) self.splitter.setSizes([250]) # Some signals self.tabBar.currentChanged.connect(self.showTab) self.tabBar.tabCloseRequested.connect(self.closeTab) self.tabBar.tabMoved.connect(self.moveTab) self._mainTab.requestOpen.connect(self.openTab) self._mainTab.requestRemove.connect(self.removeFile) self.tabChanged.connect(lambda i: self._toolbox.setContentFor(self.tab(i))) self.setLayout(mainLayout) def __addTab(self, filePath): """Returns existing tab index. Creates a new one if it isn't opened and returns its index otherwise.""" for i in range(self.tabBar.count()): widget = self.pages.widget(i) if not widget.isStatic and filePath == widget.filePath: return i tab = SubtitleEditor(filePath, self._subtitleData, self) newIndex = self.tabBar.addTab(self._createTabName(tab.name, tab.history.isClean())) tab.history.cleanChanged.connect( lambda clean: self._cleanStateForFileChanged(filePath, clean)) self.pages.addWidget(tab) return newIndex def __drawSplitterHandle(self, index): splitterHandle = self.splitter.handle(index) splitterLayout = QVBoxLayout(splitterHandle) splitterLayout.setSpacing(0) splitterLayout.setContentsMargins(0, 0, 0, 0) line = QFrame(splitterHandle) line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) splitterLayout.addWidget(line) splitterHandle.setLayout(splitterLayout) def _createTabName(self, name, cleanState): if cleanState is True: return name else: return "%s +" % name def _cleanStateForFileChanged(self, filePath, cleanState): page = self.tabByPath(filePath) if page is not None: for i in range(self.tabBar.count()): if self.tabBar.tabText(i)[:len(page.name)] == page.name: self.tabBar.setTabText(i, self._createTabName(page.name, cleanState)) return def saveWidgetState(self, settings): settings.setState(self.splitter, self.splitter.saveState()) settings.setHidden(self._toolbox, self._toolbox.isHidden()) def restoreWidgetState(self, settings): self.showPanel(not settings.getHidden(self._toolbox)) splitterState = settings.getState(self.splitter) if not splitterState.isEmpty(): self.splitter.restoreState(settings.getState(self.splitter)) @pyqtSlot(str, bool) def openTab(self, filePath, background=False): if self._subtitleData.fileExists(filePath): tabIndex = self.__addTab(filePath) if background is False: self.showTab(tabIndex) else: log.error(_("SubtitleEditor not created for %s!" % filePath)) @pyqtSlot(str) def removeFile(self, filePath): tab = self.tabByPath(filePath) command = RemoveFile(filePath) if tab is not None: index = self.pages.indexOf(tab) if self.closeTab(index): self._subtitleData.execute(command) else: self._subtitleData.execute(command) @pyqtSlot(int) def closeTab(self, index): tab = self.tab(index) if tab.canClose(): widgetToRemove = self.pages.widget(index) self.tabBar.removeTab(index) self.pages.removeWidget(widgetToRemove) widgetToRemove.deleteLater() return True return False def count(self): return self.tabBar.count() def currentIndex(self): return self.tabBar.currentIndex() def currentPage(self): return self.pages.currentWidget() @pyqtSlot(int, int) def moveTab(self, fromIndex, toIndex): fromWidget = self.pages.widget(fromIndex) toWidget = self.pages.widget(toIndex) if fromWidget.isStatic or toWidget.isStatic: self.tabBar.blockSignals(True) # signals would cause infinite recursion self.tabBar.moveTab(toIndex, fromIndex) self.tabBar.blockSignals(False) return else: self.pages.removeWidget(fromWidget) self.pages.removeWidget(toWidget) if fromIndex < toIndex: self.pages.insertWidget(fromIndex, toWidget) self.pages.insertWidget(toIndex, fromWidget) else: self.pages.insertWidget(toIndex, fromWidget) self.pages.insertWidget(fromIndex, toWidget) # Hack # Qt changes tabs during mouse drag and dropping. The next line is added # to prevent it. self.showTab(self.tabBar.currentIndex()) @pyqtSlot(int) def showTab(self, index): showWidget = self.pages.widget(index) if showWidget: self.pages.setCurrentWidget(showWidget) self.tabBar.blockSignals(True) self.tabBar.setCurrentIndex(index) self.tabBar.blockSignals(False) # Try to update current tab. showWidget.updateTab() self._tabChanged.emit(index) def showPanel(self, val): if val is True: self._toolbox.show() else: self._toolbox.hide() def togglePanel(self): if self._toolbox.isHidden(): self._toolbox.show() else: self._toolbox.hide() def tab(self, index): return self.pages.widget(index) def tabByPath(self, path): for i in range(self.pages.count()): page = self.tab(i) if not page.isStatic and page.filePath == path: return page return None @property def fileList(self): return self._mainTab
class HeapPluginForm(PluginForm): def __init__(self): super(HeapPluginForm, self).__init__() self.parent = None self.config_path = None self.config = None self.tracer = None self.heap = None self.cur_arena = None # default: main_arena self.ptr_size = get_arch_ptrsize() def OnCreate(self, form): self.parent = self.FormToPyQtWidget(form) self.setup_gui() self.init_heap() self.populate_gui() def setup_gui(self): self.chunk_widget = ChunkWidget(self) self.tracer_tab = TracerWidget(self) self.arena_widget = ArenaWidget(self) self.bins_widget = BinsWidget(self) self.tcache_widget = TcacheWidget(self) self.magic_widget = MagicWidget(self) self.config_widget = ConfigWidget(self) self.tabs = QTabWidget() self.tabs.addTab(self.tracer_tab, "Tracer") self.tabs.addTab(self.arena_widget, "Arena") self.tabs.addTab(self.bins_widget, "Bins") self.tabs.addTab(self.tcache_widget, "Tcache") self.tabs.addTab(self.magic_widget, "Magic") self.tabs.addTab(self.config_widget, "Config") self.btn_reload = QPushButton("Reload info") icon = QtGui.QIcon(os.path.normpath(ICONS_DIR + '/refresh.png')) self.btn_reload.setIcon(icon) self.btn_reload.setFixedWidth(120) self.btn_reload.setEnabled(False) self.btn_reload.clicked.connect(self.reload_gui_info) self.cb_arenas = QComboBox() self.cb_arenas.setFixedWidth(150) self.cb_arenas.currentIndexChanged[int].connect(self.cb_arenas_changed) hbox_arenas = QHBoxLayout() hbox_arenas.addWidget(QLabel('Switch arena: ')) hbox_arenas.addWidget(self.cb_arenas) hbox_arenas.setContentsMargins(0, 0, 0, 0) self.arenas_widget = QWidget() self.arenas_widget.setLayout(hbox_arenas) self.arenas_widget.setVisible(False) self.txt_warning = QLabel() self.txt_warning.setStyleSheet("font-weight: bold; color: red") self.txt_warning.setVisible(False) hbox_top = QHBoxLayout() hbox_top.addWidget(self.btn_reload) hbox_top.addWidget(self.arenas_widget) hbox_top.addWidget(self.txt_warning) hbox_top.setContentsMargins(0, 0, 0, 0) hbox_top.addStretch(1) vbox_left_panel = QVBoxLayout() vbox_left_panel.addLayout(hbox_top) vbox_left_panel.addWidget(self.tabs) vbox_left_panel.setContentsMargins(0, 0, 0, 0) left_panel = QWidget() left_panel.setLayout(vbox_left_panel) self.splitter = QSplitter(QtCore.Qt.Horizontal) self.splitter.addWidget(left_panel) self.splitter.addWidget(self.chunk_widget) self.splitter.setStretchFactor(0, 1) main_layout = QVBoxLayout() main_layout.addWidget(self.splitter) self.parent.setLayout(main_layout) def populate_gui(self): self.magic_widget.populate_libc_offsets() self.reload_gui_info() def reload_gui_info(self, from_arena_cb=False): if not self.heap: return if not self.heap.get_heap_base(): self.show_warning('Heap not initialized') return self.hide_warning() self.arenas_widget.setVisible(True) if not from_arena_cb: self.populate_arenas() self.arena_widget.populate_table() self.tcache_widget.populate_table() self.bins_widget.populate_tables() def init_heap(self): try: self.config_path = CONFIG_PATH self.config = HeapConfig(self.config_path) self.config_widget.load_config() except Exception as e: self.config = None self.show_warning('Please, update the config file') warning(str(e)) return if not self.config.offsets: arch_bits = self.ptr_size * 8 self.show_warning('Config: Libc offsets for %d bits not found.' % arch_bits) return try: current_libc_version = get_libc_version() if self.config.libc_version == current_libc_version or current_libc_version == None: self.heap = Heap(self.config) self.btn_reload.setEnabled(True) self.tabs.setTabEnabled(3, self.heap.tcache_enabled) else: self.show_warning('Config: glibc version mismatched: %s != %s' % \ (str(self.config.libc_version), str(current_libc_version))) except AttributeError: self.show_warning('Invalid config file content') def populate_arenas(self): old_arena = self.cur_arena self.cb_arenas.clear() for addr, arena in self.heap.arenas(): if addr == self.heap.main_arena_addr: self.cb_arenas.addItem("main_arena", None) else: self.cb_arenas.addItem("0x%x" % addr, addr) idx = self.cb_arenas.findData(old_arena) if idx != -1: self.cb_arenas.setCurrentIndex(idx) def show_warning(self, txt): self.txt_warning.setText(txt) self.txt_warning.setVisible(True) def hide_warning(self): self.txt_warning.setVisible(False) def cb_arenas_changed(self, idx): self.cur_arena = self.cb_arenas.itemData(idx) self.reload_gui_info(True) def show_chunk_info(self, address): self.chunk_widget.show_chunk(address) def Show(self): return PluginForm.Show(self, PLUGNAME, options = ( PluginForm.FORM_TAB | PluginForm.FORM_CLOSE_LATER )) def OnClose(self, form): if self.tracer: self.tracer.unhook() log("Tracer disabled") log("Form closed")
def __init__(self, ma): super(MainWidget, self).__init__() self.ma = ma mainLayout = QVBoxLayout() splitter = QSplitter() self.local_path_view = LocalPathView() self.server_path_view = ServerPathView() splitter.addWidget(self.server_path_view) splitter.addWidget(self.local_path_view) splitter.setStretchFactor(0, 1) splitter.setStretchFactor(1, 1) self.command_output = QTextEdit() self.command_output.setReadOnly(True) splitter_vl = QSplitter() splitter_vl.setOrientation(Qt.Vertical) splitter_vl.addWidget(splitter) splitter_vl.addWidget(self.command_output) splitter_vl.setStretchFactor(0, 8) splitter_vl.setStretchFactor(1, 2) command_line_hl = QHBoxLayout() fcommand_line_name = QLabel("Command line:") self.lineEdit = QLineEdit() extract_button = QPushButton("Extract") command_line_hl.addWidget(fcommand_line_name) command_line_hl.addWidget(self.lineEdit) command_line_hl.addWidget(extract_button) mainLayout.addWidget(splitter_vl) mainLayout.addLayout(command_line_hl) self.setLayout(mainLayout) self.lineEdit.returnPressed.connect(self.processCommand) extract_button.clicked.connect(self.extract) config = {} try: with open('config.json', 'r') as f: config = json.load(f) except : pass # [--version] [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]* prog_name = sys.argv[0] parser = argparse.ArgumentParser() if len(sys.argv) > 1: if(sys.argv[1] == "-C"): sys.argv.pop(1) if (sys.argv[1][0] != '-'): config['config'] = sys.argv[1] sys.argv.pop(1) parser.add_argument("-s", dest='index_server') parser.add_argument("-t", dest='tape_server') parser.add_argument("-d", dest='tape_device') parser.add_argument('args', nargs=argparse.REMAINDER) parsed = parser.parse_args() if parsed.index_server: config['index_server'] = parsed.index_server if parsed.tape_server: config['tape_server'] = parsed.tape_server if parsed.tape_device: config['tape_device'] = parsed.tape_device config["args"] = parsed.args sys.argv = [prog_name] self.amrecover = AmrecoverWrapper(config) self.command_output.setPlainText(self.amrecover.getCommandRes())