def __init__(self, signalNames): super(MainWindow, self).__init__() widget = QWidget() self.setCentralWidget(widget) self.consoleView = ConsoleView() self.signalView = SignalView() buttonsWidget = QWidget() scroll = QScrollArea() scroll.setWidget(self.signalView) scroll.setWidgetResizable(True) hboxSignalButtons = QHBoxLayout() self.signalButtons = self.createSignalButtons(signalNames, hboxSignalButtons) buttonsWidget.setLayout(hboxSignalButtons) splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(scroll) splitter.addWidget(self.consoleView) vbox = QVBoxLayout() vbox.addWidget(buttonsWidget) vbox.addWidget(splitter) self.createActions() self.createMenu() widget.setLayout(vbox) self.setWindowTitle("kit")
def __createFigure(self): ## self.__fig=mpl.figure.Figure(figsize=(8, 5),constrained_layout=True, tight_layout=None) #单位英寸 #self.__fig = mpl.figure.Figure(figsize=(4, 2)) #单位英寸 self.__fig = mpl.figure.Figure() figCanvas = FigureCanvas(self.__fig) # 创建FigureCanvas对象,必须传递一个Figure对象 self.__fig.suptitle("显示", fontsize=16, fontweight='bold') # 总的图标题 naviToolbar = NavigationToolbar(figCanvas, self) # 创建工具栏 naviToolbar.setToolButtonStyle( Qt.ToolButtonTextUnderIcon ) # ToolButtonTextUnderIcon,ToolButtonTextBesideIcon self.addToolBar(naviToolbar) # 添加工具栏到主窗口 self.setCentralWidget(figCanvas) splitter1 = QSplitter(Qt.Vertical) splitter1.addWidget(self.ui.verticalLayoutWidget) splitter1.addWidget(self.ui.horizontalLayoutWidget) # splitter2 = QSplitter(Qt.Vertical) # splitter2.addWidget(splitter1) # splitter2.addWidget(bottom) splitter = QSplitter(self) splitter.setOrientation(Qt.Horizontal) splitter.addWidget(splitter1) # 左侧控制面板 splitter.addWidget(figCanvas) # 右侧FigureCanvas对象 self.setCentralWidget(splitter)
def __post_init__(self) -> None: super(VisualizerWindow, self).__init__(self.parent) self.deviceState = {} main_splitter = QSplitter(self) debug_display_image_widget = DebugDisplayImageWidget( self.deviceState, self.refresh) q_scroll_area = QScrollArea() q_scroll_area.setWidget(debug_display_image_widget) main_splitter.addWidget(q_scroll_area) render_splitter = QSplitter(main_splitter) render_splitter.setOrientation(QtCore.Qt.Vertical) self.stick_selector = QtWidgets.QComboBox() self.stick_selector.activated.connect(self._switch_stick) render_splitter.addWidget(self.stick_selector) device_render_display = DeviceRenderDisplay(self.deviceState) render_splitter.addWidget(device_render_display) main_splitter.addWidget(render_splitter) self.setCentralWidget(main_splitter) self.setMinimumSize(debug_display_image_widget.width(), debug_display_image_widget.height()) self.device_render_display = device_render_display
def __createFigure(self): ## self.__fig=mpl.figure.Figure(figsize=(8, 5),constrained_layout=True, tight_layout=None) #单位英寸 ## self.__fig=mpl.figure.Figure(figsize=(8, 5)) #单位英寸 self.__fig = mpl.figure.Figure() figCanvas = FigureCanvas(self.__fig) #创建FigureCanvas对象,必须传递一个Figure对象 self.__fig.suptitle("suptitle:matplotlib in Qt GUI", fontsize=16, fontweight='bold') # 总的图标题 naviToolbar = NavigationToolbar(figCanvas, self) #创建NavigationToolbar工具栏 actList = naviToolbar.actions() #关联的Action列表 count = len(actList) #Action的个数 lastAction = actList[count - 1] #最后一个Action labCurAxes = QLabel("当前子图") naviToolbar.insertWidget(lastAction, labCurAxes) self.__comboAxes = QComboBox(self) #子图列表,用于选择子图 self.__comboAxes.setToolTip("选择当前子图") self.__comboAxes.currentIndexChanged.connect(self.do_currentAxesChaned) naviToolbar.insertWidget(lastAction, self.__comboAxes) naviToolbar.insertAction(lastAction, self.ui.actQuit) #在最后一个Action之前插入一个Action ## naviToolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) #ToolButtonTextUnderIcon self.addToolBar(naviToolbar) #添加作为主窗口工具栏 splitter = QSplitter(self) splitter.setOrientation(Qt.Horizontal) splitter.addWidget(self.ui.toolBox) #左侧控制面板 splitter.addWidget(figCanvas) #右侧FigureCanvas对象 self.setCentralWidget(splitter)
def setupWindow(self): """Set up the widgets in the main window.""" home_page_url = "https://www.google.com" # Create the view instance for the web browser self.web_view = QWebEngineView() self.web_view.setUrl(QUrl(home_page_url)) self.web_view.urlChanged.connect(self.loadHTML) self.html_text_edit = QTextEdit() self.html_text_edit.setText("Loading HTML...") self.html_text_edit.setFont(QFont('Courier', 12)) # Create splitter container and arrange widgets splitter = QSplitter() splitter.setOrientation(Qt.Vertical) splitter.addWidget(self.web_view) splitter.addWidget(self.html_text_edit) main_h_box = QHBoxLayout() main_h_box.addWidget(splitter) main_container = QWidget() main_container.setLayout(main_h_box) self.setCentralWidget(main_container)
def setObject(self, mobj): element = moose.element(mobj) try: view = self.view_dict[element] except KeyError: view = ObjectEditView(element) self.view_dict[element] = view view.model().objectNameChanged.connect(self.emitObjectNameChanged) view.colorDialog.colorSelected.connect( lambda color: self.colorChanged.emit(element, color)) textEdit = QTextEdit() view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) textEdit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) base = QSplitter() base.setOrientation(QtCore.Qt.Vertical) layout = QVBoxLayout() layout.addWidget(view) #, 0, 0) lineedit = QLineEdit("Notes:") lineedit.setReadOnly(True) layout.addWidget(lineedit) if (isinstance(mobj, moose.PoolBase) or isinstance(mobj, moose.ReacBase) or isinstance(mobj, moose.EnzBase)): info = moose.Annotator(mobj.path + '/info') textEdit.setText(QtCore.QString(info.getField('notes'))) textEdit.textChanged.connect( lambda: info.setField('notes', str(textEdit.toPlainText()))) layout.addWidget(textEdit) #,1,0) base.setLayout(layout) self.setWidget(base) self.setWindowTitle('Edit: %s' % (element.path)) view.update()
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 setup_center_ui(self): """ Set up the central widget area, which includes: DatasetWidget LogWidget """ self.setWindowTitle(f"CLARITE v{self.appctx.VERSION}") self.setWindowIcon(QIcon(":/images/clarite_logo.png")) self.setContentsMargins(10, 10, 10, 10) # Set up the central widget splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.setMinimumSize(800, 600) self.setCentralWidget(splitter) # Add the main sections dataset_widget = DatasetWidget(parent=self) splitter.addWidget(dataset_widget) self.log_tabs = QTabWidget(parent=self) self.log_tabs.setTabPosition(QTabWidget.North) splitter.addWidget(self.log_tabs) # Set the initial sizes (and relative ratio) of the two groups splitter.setSizes([500, 100])
def init_ui(self): """ Initialize the interface """ # layout the tab and textedit widgets inside the splitter splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) # Add tabs self.add_new_tab("Login...") self.add_new_tab("", False) self.tabs.currentChanged.connect(self.on_change) splitter.addWidget(self.tabs) # Add text log self.text_log_frame = QPlainTextEdit(self) splitter.addWidget(self.text_log_frame) # configure logging text_log_handler.logger_signals.log_message.connect(self.on_log) # add the splitter to the main layout self.main_layout.addWidget(splitter) # Set main layout self.setLayout(self.main_layout)
class Spliter(QWidget): def __init__(self, parent=None): super(Spliter, self).__init__(parent) self.splayout = QSplitter(self) self.splayout.setGeometry(QtCore.QRect(70, 10, 256, 576)) self.splayout.setOrientation(QtCore.Qt.Vertical) self.table1 = DetailFirstrowdata(self.splayout) self.table2 = DetailSecondrowdata(self.splayout) self.table3 = DetailThirdrowdata(self.splayout) self.gridLayout = QtWidgets.QGridLayout(self) self.gridLayout.addWidget(self.splayout) self.table1.firstrow.cellClicked['int', 'int'].connect( self.getindex) # 点击事件,更新第二栏 self.table1.firstrow.cellClicked['int', 'int'].connect( self.getindexnew) # 点击事件,更新第三栏 # 鼠标点击后 设置第二行,第三行的数据 def getindexnew(self): row = self.table1.firstrow.currentRow() strindex = self.table1.firstrow.item(row, 0).text() # 取 所点击行的第一个数据, index = int(strindex) self.table3.dynamicsetval(index) def getindex(self): row = self.table1.firstrow.currentRow() strindex = self.table1.firstrow.item(row, 0).text() index = int(strindex) self.table2.dynamicsetval(index)
class Ui_Form(object): """default range slider form""" def setupUi(self, Form): Form.setObjectName(_fromUtf8("QRangeSlider")) Form.resize(300, 30) Form.setStyleSheet(_fromUtf8(DEFAULT_CSS)) self.gridLayout = QGridLayout(Form) # self.gridLayout.setMargin(0) self.gridLayout.setSpacing(0) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self._splitter = QSplitter(Form) self._splitter.setMinimumSize(QtCore.QSize(0, 0)) self._splitter.setMaximumSize(QtCore.QSize(16777215, 16777215)) self._splitter.setOrientation(QtCore.Qt.Horizontal) self._splitter.setObjectName(_fromUtf8("splitter")) self._head = QGroupBox(self._splitter) self._head.setTitle(_fromUtf8("")) self._head.setObjectName(_fromUtf8("Head")) self._handle = QGroupBox(self._splitter) self._handle.setTitle(_fromUtf8("")) self._handle.setObjectName(_fromUtf8("Span")) self._tail = QGroupBox(self._splitter) self._tail.setTitle(_fromUtf8("")) self._tail.setObjectName(_fromUtf8("Tail")) self.gridLayout.addWidget(self._splitter, 0, 0, 1, 1) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): # encoding = QApplication.UnicodeUTF8 # Form.setWindowTitle(QApplication.translate("QRangeSlider", # "QRangeSlider", # None, encoding)) pass
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): super(MainWindow, self).__init__() self.resize(1400, 800) self.setWindowTitle('Light Seeker') self.menuBar() self.menu_bar() self.output = NewTable.OutputTable() self.input = NewTable.InputTable() spliter = QSplitter(self) spliter.addWidget(self.output) spliter.addWidget(self.input) spliter.setOrientation(Qt.Horizontal) self.setCentralWidget(spliter) QThread.sleep(1) self.show() qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft())
class MrhReadWidget(QWidget): """Tab READ.""" def __init__(self): super().__init__() self.datatable = MrhReadTable() self.datatable.setObjectName('read_datatable') self.viewoptiongroup = MrhReadViewGroupbox() self.viewoptiongroup.setObjectName('read_viewoption') self.info_textedit = QTextEdit() self.info_textedit.setObjectName('read_info_textedit') self.functiongroup = MrhReadFunctionGroupbox() self.functiongroup.setObjectName('read_functiongroup') self.memooptiongroup = MrhReferenceMemoGroupbox() self.memooptiongroup.setObjectName('read_memooption') self.vlayout = QVBoxLayout() self.splitter = QSplitter() self.splitter.setChildrenCollapsible(False) self.splitter.setOrientation(Qt.Vertical) self.splitter.addWidget(self.datatable) self.splitter.addWidget(self.info_textedit) self.splitter.addWidget(self.memooptiongroup) self.vlayout.addWidget(self.splitter) self.vlayout.addWidget(self.viewoptiongroup) self.vlayout.addWidget(self.functiongroup) self.setLayout(self.vlayout)
class Ui_Form(object): """default range slider form""" def setupUi(self, Form): Form.setObjectName(_fromUtf8("QRangeSlider")) Form.resize(300, 30) Form.setStyleSheet(_fromUtf8(DEFAULT_CSS)) self.gridLayout = QGridLayout(Form) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setSpacing(0) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self._splitter = QSplitter(Form) self._splitter.setMinimumSize(QtCore.QSize(0, 0)) self._splitter.setMaximumSize(QtCore.QSize(16777215, 16777215)) self._splitter.setOrientation(QtCore.Qt.Horizontal) self._splitter.setObjectName(_fromUtf8("splitter")) self._head = QGroupBox(self._splitter) self._head.setTitle(_fromUtf8("")) self._head.setObjectName(_fromUtf8("Head")) self._handle = QGroupBox(self._splitter) self._handle.setTitle(_fromUtf8("")) self._handle.setObjectName(_fromUtf8("Span")) self._tail = QGroupBox(self._splitter) self._tail.setTitle(_fromUtf8("")) self._tail.setObjectName(_fromUtf8("Tail")) self.gridLayout.addWidget(self._splitter, 0, 0, 1, 1) QtCore.QMetaObject.connectSlotsByName(Form)
def _on_ui_element_created(self, elem, widget): if elem == 'disassembly': self.disassembly_view = widget self.disassembly_view.run_default_disassembler = False self.disassembly_view.onDisassemble.connect(self._on_disassemble) r2_info = QSplitter() r2_info.setOrientation(Qt.Vertical) call_refs = DwarfListView() self.call_refs_model = QStandardItemModel(0, 3) self.call_refs_model.setHeaderData(0, Qt.Horizontal, 'call refs') self.call_refs_model.setHeaderData(1, Qt.Horizontal, '') self.call_refs_model.setHeaderData(2, Qt.Horizontal, '') call_refs.setModel(self.call_refs_model) code_xrefs = DwarfListView() self.code_xrefs_model = QStandardItemModel(0, 3) self.code_xrefs_model.setHeaderData(0, Qt.Horizontal, 'code xrefs') self.code_xrefs_model.setHeaderData(1, Qt.Horizontal, '') self.code_xrefs_model.setHeaderData(2, Qt.Horizontal, '') code_xrefs.setModel(self.code_xrefs_model) r2_info.addWidget(call_refs) r2_info.addWidget(code_xrefs) self.disassembly_view.insertWidget(0, r2_info) self.disassembly_view.setStretchFactor(0, 1) self.disassembly_view.setStretchFactor(1, 5) r2_menu = QMenu('r2') r2_menu.addAction('graph view', self.show_graph_view) r2_menu.addAction('decompile', self.show_decompiler_view) self.disassembly_view.disasm_view.menu_extra_menu.append(r2_menu)
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.populateScene() self.h1Splitter = QSplitter() self.h2Splitter = QSplitter() vSplitter = QSplitter() vSplitter.setOrientation(Qt.Vertical) vSplitter.addWidget(self.h1Splitter) vSplitter.addWidget(self.h2Splitter) view = View("Top left view") view.view().setScene(self.scene) self.h1Splitter.addWidget(view) view = View("Top right view") view.view().setScene(self.scene) self.h1Splitter.addWidget(view) view = View("Bottom left view") view.view().setScene(self.scene) self.h2Splitter.addWidget(view) view = View("Bottom right view") view.view().setScene(self.scene) self.h2Splitter.addWidget(view) layout = QHBoxLayout() layout.addWidget(vSplitter) self.setLayout(layout) self.setWindowTitle("Chip Demo")
class Ui_Mode(QMainWindow): """ 模式选择界面 """ def __init__(self, prev, parent=None): QMainWindow.__init__(self, parent) self.prev = prev self.setWindowTitle("规则录制界面") self.split = QSplitter(self) self.split.setOrientation(Qt.Vertical) self.split.setContentsMargins(0, 10, 10, 0) self.label = QLabel(self.split) self.label.setText("请选择您要采集的网页类型") self.label.setStyleSheet("font:bold;color:#8A2BE2") self.label.setContentsMargins(10, 10, 10, 10) self.mode_widget = QWidget(self.split) self.mode_widget_layout = QHBoxLayout() self.mode_widget.setLayout(self.mode_widget_layout) self.mode_widget.setStyleSheet("background:#7CCD7C") self.mode_1 = My_Label(1, self) self.mode_2 = My_Label(2, self) self.mode_3 = My_Label(3, self) mode_image_1 = QPixmap('../images/mode-1.png') mode_image_2 = QPixmap('../images/mode-2.png') mode_image_3 = QPixmap('../images/mode-3.png') self.mode_1.setPixmap(mode_image_1) self.mode_2.setPixmap(mode_image_2) self.mode_3.setPixmap(mode_image_3) self.mode_widget_layout.addStretch() self.mode_widget_layout.addWidget(self.mode_1) self.mode_widget_layout.addWidget(self.mode_2) self.mode_widget_layout.addWidget(self.mode_3) self.mode_widget_layout.addStretch() self.mode_illustrate_widget = QWidget(self.split) self.mode_illustrate_widget_layout = QHBoxLayout() self.mode_illustrate_widget.setLayout( self.mode_illustrate_widget_layout) # self.mode_illustrate_widget.setStyleSheet("background:white") self.i_mode = QLabel(self.mode_illustrate_widget) i_mode_image = QPixmap('../images/i-mode-1.png') self.i_mode.setPixmap(i_mode_image) self.mode_illustrate_widget_layout.addStretch() self.mode_illustrate_widget_layout.addWidget(self.i_mode) self.mode_illustrate_widget_layout.addStretch() self.split.addWidget(self.label) self.split.addWidget(self.mode_widget) self.split.addWidget(self.mode_illustrate_widget) self.split.setStretchFactor(0, 1) self.split.setStretchFactor(2, 50) self.split.setStretchFactor(3, 500) self.setCentralWidget(self.split)
def __init__(self, LOGIN, isRunningOnPi=False, parent=None): super(MainWindow, self).__init__() self.main_widget = QWidget() self.mdi = QMdiArea() self.setWindowTitle('Brew Monitoring System') bar = self.menuBar() filebar = bar.addMenu("File") filebar.addAction("New User") filebar.addAction("New Brew") filebar.triggered.connect(self.fileaction) viewbar = bar.addMenu("View") viewbar.addAction("Mash and Boil Vessels") viewbar.addAction("Fermentation Vessels") viewbar.addAction("Past Brew Data") viewbar.triggered.connect(self.viewaction) windowbar = bar.addMenu("Window") windowbar.addAction("Cascade") windowbar.addAction("Tiled") windowbar.triggered.connect(self.windowaction) systembar = bar.addMenu("System") systembar.addAction("Check For Faults") self.mainwindow = MdiMainWindow(LOGIN, isRunningOnPi=isRunningOnPi, parent=self) quitButton = QPushButton("Quit") quitButton.clicked.connect(lambda: self.close()) quitLayout = QHBoxLayout() quitLayout.addStretch(10) quitLayout.addWidget(quitButton) splitter = QSplitter() splitter.setOrientation(2) splitter.addWidget(self.mainwindow) splitter.addWidget(self.mdi) layout = QVBoxLayout() #layout.addWidget(self.mainwindow) #layout.addWidget(self.mdi) layout.addWidget(splitter) #layout.addLayout(quitLayout) #self.main_widget.setLayout(layout) # self.main_widget.showFullScreen() self.main_widget.setLayout(layout) self.setMinimumSize(700, 500) self.resize(0, 0) self.setCentralWidget(self.main_widget)
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')
class CanvasToolDock(QWidget): """Canvas dock widget with widget toolbox, quick help and canvas actions. """ def __init__(self, parent=None, **kwargs): QWidget.__init__(self, parent, **kwargs) self.__setupUi() def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.toolbox = WidgetToolBox() self.help = QuickHelpWidget(objectName="quick-help") self.__splitter = QSplitter() self.__splitter.setOrientation(Qt.Vertical) self.__splitter.addWidget(self.toolbox) self.__splitter.addWidget(self.help) self.toolbar = DynamicResizeToolBar() self.toolbar.setMovable(False) self.toolbar.setFloatable(False) self.toolbar.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) layout.addWidget(self.__splitter, 10) layout.addWidget(self.toolbar) self.setLayout(layout) self.__splitterResizer = SplitterResizer() self.__splitterResizer.setSplitterAndWidget(self.__splitter, self.help) def setQuickHelpVisible(self, state): """Set the quick help box visibility status. """ self.__splitterResizer.setExpanded(state) def quickHelpVisible(self): return self.__splitterResizer.expanded() def setQuickHelpAnimationEnabled(self, enabled): """Enable/disable the quick help animation. """ self.__splitterResizer.setAnimationEnabled(enabled) def toogleQuickHelpAction(self): """Return a checkable QAction for help show/hide. """ return self.__splitterResizer.toogleExpandedAction()
class Ui_Task(QMainWindow): """ 任务展示页面 """ def __init__(self, prev, parent=None): QMainWindow.__init__(self, parent) self.prev = prev self.setWindowTitle("任务展示界面") self.layout = QHBoxLayout() self.setLayout(self.layout) self.toolbar = self.addToolBar("step") self.add = QAction(QIcon("../images/add.png"), "新增", self) self.delete = QAction(QIcon("../images/delete.png"), "删除", self) self.search_text = MyLineEdit(self) self.search_text.setPlaceholderText("请输入查询关键字") self.search_text.setContentsMargins(20, 0, 0, 0) self.search_text.setMinimumHeight(40) self.refresh = QAction(QIcon("../images/refresh.png"), "刷新", self) self.toolbar.addAction(self.add) self.add.triggered.connect(lambda: self.prev.create_tab(0, 0, "")) self.toolbar.addAction(self.delete) self.task = TaskList(self) self.delete.triggered.connect(lambda: self.task.delete_task()) self.toolbar.addWidget(self.search_text) self.toolbar.addAction(self.refresh) self.refresh.triggered.connect(lambda: self.task.search_node()) self.toolbar.addSeparator() self.split = QSplitter(self) self.split.setOrientation(Qt.Vertical) self.tree = QTreeWidget(self.split) self.tree.setColumnCount(8) # self.tree.setStyleSheet(r'QTreeView{font-size:20px}') self.tree.setStyleSheet(WidgetStyle.TREE_WIDGET) self.tree.itemDoubleClicked.connect(self.show_task) self.tree.itemChanged.connect(self.task.click_process) # self.tree.setColumnHidden(5,True) self.tree.setHeaderLabels(['名称', '地址', '采集类型', '用户', '操作']) self.tree.header().setDefaultAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.split.addWidget(self.tree) self.setCentralWidget(self.split) self.task.load_data() def show_task(self, item): try: type = item.text(7) if type == "task": id = int(item.text(6)) name = item.text(0) self.prev.create_tab(1, id, name) except Exception as a: print(a)
def __createFigure(self): # 设置窗口画布,并添加分割线 self._fig = plt.Figure() figCanvas = FigureCanvas(self._fig) naviToolbar = NavigationToolbar(figCanvas, self) self.addToolBar(naviToolbar) splitter = QSplitter(self) splitter.setOrientation(Qt.Horizontal) splitter.addWidget(figCanvas) self.setCentralWidget(splitter)
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 add_new_tab(self, webAddress_name_list, text): self.setVisible(True) widget = QWidget() layout = QVBoxLayout() layout_h = QHBoxLayout() splitter = QSplitter() splitter.setOrientation(Qt.Horizontal) listWidget = QListWidget() listWidget.setCurrentRow(0) browser = QWebEngineView() lineEdit_url = LineEdit() pushButton_copy = QPushButton('复制网址') splitter.addWidget(listWidget) splitter.addWidget(browser) splitter.addWidget(self.listWidget_history) splitter.setStretchFactor(0, 2) splitter.setStretchFactor(1, 8) splitter.setStretchFactor(2, 1) layout_h.addWidget(lineEdit_url) layout_h.addWidget(pushButton_copy) layout.addLayout(layout_h) layout.addWidget(splitter) widget.setLayout(layout) self.lineEdit_url_list.append(lineEdit_url) self.browser_list.append(browser) self.listWidget_list.append(listWidget) name_list, self.webAddress_history_list = self.load_history_from_database( ) self.listWidget_history.addItems(name_list) listWidget.currentRowChanged.connect(self.listWidget_changed) lineEdit_url.returnPressed.connect(self.lineEdit_enterd) pushButton_copy.clicked.connect(self.pushButton_copy_clicked) webAddress_list = [ address.split('-----')[1].format(text) for address in webAddress_name_list ] self.webAddress_LIST.append(webAddress_list) webName_list = [ address.split('-----')[0] for address in webAddress_name_list ] url = webAddress_list[0] listWidget.addItems(webName_list) browser.setUrl(QUrl(url)) lineEdit_url.setText(url) i = self.tabWidget.addTab(widget, 'loading') browser.urlChanged.connect(lambda qurl, browser=browser: lineEdit_url. setText(qurl.toString())) browser.loadFinished.connect(lambda _, i=i, browser=browser: self. setTabText_and_to_history(i, browser)) self.tabWidget.setCurrentIndex(i)
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(400, 300) self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.label = QLabel(self.centralwidget) self.label.setGeometry(QRect(100, 10, 200, 31)) font = QFont() font.setFamily("Georgia") font.setPointSize(16) self.label.setFont(font) self.label.setAlignment(Qt.AlignCenter) self.label.setObjectName("label") self.splitter = QSplitter(self.centralwidget) self.splitter.setGeometry(QRect(20, 70, 351, 151)) self.splitter.setOrientation(Qt.Vertical) self.splitter.setObjectName("splitter") self.label_2 = QLabel(self.splitter) font = QFont() font.setFamily("Georgia") font.setPointSize(12) self.label_2.setFont(font) self.label_2.setAlignment(Qt.AlignCenter) self.label_2.setWordWrap(True) self.label_2.setObjectName("label_22") self.label_3 = QLabel(self.splitter) font = QFont() font.setFamily("Georgia") font.setPointSize(12) self.label_3.setFont(font) self.label_3.setAlignment(Qt.AlignCenter) self.label_3.setWordWrap(True) self.label_3.setObjectName("label_3") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(MainWindow) self.menubar.setGeometry(QRect(0, 0, 400, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Новая вкладка")) self.label.setText(_translate("MainWindow", "Добро Пожаловать")) self.label_2.setText(_translate("MainWindow", "Чтобы начать нажмите PgUp.")) self.label_3.setText(_translate("MainWindow", "Чтобы завершить нажмите PgUp и подождите."))
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.fileList = ui.FileList.FileList(self) self.fileListLabel = self.getLabel(self.fileList, "项目列表") self.imageArea = ui.ImageArea.ImageArea(self) self.imageAreaLabel = self.getLabel(self.imageArea, "图像预览") self.infoTable = ui.InfoTable.InfoTable(self) self.infoTableLabel = self.getLabel(self.infoTable, "输出列表") self.staBar = QStatusBar() self.staBar.setStyleSheet(uiConfig.STATUSBAR_S) self.setStatusBar(self.staBar) # 创建一个QSplitter,用来分割窗口 self.splitter = QSplitter(self) self.splitter.addWidget(self.fileListLabel) self.splitter.addWidget(self.imageAreaLabel) self.splitter.addWidget(self.infoTableLabel) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 3) self.splitter.setStretchFactor(2, 2) # QSplitter按照垂直分割 self.splitter.setStyleSheet(uiConfig.SPLITER_S) self.splitter.setOrientation(Qt.Horizontal) self.setCentralWidget(self.splitter) self.setWindowTitle("地图坐标拾取系统") # self.setStyleSheet("QMainWindow::separator { background: rgb(190,231,233) }") # self.setWindowFlag(Qt.WindowMaximizeButtonHint, False) # self.setWindowFlags(Qt.FramelessWindowHint) self.setWindowState(Qt.WindowMaximized) size = QDesktopWidget().screenGeometry(-1) self.setFixedSize(size.width(), size.height()) self.setWindowIcon(QIcon("ui/images/logo.png")) self.setStyleSheet(uiConfig.MAINWINDOW_S) def getLabel(self, mWidget, text): qLabel = QLabel() qLabel.setStyleSheet(uiConfig.GRANDLABEL_S) vLayout = QVBoxLayout() textLabel = QLabel() textLabel.setStyleSheet(uiConfig.TEXTLABEL_S) textLabel.setText(" " + text) textLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) mWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) vLayout.setContentsMargins(0, 0, 0, 0) vLayout.setSpacing(0) vLayout.addWidget(textLabel) vLayout.addWidget(mWidget) qLabel.setLayout(vLayout) return qLabel
class Ui_Setp_Label(QMainWindow): ''' 步骤标签说明 ''' def __init__(self, parent=None): QMainWindow.__init__(self, parent) # 采集类型 0:未选择类型 1:列表或表格 2:列表详情 3:单页采集 self.acq_type = 0 self.split = QSplitter(self) self.split.setOrientation(Qt.Horizontal) self.setCentralWidget(self.split) self.step_widget = QWidget(self.split) self.step_widget_layout = QHBoxLayout() self.step_widget_layout.setAlignment(Qt.AlignRight) self.step_widget.setLayout(self.step_widget_layout) self.basic_info = My_Label_TWO(1, self) self.basic_info.setText("设置基本信息") # self.basic_info.setPixmap(QPixmap('../images/step-1.png')) m = QMovie('../images/s-step-1.gif') self.basic_info.setMovie(m) m.start() self.site_type = My_Label_TWO(2, self) self.site_type.setText("设置网页类型") self.site_type.setMovie(m) self.site_type.setPixmap(QPixmap('../images/step-2.png')) self.navi = My_Label_TWO(3, self) self.navi.setText("设置列表") self.navi.setPixmap(QPixmap('../images/step-3.png')) self.navi.hide() self.flip = My_Label_TWO(4, self) self.flip.setText("翻页") self.flip.setPixmap(QPixmap('../images/step-4.png')) self.flip.hide() self.field = My_Label_TWO(5, self) self.field.setText("设置字段") self.field.setPixmap(QPixmap('../images/step-5.png')) self.field.hide() self.finish = My_Label_TWO(6, self) self.finish.setText("完成") self.finish.setPixmap(QPixmap('../images/step-6.png')) self.finish.hide() self.step_widget_layout.addWidget(self.basic_info) self.step_widget_layout.addWidget(self.site_type) self.step_widget_layout.addWidget(self.navi) self.step_widget_layout.addWidget(self.flip) self.step_widget_layout.addWidget(self.field) self.step_widget_layout.addWidget(self.finish) self.split.addWidget(self.step_widget)
def build_left_column(self): splitter = QSplitter() splitter.setHandleWidth(1) splitter.setOrientation(Qt.Vertical) splitter.setContentsMargins(0, 0, 0, 0) from ui.panel_hooks import HooksPanel self.hooks_panel = HooksPanel(self.app) splitter.addWidget(self.hooks_panel) from ui.panel_watchers import WatchersPanel self.watchers_panel = WatchersPanel(self.app) splitter.addWidget(self.watchers_panel) return splitter
def build_right_column(self): splitter = QSplitter() splitter.setHandleWidth(1) splitter.setOrientation(Qt.Vertical) splitter.setContentsMargins(0, 0, 0, 0) from ui.panel_contexts import ContextsPanel self.contexts_panel = ContextsPanel(self.app) splitter.addWidget(self.contexts_panel) from ui.panel_backtrace import BacktracePanel self.backtrace_panel = BacktracePanel(self.app) splitter.addWidget(self.backtrace_panel) return splitter
def build_left_column(self): splitter = QSplitter() splitter.setHandleWidth(1) splitter.setOrientation(Qt.Vertical) splitter.setContentsMargins(0, 0, 0, 0) self.hooks_panel = HooksPanel(self.app) splitter.addWidget(self.hooks_panel) self.contexts_panel = ContextsPanel(self.app) splitter.addWidget(self.contexts_panel) self.backtrace_panel = BacktracePanel(self.app) splitter.addWidget(self.backtrace_panel) return 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 splitViewSpace(self, viewspace, orientation): """Split the given view. If orientation == Qt.Horizontal, adds a new view to the right. If orientation == Qt.Vertical, adds a new view to the bottom. """ active = viewspace is self.activeViewSpace() splitter = viewspace.parentWidget() newspace = ViewSpace(self) if splitter.count() == 1: splitter.setOrientation(orientation) size = splitter.sizes()[0] splitter.addWidget(newspace) splitter.setSizes([size / 2, size / 2]) elif splitter.orientation() == orientation: index = splitter.indexOf(viewspace) splitter.insertWidget(index + 1, newspace) else: index = splitter.indexOf(viewspace) newsplitter = QSplitter() newsplitter.setOrientation(orientation) sizes = splitter.sizes() splitter.insertWidget(index, newsplitter) newsplitter.addWidget(viewspace) splitter.setSizes(sizes) size = newsplitter.sizes()[0] newsplitter.addWidget(newspace) newsplitter.setSizes([size / 2, size / 2]) self._viewSpaces.insert(0, newspace) newspace.showDocument(viewspace.document()) if active: newspace.activeView().setFocus() self.actionCollection.window_close_view.setEnabled(self.canCloseViewSpace()) self.actionCollection.window_close_others.setEnabled(self.canCloseViewSpace())
class PanelContainer(QWidget): def __init__(self, panelWin): super(QWidget, self).__init__() self.panelWindow = panelWin self.panelCount = 0 self.mainLayout = QGridLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.splitter = QSplitter(self) self.containerParent = 0 self.mainLayout.addWidget(self.splitter, 0, 0) def splitter(self): return self.splitter def addPanel(self, panel=None): if panel: panel.setParent(self) panel.setContainer(self) self.splitter.addWidget(panel) self.panelCount += 1 self.updatePanelSignals(panel) else: panel = self.createPanel() self.splitter.addWidget(panel) return panel def addPanelSplit(self, panel, direction): panel = PanelWidget(self) if 0 else panel # Store original size origSize = panel.size() # reparent the panel panel.setParent(self) panel.setContainer(self) # set orientation and add the panel self.splitter.setOrientation(direction) self.splitter.addWidget(panel) # add another panel for split panel = self.createPanel() self.splitter.addWidget(panel) sizes = list() origSize *= 0.5 if direction == Qt.Horizontal: sizes.append(origSize.width()) sizes.append(origSize.width()) else: sizes.append(origSize.height()) sizes.append(origSize.height()) self.splitter.setSizes(sizes) self.panelCount += 1 def addContainer(self, child): child = PanelContainer(self) if 0 else child self.splitter.addWidget(child) child.setParentContainer(self) def insertContainer(self, child, index): child = PanelContainer(self) if 0 else child self.splitter.insertWidget(index, child) child.setParentContainer(self) def setParentContainer(self, parent): self.containerParent = parent def parentContainer(self): return self.containerParent def childContainers(self): # childContainers = list() # for index in range(0, self.splitter.count()): # container = self.splitter.widget(index) # if container: # childContainers.append(container) return self.sortedChildren() def panels(self): # panels = list() # for index in range(0, self.splitter.count()): # panel = self.splitter.widget(index) # if panel: # panels.append(panel) return self.sortedChildren() def sortedChildren(self): return (self.splitter.widget(index) for index in range(self.splitter.count())) def numberOfPanels(self): return self.panelCount def createPanel(self): panel = PanelWidget(self) panel.createMenu(WorkbenchWidget.panelNames()) self.connectPanelSignals(panel) self.panelCount += 1 return panel def connectPanelSignals(self, panel): panel = PanelWidget(self) if 0 else panel panel.panelSplit.connect(lambda: self.panelWindow.splitPanel()) panel.panelFloat.connect(lambda : self.panelWindow.floatPanel()) panel.panelClosed.connect(lambda : self.panelWindow.closePanel()) panel.panelMenuTriggered.connect(lambda : self.panelWindow.closePanel()) panel.tabClosed.connect(lambda : self.panelWindow.closePanel()) def updatePanelSignals(self, panel): panel = PanelWidget(self) if 0 else panel panel.panelSplit.disconnect() panel.panelFloat.disconnect() panel.panelClosed.disconnect() panel.panelMenuTriggered.disconnect() panel.tabClosed.disconnect()
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())
class ParamModWgt(QWidget): def __init__(self, parent=None): super().__init__(parent) self.main_window = parent self.buildRequiredTagsGB() # Widgets self.newParamBtn = QPushButton("New") self.deleteParamBtn = QPushButton("Delete") self.paramSaveAnnotBtn = QPushButton("Save") buttonWidget = QWidget(self) self.existingParamsGB = QGroupBox("Existing parameters", self) self.paramListTblWdg = QTableView() self.paramListModel = ParameterListModel(parent=self) self.paramListTblWdg.setSelectionBehavior(QAbstractItemView.SelectRows) self.paramListTblWdg.setSelectionMode(QAbstractItemView.SingleSelection) self.paramListTblWdg.setModel(self.paramListModel) self.paramListTblWdg.setColumnWidth(0, 150) self.paramListTblWdg.setColumnWidth(1, 350) self.relationWgt = ParamRelationWgt(parent) self.newParamsGB = QGroupBox("Parameter details", self) self.resultTypeCbo = QComboBox(self) self.isExpProp = QCheckBox("is an experimental property", self) self.resultTypeCbo.addItems(["point value", "function", "numerical trace"]) self.singleValueParamWgt = ParamValueWgt(parent) self.functionParamWgt = ParamFunctionWgt(parent) self.traceParamWgt = ParamTraceWgt(parent) self.functionParamWgt.mainWgt = self self.paramModStack = QStackedWidget(self) self.paramModStack.addWidget(self.singleValueParamWgt) self.paramModStack.addWidget(self.functionParamWgt) self.paramModStack.addWidget(self.traceParamWgt) # Signals selectionModel = self.paramListTblWdg.selectionModel() selectionModel.selectionChanged.connect(self.selectedParameterChanged) self.newParamBtn.clicked.connect(self.newParameter) self.deleteParamBtn.clicked.connect(self.deleteParameter) self.paramSaveAnnotBtn.clicked.connect(self.saveParameter) self.resultTypeCbo.currentIndexChanged.connect(self.paramModStack.setCurrentIndex) self.singleValueParamWgt.paramTypeSelected.connect(self.newParamTypeSelected) self.functionParamWgt.paramTypeSelected.connect(self.newParamTypeSelected) self.traceParamWgt.paramTypeSelected.connect(self.newParamTypeSelected) # Layout buttonLayout = QVBoxLayout(buttonWidget) buttonLayout.addWidget(self.paramSaveAnnotBtn) buttonLayout.addWidget(self.deleteParamBtn) buttonLayout.addWidget(self.newParamBtn) existGrid = QHBoxLayout(self.existingParamsGB) existGrid.addWidget(buttonWidget) existGrid.addWidget(self.paramListTblWdg) newGrid = QGridLayout(self.newParamsGB) newGrid.addWidget(QLabel("Result type"), 0, 0) newGrid.addWidget(self.resultTypeCbo, 0, 1) newGrid.addWidget(self.isExpProp, 0, 2) newGrid.addWidget(self.paramModStack, 1, 0, 1, 3) newGrid.addWidget(self.relationWgt, 1, 3) layout = QVBoxLayout(self) self.rootLayout = QSplitter(Qt.Vertical, self) self.rootLayout.setOrientation(Qt.Vertical) self.rootLayout.addWidget(self.existingParamsGB) self.rootLayout.addWidget(self.newParamsGB) self.rootLayout.addWidget(self.requireTagGB) layout.addWidget(self.rootLayout) # Initial behavior self.newParamBtn.setEnabled(True) self.deleteParamBtn.setEnabled(False) self.paramSaveAnnotBtn.setEnabled(False) self.additionMode = False self.newParamsGB.setEnabled(False) def setRootLayoutSizes(self, sizes): self.rootLayout.setSizes(sizes) def viewParameter(self, parameter): row = -1 for row, param in enumerate(self.paramListModel.parameterList): if param.id == parameter.id: break assert(row > -1) self.paramListTblWdg.selectRow(row) @pyqtSlot(str) def newParamTypeSelected(self, paramName): self.requiredTagsListModel.clear() self.requiredTagsListModel.refresh() paramType = getParameterTypeFromName(paramName) if paramType is None: raise ValueError("Parameter type with name '" + paramName + "' was not found.") for reqTag in paramType.requiredTags: self.requiredTagsListModel.addTag(reqTag.id, reqTag.name, reqTag.id, reqTag.name) self.requiredTagsListModel.refresh() def buildRequiredTagsGB(self): # Widgets self.requireTagGB = QGroupBox("Required tag categories", self) self.requiredTagsListTblWdg = RequiredTagsTableView() self.requiredTagsListModel = RequiredTagsListModel(parent=self) self.requiredTagsListTblWdg.setSelectionBehavior(QAbstractItemView.SelectRows) self.requiredTagsListTblWdg.setSelectionMode(QAbstractItemView.SingleSelection) self.requiredTagsListTblWdg.setModel(self.requiredTagsListModel) self.requiredTagsListTblWdg.setColumnWidth(0, 200) self.requiredTagsListTblWdg.setColumnWidth(1, 200) # Layout requiredTagLayout = QGridLayout(self.requireTagGB) requiredTagLayout.addWidget(self.requiredTagsListTblWdg, 0, 0, 4, 1) def newParameter(self): self.resultTypeCbo.setCurrentIndex(0) self.paramModStack.currentWidget().newParameter() self.singleValueParamWgt.newParameter() self.functionParamWgt.newParameter() self.traceParamWgt.newParameter() self.newParamsGB.setEnabled(True) self.paramListTblWdg.clearSelection() self.newParamBtn.setEnabled(False) self.deleteParamBtn.setEnabled(False) self.paramSaveAnnotBtn.setEnabled(True) self.isExpProp.setChecked(False) def saveParameter(self): relationship = self.relationWgt.getRelationship() # Get the ID of the modified parameter if we are modifying an existing # parameters if len(self.paramListTblWdg.selectionModel().selectedRows()) != 0: selectedRow = self.paramListTblWdg.selectionModel().currentIndex().row() paramId = self.main_window.currentAnnotation.parameters[selectedRow].id else: paramId = None param = self.paramModStack.currentWidget().saveParameter(relationship, paramId) if not param is None: param.requiredTags = self.requiredTagsListModel.getRequiredTags() param.isExperimentProperty = self.isExpProp.isChecked() selectedRow = self.paramListTblWdg.selectionModel().currentIndex().row() # Even when there is no selection, selectedRow can take a zero value. This "if" # controls for that. if len(self.paramListTblWdg.selectionModel().selectedRows()) == 0: selectedRow = -1 if selectedRow >= 0: self.main_window.currentAnnotation.parameters[selectedRow] = param else: self.main_window.currentAnnotation.parameters.append(param) self.additionMode = False nbParams = len(self.main_window.currentAnnotation.parameters) self.main_window.saveAnnotation() if selectedRow < 0 : selectedRow = nbParams-1 self.paramListTblWdg.selectRow(selectedRow) self.loadRow(selectedRow) def deleteParameter(self): selectedRow = self.paramListTblWdg.selectionModel().currentIndex().row() del self.main_window.currentAnnotation.parameters[selectedRow] self.main_window.saveAnnotation() self.refreshModelingParameters() def refreshModelingParameters(self): selectedRow = self.paramListTblWdg.selectionModel().currentIndex().row() self.loadModelingParameter(selectedRow) def loadModelingParameter(self, row = None): """ Call when a new annotation has been selected so that all the modeling parameters associated with this annotation are loaded in the parameter list. """ self.requiredTagsListModel.clear() self.requiredTagsListModel.refresh() if self.main_window.currentAnnotation is None: self.paramListModel.parameterList = [] else: self.paramListModel.parameterList = self.main_window.currentAnnotation.parameters aRowIsSelected = not row is None if aRowIsSelected: if row < 0: noRowToLoad = self.paramListTblWdg.model().rowCount()-row else: noRowToLoad = row else: ## No rows are selected noRowToLoad = -1 self.loadRow(noRowToLoad) self.newParamBtn.setEnabled(True) self.deleteParamBtn.setEnabled(aRowIsSelected) self.paramSaveAnnotBtn.setEnabled(aRowIsSelected) self.paramModStack.currentWidget().loadModelingParameter(row) self.relationWgt.loadModelingParameter(row) self.newParamsGB.setEnabled(aRowIsSelected) self.paramListModel.refresh() def loadRow(self, selectedRow = None): """ Called when a row has been selected in the table listing all the modeling parameters. It update the interface with the values associated with this specific parameter. """ def nlxCheck(id): if id in nlx2ks: return nlx2ks[id] return id def clear(): self.requiredTagsListModel.clear() self.paramModStack.currentWidget().loadRow(None) self.relationWgt.clear() self.paramListTblWdg.clearSelection() if selectedRow is None: selectedRow = self.paramListTblWdg.selectionModel().currentIndex().row() if self.main_window.currentAnnotation is None: clear() return if selectedRow < 0 or selectedRow >= len(self.main_window.currentAnnotation.parameters) : clear() return currentParameter = self.main_window.currentAnnotation.parameters[selectedRow] self.newParamBtn.setEnabled(True) self.deleteParamBtn.setEnabled(True) self.paramSaveAnnotBtn.setEnabled(True) if currentParameter.description.type == "pointValue": self.resultTypeCbo.setCurrentIndex(0) self.paramModStack.setCurrentIndex(0) elif currentParameter.description.type == "function": self.resultTypeCbo.setCurrentIndex(1) self.paramModStack.setCurrentIndex(1) elif currentParameter.description.type == "numericalTrace": self.resultTypeCbo.setCurrentIndex(2) self.paramModStack.setCurrentIndex(2) else: raise ValueError("Type of parameter description " + currentParameter.description.type + " is invalid.") self.paramModStack.currentWidget().loadRow(currentParameter) self.relationWgt.loadRow(currentParameter) self.isExpProp.setChecked(currentParameter.isExperimentProperty) ## UPDATING REQUIRED TAGS self.requiredTagsListModel.clear() for tag in currentParameter.requiredTags: self.requiredTagsListModel.addTag(tag.rootId, self.main_window.dicData[tag.rootId], tag.id, tag.name) ## Adding new required tags that may have been specified since the ## creation of this parameter instance. parameterType = getParameterTypeFromID(currentParameter.typeId) reqTags = {reqTag.rootId:reqTag for reqTag in parameterType.requiredTags} for reqTagRootId, reqTag in reqTags.items(): #print(nlxCheck(reqTagRootId), [nlxCheck(tag.rootId) for tag in currentParameter.requiredTags]) if not nlxCheck(reqTagRootId) in [nlxCheck(tag.rootId) for tag in currentParameter.requiredTags]: self.requiredTagsListModel.addTag(reqTag.rootId, self.main_window.dicData[reqTag.rootId], reqTag.id, reqTag.name) self.requiredTagsListModel.refresh() self.newParamsGB.setEnabled(True) def selectedParameterChanged(self, selected, deselected): if len(selected.indexes()) == 0: return if self.additionMode: msgBox = QMessageBox(self) msgBox.setWindowTitle("Cancellation") msgBox.setText("Are you sure you want to cancel the addition of the new parameter being edited? If not, say no and then hit 'Save' to save this new parameter.") msgBox.setStandardButtons(QMessageBox.No | QMessageBox.Yes) msgBox.setDefaultButton(QMessageBox.No) if msgBox.exec_() == QMessageBox.Yes: self.additionMode = False self.loadRow() else: #self.paramListTblWdg.selectRow(-1) self.paramListTblWdg.clearSelection() else: self.loadRow()
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 SignalTabController(QWidget): frame_closed = pyqtSignal(SignalFrameController) not_show_again_changed = pyqtSignal() signal_created = pyqtSignal(Signal) files_dropped = pyqtSignal(list) frame_was_dropped = pyqtSignal(int, int) @property def num_frames(self): return self.splitter.count() - 1 @property def signal_frames(self): """ :rtype: list of SignalFrameController """ return [self.splitter.widget(i) for i in range(self.num_frames)] @property def signal_undo_stack(self): return self.undo_stack def __init__(self, project_manager, parent=None): super().__init__(parent) self.ui = Ui_Interpretation() self.ui.setupUi(self) self.splitter = QSplitter() self.splitter.setStyleSheet("QSplitter::handle:vertical {\nmargin: 4px 0px; background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0, \nstop:0 rgba(255, 255, 255, 0), \nstop:0.5 rgba(100, 100, 100, 100), \nstop:1 rgba(255, 255, 255, 0));\n image: url(:/icons/data/icons/splitter_handle_horizontal.svg);\n}") self.splitter.setOrientation(Qt.Vertical) self.splitter.setChildrenCollapsible(True) self.splitter.setHandleWidth(6) placeholder_widget = QWidget() placeholder_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.undo_stack = QUndoStack() self.project_manager = project_manager self.splitter.addWidget(placeholder_widget) self.signal_vlay = QVBoxLayout() self.signal_vlay.setContentsMargins(0,0,0,0) self.signal_vlay.addWidget(self.splitter) self.ui.scrlAreaSignals.setLayout(self.signal_vlay) self.drag_pos = None def on_files_dropped(self, files): self.files_dropped.emit(files) def close_frame(self, frame:SignalFrameController): self.frame_closed.emit(frame) def add_signal_frame(self, proto_analyzer): sig_frame = SignalFrameController(proto_analyzer, self.undo_stack, self.project_manager, parent=self) sframes = self.signal_frames if len(proto_analyzer.signal.filename) == 0: # new signal from "create signal from selection" sig_frame.ui.btnSaveSignal.show() self.__create_connects_for_signal_frame(signal_frame=sig_frame) sig_frame.signal_created.connect(self.signal_created.emit) sig_frame.not_show_again_changed.connect(self.not_show_again_changed.emit) sig_frame.ui.lineEditSignalName.setToolTip(self.tr("Sourcefile: ") + proto_analyzer.signal.filename) sig_frame.apply_to_all_clicked.connect(self.on_apply_to_all_clicked) prev_signal_frame = sframes[-1] if len(sframes) > 0 else None if prev_signal_frame is not None and hasattr(prev_signal_frame, "ui"): sig_frame.ui.cbProtoView.setCurrentIndex(prev_signal_frame.ui.cbProtoView.currentIndex()) sig_frame.blockSignals(True) if proto_analyzer.signal.qad_demod_file_loaded: sig_frame.ui.cbSignalView.setCurrentIndex(1) sig_frame.ui.cbSignalView.setDisabled(True) self.splitter.insertWidget(self.num_frames, sig_frame) sig_frame.blockSignals(False) default_view = constants.SETTINGS.value('default_view', 0, int) sig_frame.ui.cbProtoView.setCurrentIndex(default_view) return sig_frame def __create_connects_for_signal_frame(self, signal_frame: SignalFrameController): signal_frame.hold_shift = constants.SETTINGS.value('hold_shift_to_drag', False, type=bool) signal_frame.drag_started.connect(self.frame_dragged) signal_frame.frame_dropped.connect(self.frame_dropped) signal_frame.files_dropped.connect(self.on_files_dropped) signal_frame.closed.connect(self.close_frame) def add_empty_frame(self, filename: str, proto): sig_frame = SignalFrameController(proto_analyzer=proto, undo_stack=self.undo_stack, project_manager=self.project_manager, proto_bits=proto.decoded_proto_bits_str, parent=self) sig_frame.ui.lineEditSignalName.setText(filename) sig_frame.setMinimumHeight(sig_frame.height()) sig_frame.set_empty_frame_visibilities() self.__create_connects_for_signal_frame(signal_frame=sig_frame) self.splitter.insertWidget(self.num_frames, sig_frame) return sig_frame def set_frame_numbers(self): for i, f in enumerate(self.signal_frames): f.ui.lSignalNr.setText("{0:d}:".format(i + 1)) @pyqtSlot() def save_all(self): if self.num_frames == 0: return settings = constants.SETTINGS try: not_show = settings.value('not_show_save_dialog', type=bool, defaultValue=False) except TypeError: not_show = False if not not_show: cb = QCheckBox("Don't ask me again.") msg_box = QMessageBox(QMessageBox.Question, self.tr("Confirm saving all signals"), self.tr("All changed signal files will be overwritten. OK?")) msg_box.addButton(QMessageBox.Yes) msg_box.addButton(QMessageBox.No) msg_box.setCheckBox(cb) reply = msg_box.exec() not_show_again = cb.isChecked() settings.setValue("not_show_save_dialog", not_show_again) self.not_show_again_changed.emit() if reply != QMessageBox.Yes: return for f in self.signal_frames: if f.signal is None or f.signal.filename == "": continue f.signal.save() @pyqtSlot() def close_all(self): for f in self.signal_frames: f.my_close() @pyqtSlot(Signal) def on_apply_to_all_clicked(self, signal: Signal): for frame in self.signal_frames: if frame.signal is not None: frame.signal.noise_min_plot = signal.noise_min_plot frame.signal.noise_max_plot = signal.noise_max_plot frame.signal.block_protocol_update = True proto_needs_update = False if frame.signal.modulation_type != signal.modulation_type: frame.signal.modulation_type = signal.modulation_type proto_needs_update = True if frame.signal.qad_center != signal.qad_center: frame.signal.qad_center = signal.qad_center proto_needs_update = True if frame.signal.tolerance != signal.tolerance: frame.signal.tolerance = signal.tolerance proto_needs_update = True if frame.signal.noise_threshold != signal.noise_threshold: frame.signal.noise_threshold = signal.noise_threshold proto_needs_update = True if frame.signal.bit_len != signal.bit_len: frame.signal.bit_len = signal.bit_len proto_needs_update = True frame.signal.block_protocol_update = False if proto_needs_update: frame.signal.protocol_needs_update.emit() @pyqtSlot(QPoint) def frame_dragged(self, pos: QPoint): self.drag_pos = pos @pyqtSlot(QPoint) def frame_dropped(self, pos: QPoint): start = self.drag_pos if start is None: return end = pos start_index = -1 end_index = -1 if self.num_frames > 1: for i, w in enumerate(self.signal_frames): if w.geometry().contains(start): start_index = i if w.geometry().contains(end): end_index = i self.swap_frames(start_index, end_index) self.frame_was_dropped.emit(start_index, end_index) @pyqtSlot(int, int) def swap_frames(self, from_index: int, to_index: int): if from_index != to_index: start_sig_widget = self.splitter.widget(from_index) self.splitter.insertWidget(to_index, start_sig_widget) @pyqtSlot() def on_participant_changed(self): for sframe in self.signal_frames: sframe.on_participant_changed()
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 Listspace(QSplitter, ViewManager): """ Class implementing the listspace viewmanager class. @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @signal lastEditorClosed() emitted after the last editor window was closed @signal editorOpened(str) emitted after an editor window was opened @signal editorOpenedEd(Editor) emitted after an editor window was opened @signal editorClosed(str) emitted just before an editor window gets closed @signal editorClosedEd(Editor) emitted just before an editor window gets closed @signal editorRenamed(str) emitted after an editor was renamed @signal editorRenamedEd(Editor) emitted after an editor was renamed @signal editorSaved(str) emitted after an editor window was saved @signal editorSavedEd(Editor) emitted after an editor window was saved @signal checkActions(Editor) emitted when some actions should be checked for their status @signal cursorChanged(Editor) emitted after the cursor position of the active window has changed @signal breakpointToggled(Editor) emitted when a breakpoint is toggled. @signal bookmarkToggled(Editor) emitted when a bookmark is toggled. @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled. @signal previewStateChanged(bool) emitted to signal a change in the preview state @signal editorLanguageChanged(Editor) emitted to signal a change of an editors language @signal editorTextChanged(Editor) emitted to signal a change of an editor's text @signal editorLineChanged(str,int) emitted to signal a change of an editor's current line (line is given one based) """ changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) lastEditorClosed = pyqtSignal() editorOpened = pyqtSignal(str) editorOpenedEd = pyqtSignal(Editor) editorClosed = pyqtSignal(str) editorClosedEd = pyqtSignal(Editor) editorRenamed = pyqtSignal(str) editorRenamedEd = pyqtSignal(Editor) editorSaved = pyqtSignal(str) editorSavedEd = pyqtSignal(Editor) checkActions = pyqtSignal(Editor) cursorChanged = pyqtSignal(Editor) breakpointToggled = pyqtSignal(Editor) bookmarkToggled = pyqtSignal(Editor) syntaxerrorToggled = pyqtSignal(Editor) previewStateChanged = pyqtSignal(bool) editorLanguageChanged = pyqtSignal(Editor) editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) def __init__(self, parent): """ Constructor @param parent parent widget (QWidget) """ self.stacks = [] QSplitter.__init__(self, parent) ViewManager.__init__(self) self.setChildrenCollapsible(False) self.viewlist = QListWidget(self) policy = self.viewlist.sizePolicy() policy.setHorizontalPolicy(QSizePolicy.Ignored) self.viewlist.setSizePolicy(policy) self.addWidget(self.viewlist) self.viewlist.setContextMenuPolicy(Qt.CustomContextMenu) self.viewlist.currentRowChanged.connect(self.__showSelectedView) self.viewlist.customContextMenuRequested.connect(self.__showMenu) self.stackArea = QSplitter(self) self.stackArea.setChildrenCollapsible(False) self.addWidget(self.stackArea) self.stackArea.setOrientation(Qt.Vertical) stack = StackedWidget(self.stackArea) self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) self.setSizes([int(self.width() * 0.2), int(self.width() * 0.8)]) # 20% for viewlist, 80% for the editors self.__inRemoveView = False self.__initMenu() self.contextMenuEditor = None self.contextMenuIndex = -1 def __initMenu(self): """ Private method to initialize the viewlist context menu. """ self.__menu = QMenu(self) self.__menu.addAction( UI.PixmapCache.getIcon("tabClose.png"), self.tr('Close'), self.__contextMenuClose) self.closeOthersMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("tabCloseOther.png"), self.tr("Close Others"), self.__contextMenuCloseOthers) self.__menu.addAction( self.tr('Close All'), self.__contextMenuCloseAll) self.__menu.addSeparator() self.saveMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("fileSave.png"), self.tr('Save'), self.__contextMenuSave) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAs.png"), self.tr('Save As...'), self.__contextMenuSaveAs) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAll.png"), self.tr('Save All'), self.__contextMenuSaveAll) self.__menu.addSeparator() self.openRejectionsMenuAct = self.__menu.addAction( self.tr("Open 'rejection' file"), self.__contextMenuOpenRejections) self.__menu.addSeparator() self.__menu.addAction( UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__contextMenuPrintFile) self.__menu.addSeparator() self.copyPathAct = self.__menu.addAction( self.tr("Copy Path to Clipboard"), self.__contextMenuCopyPathToClipboard) def __showMenu(self, point): """ Private slot to handle the customContextMenuRequested signal of the viewlist. @param point position to open the menu at (QPoint) """ if self.editors: itm = self.viewlist.itemAt(point) if itm is not None: row = self.viewlist.row(itm) self.contextMenuEditor = self.editors[row] self.contextMenuIndex = row if self.contextMenuEditor: self.saveMenuAct.setEnabled( self.contextMenuEditor.isModified()) fileName = self.contextMenuEditor.getFileName() self.copyPathAct.setEnabled(bool(fileName)) if fileName: rej = "{0}.rej".format(fileName) self.openRejectionsMenuAct.setEnabled( os.path.exists(rej)) else: self.openRejectionsMenuAct.setEnabled(False) self.closeOthersMenuAct.setEnabled( self.viewlist.count() > 1) self.__menu.popup(self.viewlist.mapToGlobal(point)) def canCascade(self): """ Public method to signal if cascading of managed windows is available. @return flag indicating cascading of windows is available """ return False def canTile(self): """ Public method to signal if tiling of managed windows is available. @return flag indicating tiling of windows is available """ return False def canSplit(self): """ public method to signal if splitting of the view is available. @return flag indicating splitting of the view is available. """ return True def tile(self): """ Public method to tile the managed windows. """ pass def cascade(self): """ Public method to cascade the managed windows. """ pass def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). """ self.viewlist.clear() for win in self.editors: for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() def _removeView(self, win): """ Protected method to remove a view (i.e. window). @param win editor window to be removed """ self.__inRemoveView = True ind = self.editors.index(win) itm = self.viewlist.takeItem(ind) if itm: del itm for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() self.__inRemoveView = False if ind > 0: ind -= 1 else: if len(self.editors) > 1: ind = 1 else: return stack.setCurrentWidget(stack.firstEditor()) self._showView(self.editors[ind].parent()) aw = self.activeWindow() fn = aw and aw.getFileName() or None if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) def _addView(self, win, fn=None, noName="", next=False): """ Protected method to add a view (i.e. window). @param win editor assembly to be added @param fn filename of this editor (string) @param noName name to be used for an unnamed editor (string) @param next flag indicating to add the view next to the current view (bool) """ editor = win.getEditor() if fn is None: if not noName: self.untitledCount += 1 noName = self.tr("Untitled {0}").format(self.untitledCount) self.viewlist.addItem(noName) editor.setNoName(noName) else: txt = os.path.basename(fn) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = QListWidgetItem(txt) itm.setToolTip(fn) self.viewlist.addItem(itm) self.currentStack.addWidget(win) self.currentStack.setCurrentWidget(win) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect(self.__cursorLineChanged) index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __captionChange(self, cap, editor): """ Private method to handle caption change signals from the editor. Updates the listwidget text to reflect the new caption information. @param cap Caption for the editor (string) @param editor Editor to update the caption for """ fn = editor.getFileName() if fn: self.setEditorName(editor, fn) def __cursorLineChanged(self, lineno): """ Private slot to handle a change of the current editor's cursor line. @param lineno line number of the current editor's cursor (zero based) """ editor = self.sender() if editor: fn = editor.getFileName() if fn: self.editorLineChanged.emit(fn, lineno + 1) def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). @param win editor assembly to be shown @param fn filename of this editor (string) """ editor = win.getEditor() for stack in self.stacks: if stack.hasEditor(editor): stack.setCurrentWidget(win) self.currentStack = stack break index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __showSelectedView(self, row): """ Private slot called to show a view selected in the list. @param row row number of the item clicked on (integer) """ if row != -1: self._showView(self.editors[row].parent()) self._checkActions(self.editors[row]) def activeWindow(self): """ Public method to return the active (i.e. current) window. @return reference to the active editor """ return self.currentStack.currentWidget() def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. @param windowMenu reference to the window menu """ pass def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. """ pass def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. @param editor editor window to be changed @param newName new name to be shown (string) """ if newName: currentRow = self.viewlist.currentRow() index = self.editors.index(editor) txt = os.path.basename(newName) if not QFileInfo(newName).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = self.viewlist.item(index) itm.setText(txt) itm.setToolTip(newName) self.viewlist.setCurrentRow(currentRow) self.changeCaption.emit(newName) def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. @param m flag indicating the modification status (boolean) @param editor editor window changed """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if m: keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon( UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) self._checkActions(editor) def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. @param editor editor that sent the signal """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if editor.isModified(): keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon( UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) ViewManager._syntaxErrorToggled(self, editor) def addSplit(self): """ Public method used to split the current view. """ stack = StackedWidget(self.stackArea) stack.show() self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) if self.stackArea.orientation() == Qt.Horizontal: size = self.stackArea.width() else: size = self.stackArea.height() self.stackArea.setSizes( [int(size / len(self.stacks))] * len(self.stacks)) self.splitRemoveAct.setEnabled(True) self.nextSplitAct.setEnabled(True) self.prevSplitAct.setEnabled(True) def removeSplit(self): """ Public method used to remove the current split view. @return flag indicating successfull removal """ if len(self.stacks) > 1: stack = self.currentStack res = True savedEditors = stack.editors[:] for editor in savedEditors: res &= self.closeEditor(editor) if res: try: i = self.stacks.index(stack) except ValueError: return True if i == len(self.stacks) - 1: i -= 1 self.stacks.remove(stack) stack.close() self.currentStack = self.stacks[i] if len(self.stacks) == 1: self.splitRemoveAct.setEnabled(False) self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) return True return False def getSplitOrientation(self): """ Public method to get the orientation of the split view. @return orientation of the split (Qt.Horizontal or Qt.Vertical) """ return self.stackArea.orientation() def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. @param orientation orientation of the split (Qt.Horizontal or Qt.Vertical) """ self.stackArea.setOrientation(orientation) def nextSplit(self): """ Public slot used to move to the next split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) + 1 if ind == len(self.stacks): ind = 0 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def prevSplit(self): """ Public slot used to move to the previous split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) - 1 if ind == -1: ind = len(self.stacks) - 1 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def __contextMenuClose(self): """ Private method to close the selected editor. """ if self.contextMenuEditor: self.closeEditorWindow(self.contextMenuEditor) def __contextMenuCloseOthers(self): """ Private method to close the other editors. """ index = self.contextMenuIndex for i in list(range(self.viewlist.count() - 1, index, -1)) + \ list(range(index - 1, -1, -1)): editor = self.editors[i] self.closeEditorWindow(editor) def __contextMenuCloseAll(self): """ Private method to close all editors. """ savedEditors = self.editors[:] for editor in savedEditors: self.closeEditorWindow(editor) def __contextMenuSave(self): """ Private method to save the selected editor. """ if self.contextMenuEditor: self.saveEditorEd(self.contextMenuEditor) def __contextMenuSaveAs(self): """ Private method to save the selected editor to a new file. """ if self.contextMenuEditor: self.saveAsEditorEd(self.contextMenuEditor) def __contextMenuSaveAll(self): """ Private method to save all editors. """ self.saveEditorsList(self.editors) def __contextMenuOpenRejections(self): """ Private slot to open a rejections file associated with the selected editor. """ if self.contextMenuEditor: fileName = self.contextMenuEditor.getFileName() if fileName: rej = "{0}.rej".format(fileName) if os.path.exists(rej): self.openSourceFile(rej) def __contextMenuPrintFile(self): """ Private method to print the selected editor. """ if self.contextMenuEditor: self.printEditor(self.contextMenuEditor) def __contextMenuCopyPathToClipboard(self): """ Private method to copy the file name of the selected editor to the clipboard. """ if self.contextMenuEditor: fn = self.contextMenuEditor.getFileName() if fn: cb = QApplication.clipboard() cb.setText(fn) def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. @param index index of the current editor """ if index == -1 or not self.editors: return editor = self.activeWindow() if editor is None: return self._checkActions(editor) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) if not self.__inRemoveView: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) cindex = self.editors.index(editor) self.viewlist.setCurrentRow(cindex) def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched @param event the event that occurred @return flag indicating, if we handled the event """ if event.type() == QEvent.MouseButtonPress and \ not event.button() == Qt.RightButton: switched = True if isinstance(watched, QStackedWidget): switched = watched is not self.currentStack self.currentStack = watched elif isinstance(watched, QScintilla.Editor.Editor): for stack in self.stacks: if stack.hasEditor(watched): switched = stack is not self.currentStack self.currentStack = stack break currentWidget = self.currentStack.currentWidget() if currentWidget: index = self.editors.index(currentWidget) self.viewlist.setCurrentRow(index) aw = self.activeWindow() if aw is not None: self._checkActions(aw) aw.setFocus() fn = aw.getFileName() if fn: self.changeCaption.emit(fn) if switched: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) return False
class _s_CentralWidget(QWidget): ############################################################################### # CentralWidget SIGNALS ############################################################################### """ splitterCentralRotated() """ splitterCentralRotated = pyqtSignal() ############################################################################### def __init__(self, parent=None): super(_s_CentralWidget, self).__init__(parent) self.parent = parent #This variables are used to save the splitter sizes before hide self._splitterMainSizes = None self._splitterAreaSizes = None self.lateralPanel = None hbox = QHBoxLayout(self) hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) #Create Splitters to divide the UI in: MainPanel, Explorer, Misc self._splitterArea = QSplitter(Qt.Horizontal) self._splitterMain = QSplitter(Qt.Vertical) #Create scrollbar for follow mode self.scrollBar = QScrollBar(Qt.Vertical, self) self.scrollBar.setFixedWidth(20) self.scrollBar.setToolTip('Follow Mode: Scroll the Editors together') self.scrollBar.hide() self.scrollBar.valueChanged[int].connect(self.move_follow_scrolls) #Add to Main Layout hbox.addWidget(self.scrollBar) hbox.addWidget(self._splitterArea) def insert_central_container(self, container): self.mainContainer = container self._splitterMain.insertWidget(0, container) def insert_lateral_container(self, container): self.lateralPanel = LateralPanel(container) self._splitterArea.insertWidget(0, self.lateralPanel) def insert_bottom_container(self, container): self.misc = container self._splitterMain.insertWidget(1, container) def showEvent(self, event): #Show Event QWidget.showEvent(self, event) #Avoid recalculate the panel sizes if they are already loaded if self._splitterArea.count() == 2: return #Rearrange widgets on Window self._splitterArea.insertWidget(0, self._splitterMain) if not event.spontaneous(): self.change_misc_visibility() if bin(settings.UI_LAYOUT)[-1] == '1': self.splitter_central_rotate() if bin(settings.UI_LAYOUT >> 1)[-1] == '1': self.splitter_misc_rotate() if bin(settings.UI_LAYOUT >> 2)[-1] == '1': self.splitter_central_orientation() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant] heightList = list(qsettings.value("window/central/mainSize", [(self.height() / 3) * 2, self.height() / 3])) widthList = list(qsettings.value("window/central/areaSize", [(self.width() / 6) * 5, self.width() / 6])) self._splitterMainSizes = [int(heightList[0]), int(heightList[1])] self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])] #Set the sizes to splitters #self._splitterMain.setSizes(self._splitterMainSizes) self._splitterMain.setSizes(self._splitterMainSizes) self._splitterArea.setSizes(self._splitterAreaSizes) self.misc.setVisible( qsettings.value("window/show_misc", False, type=bool)) def change_misc_visibility(self, on_start=False): if self.misc.isVisible(): self._splitterMainSizes = self._splitterMain.sizes() self.misc.hide() widget = self.mainContainer.get_actual_widget() if widget: widget.setFocus() else: self.misc.show() self.misc.gain_focus() def change_main_visibility(self): if self.mainContainer.isVisible(): self.mainContainer.hide() else: self.mainContainer.show() def change_explorer_visibility(self, force_hide=False): if self.lateralPanel.isVisible() or force_hide: self._splitterAreaSizes = self._splitterArea.sizes() self.lateralPanel.hide() else: self.lateralPanel.show() def splitter_central_rotate(self): w1, w2 = self._splitterArea.widget(0), self._splitterArea.widget(1) self._splitterArea.insertWidget(0, w2) self._splitterArea.insertWidget(1, w1) self.splitterCentralRotated.emit() def splitter_central_orientation(self): if self._splitterArea.orientation() == Qt.Horizontal: self._splitterArea.setOrientation(Qt.Vertical) else: self._splitterArea.setOrientation(Qt.Horizontal) def splitter_misc_rotate(self): w1, w2 = self._splitterMain.widget(0), self._splitterMain.widget(1) self._splitterMain.insertWidget(0, w2) self._splitterMain.insertWidget(1, w1) def splitter_misc_orientation(self): if self._splitterMain.orientation() == Qt.Horizontal: self._splitterMain.setOrientation(Qt.Vertical) else: self._splitterMain.setOrientation(Qt.Horizontal) def get_area_sizes(self): if self.lateralPanel.isVisible(): self._splitterAreaSizes = self._splitterArea.sizes() return self._splitterAreaSizes def get_main_sizes(self): if self.misc.isVisible(): self._splitterMainSizes = self._splitterMain.sizes() return self._splitterMainSizes def enable_follow_mode_scrollbar(self, val): if val: editorWidget = self.mainContainer.get_actual_editor() maxScroll = editorWidget.verticalScrollBar().maximum() position = editorWidget.verticalScrollBar().value() self.scrollBar.setMaximum(maxScroll) self.scrollBar.setValue(position) self.scrollBar.setVisible(val) def move_follow_scrolls(self, val): widget = self.mainContainer._tabMain.currentWidget() diff = widget._sidebarWidget.highest_line - val s1 = self.mainContainer._tabMain.currentWidget().verticalScrollBar() s2 = self.mainContainer._tabSecondary.\ currentWidget().verticalScrollBar() s1.setValue(val) s2.setValue(val + diff)
class Window(QWidget): session = dict() def __init__(self, config): super(Window, self).__init__() self.config = config self.base_uri = QUrl.fromLocalFile(os.path.dirname(__file__)).toString() # initial web view add handle all link and form submitted self.web_view = QWebView(self) self.web_view.setPage(WebPage()) self.web_view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.web_view.page().linkClicked.connect(self.link_clicked) # self.web_view.page().urlChanged.connect(self.url_changed) self.web_view.page().loadFinished.connect(self.load_finished) self.web_view.page().loadStarted.connect(self.load_started) self.web_view.page().form_submitted.connect(self.handle_form_submitted) self.web_view.page().request_reload.connect(self.handle_reload) # initial template lookup self.tempalte_lookup = TemplateLookup( directories=[self.config.settings.get("mako.directories")], module_directory=self.config.settings.get("mako.module_directory"), input_encoding="utf-8", ) # layout attribute layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) # add debug inspector if self.config.settings.get("debug", False): self.setup_inspector() self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) layout.addWidget(self.splitter) self.splitter.addWidget(self.web_view) self.splitter.addWidget(self.web_inspector) else: layout.addWidget(self.web_view) def setup_inspector(self): """ This code from http://agateau.com/2012/02/03/pyqtwebkit-experiments-part-2-debugging/ """ page = self.web_view.page() page.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) self.web_inspector = QWebInspector(self) self.web_inspector.setPage(page) shortcut = QShortcut(self) shortcut.setKey(Qt.Key_F12) shortcut.activated.connect(self.toggle_inspector) self.web_inspector.setVisible(False) def toggle_inspector(self): self.web_inspector.setVisible(not self.web_inspector.isVisible()) def handle_form_submitted(self, qurl, elements=dict()): # print("\n\ngot url: ", qurl) qqurl = QUrlQuery(qurl) for key, value in qqurl.queryItems(): elements[key] = value self.render(qurl.path(), elements) # do stuff with elements... # for item in elements.items(): # print ("got: ", item) def handle_reload(self, qurl): self.render(qurl.path()) def load_started(self): """""" # print("load_started ->: ", self.web_view.url()) def load_finished(self, finished): """""" # print("load_finished ->: ", finished) # if finished: # self.web_view.setUrl(QUrl('/login')) # def url_changed(self, qurl): # '''''' # print("url_changed ->: ", qurl) def link_clicked(self, qurl): # print("link_clicked ->: ", qurl) qqurl = QUrlQuery(qurl) elements = {} # print("got link_clicked url: ", qurl) for key, value in qqurl.queryItems(): elements[key] = value self.render(qurl.path(), elements) # self.render(qurl.path()) def render(self, url, args=None): self.config.current_route_path = url print("current_route_path: ", self.config.current_route_path) logger.debug("url: %s" % url) route = self.config.get_route(url) logger.debug("view: %s" % route) if route is not None: view = route.get("view") context_obj = context.ResourceContext(self.config, self.session) context_obj.add_args(args) try: response = view(context_obj) except Exception as e: if e.args[0] == "Request Exit": self.close() return logger.exception(e) # need error page return self.link_clicked("/home") if not isinstance(response, dict): if isinstance(response, QUrl): return self.link_clicked(response) # url = response.path() # print('window url', url) # return self.render(url) # else: # # need error page # return self.render('/login') logger.debug("response: %s" % response) template = self.tempalte_lookup.get_template(self.config.get_route(url).get("renderer")) response["request"] = context_obj response["base_uri"] = self.base_uri html = template.render(**response) self.web_view.setHtml(html, QUrl("file://" + url)) # self.web_view.setHtml(html) # self.web_view.load(a) def welcome(self): context_obj = context.ResourceContext(self.config, self.session) return self.link_clicked(context_obj.redirect_url("login"))
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 ConfigurationWidget(QWidget): """ Class implementing a dialog for the configuration of eric6. @signal preferencesChanged() emitted after settings have been changed @signal masterPasswordChanged(str, str) emitted after the master password has been changed with the old and the new password @signal accepted() emitted to indicate acceptance of the changes @signal rejected() emitted to indicate rejection of the changes """ preferencesChanged = pyqtSignal() masterPasswordChanged = pyqtSignal(str, str) accepted = pyqtSignal() rejected = pyqtSignal() DefaultMode = 0 HelpBrowserMode = 1 TrayStarterMode = 2 HexEditorMode = 3 def __init__(self, parent=None, fromEric=True, displayMode=DefaultMode, expandedEntries=[]): """ Constructor @param parent The parent widget of this dialog. (QWidget) @keyparam fromEric flag indicating a dialog generation from within the eric6 ide (boolean) @keyparam displayMode mode of the configuration dialog (DefaultMode, HelpBrowserMode, TrayStarterMode, HexEditorMode) @exception RuntimeError raised to indicate an invalid dialog mode @keyparam expandedEntries list of entries to be shown expanded (list of strings) """ assert displayMode in ( ConfigurationWidget.DefaultMode, ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode, ConfigurationWidget.HexEditorMode, ) super(ConfigurationWidget, self).__init__(parent) self.fromEric = fromEric self.displayMode = displayMode self.__setupUi() self.itmDict = {} if not fromEric: from PluginManager.PluginManager import PluginManager try: self.pluginManager = e5App().getObject("PluginManager") except KeyError: self.pluginManager = PluginManager(self) e5App().registerObject("PluginManager", self.pluginManager) if displayMode == ConfigurationWidget.DefaultMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "applicationPage": [self.tr("Application"), "preferences-application.png", "ApplicationPage", None, None], "cooperationPage": [self.tr("Cooperation"), "preferences-cooperation.png", "CooperationPage", None, None], "corbaPage": [self.tr("CORBA"), "preferences-orbit.png", "CorbaPage", None, None], "emailPage": [self.tr("Email"), "preferences-mail_generic.png", "EmailPage", None, None], "graphicsPage": [self.tr("Graphics"), "preferences-graphics.png", "GraphicsPage", None, None], "hexEditorPage": [self.tr("Hex Editor"), "hexEditor.png", "HexEditorPage", None, None], "iconsPage": [self.tr("Icons"), "preferences-icons.png", "IconsPage", None, None], "ircPage": [self.tr("IRC"), "irc.png", "IrcPage", None, None], "logViewerPage": [self.tr("Log-Viewer"), "preferences-logviewer.png", "LogViewerPage", None, None], "mimeTypesPage": [self.tr("Mimetypes"), "preferences-mimetypes.png", "MimeTypesPage", None, None], "networkPage": [self.tr("Network"), "preferences-network.png", "NetworkPage", None, None], "notificationsPage": [self.tr("Notifications"), "preferences-notifications.png", "NotificationsPage", None, None], "pluginManagerPage": [self.tr("Plugin Manager"), "preferences-pluginmanager.png", "PluginManagerPage", None, None], "printerPage": [self.tr("Printer"), "preferences-printer.png", "PrinterPage", None, None], "pythonPage": [self.tr("Python"), "preferences-python.png", "PythonPage", None, None], "qtPage": [self.tr("Qt"), "preferences-qtlogo.png", "QtPage", None, None], "securityPage": [self.tr("Security"), "preferences-security.png", "SecurityPage", None, None], "shellPage": [self.tr("Shell"), "preferences-shell.png", "ShellPage", None, None], "tasksPage": [self.tr("Tasks"), "task.png", "TasksPage", None, None], "templatesPage": [self.tr("Templates"), "preferences-template.png", "TemplatesPage", None, None], "trayStarterPage": [self.tr("Tray Starter"), "erict.png", "TrayStarterPage", None, None], "vcsPage": [self.tr("Version Control Systems"), "preferences-vcs.png", "VcsPage", None, None], "0debuggerPage": [self.tr("Debugger"), "preferences-debugger.png", None, None, None], "debuggerGeneralPage": [self.tr("General"), "preferences-debugger.png", "DebuggerGeneralPage", "0debuggerPage", None], "debuggerPythonPage": [self.tr("Python"), "preferences-pyDebugger.png", "DebuggerPythonPage", "0debuggerPage", None], "debuggerPython3Page": [self.tr("Python3"), "preferences-pyDebugger.png", "DebuggerPython3Page", "0debuggerPage", None], "0editorPage": [self.tr("Editor"), "preferences-editor.png", None, None, None], "editorAPIsPage": [self.tr("APIs"), "preferences-api.png", "EditorAPIsPage", "0editorPage", None], "editorAutocompletionPage": [self.tr("Autocompletion"), "preferences-autocompletion.png", "EditorAutocompletionPage", "0editorPage", None], "editorAutocompletionQScintillaPage": [self.tr("QScintilla"), "qscintilla.png", "EditorAutocompletionQScintillaPage", "editorAutocompletionPage", None], "editorCalltipsPage": [self.tr("Calltips"), "preferences-calltips.png", "EditorCalltipsPage", "0editorPage", None], "editorCalltipsQScintillaPage": [self.tr("QScintilla"), "qscintilla.png", "EditorCalltipsQScintillaPage", "editorCalltipsPage", None], "editorGeneralPage": [self.tr("General"), "preferences-general.png", "EditorGeneralPage", "0editorPage", None], "editorFilePage": [self.tr("Filehandling"), "preferences-filehandling.png", "EditorFilePage", "0editorPage", None], "editorSearchPage": [self.tr("Searching"), "preferences-search.png", "EditorSearchPage", "0editorPage", None], "editorSpellCheckingPage": [self.tr("Spell checking"), "preferences-spellchecking.png", "EditorSpellCheckingPage", "0editorPage", None], "editorStylesPage": [self.tr("Style"), "preferences-styles.png", "EditorStylesPage", "0editorPage", None], "editorSyntaxPage": [self.tr("Code Checkers"), "preferences-debugger.png", "EditorSyntaxPage", "0editorPage", None], "editorTypingPage": [self.tr("Typing"), "preferences-typing.png", "EditorTypingPage", "0editorPage", None], "editorExportersPage": [self.tr("Exporters"), "preferences-exporters.png", "EditorExportersPage", "0editorPage", None], "1editorLexerPage": [self.tr("Highlighters"), "preferences-highlighting-styles.png", None, "0editorPage", None], "editorHighlightersPage": [self.tr("Filetype Associations"), "preferences-highlighter-association.png", "EditorHighlightersPage", "1editorLexerPage", None], "editorHighlightingStylesPage": [self.tr("Styles"), "preferences-highlighting-styles.png", "EditorHighlightingStylesPage", "1editorLexerPage", None], "editorKeywordsPage": [self.tr("Keywords"), "preferences-keywords.png", "EditorKeywordsPage", "1editorLexerPage", None], "editorPropertiesPage": [self.tr("Properties"), "preferences-properties.png", "EditorPropertiesPage", "1editorLexerPage", None], "1editorMouseClickHandlers": [self.tr("Mouse Click Handlers"), "preferences-mouse-click-handler.png", "EditorMouseClickHandlerPage", "0editorPage", None], "0helpPage": [self.tr("Help"), "preferences-help.png", None, None, None], "helpDocumentationPage": [self.tr("Help Documentation"), "preferences-helpdocumentation.png", "HelpDocumentationPage", "0helpPage", None], "helpViewersPage": [self.tr("Help Viewers"), "preferences-helpviewers.png", "HelpViewersPage", "0helpPage", None], "0projectPage": [self.tr("Project"), "preferences-project.png", None, None, None], "projectBrowserPage": [self.tr("Project Viewer"), "preferences-project.png", "ProjectBrowserPage", "0projectPage", None], "projectPage": [self.tr("Project"), "preferences-project.png", "ProjectPage", "0projectPage", None], "multiProjectPage": [self.tr("Multiproject"), "preferences-multiproject.png", "MultiProjectPage", "0projectPage", None], "0interfacePage": [self.tr("Interface"), "preferences-interface.png", None, None, None], "interfacePage": [self.tr("Interface"), "preferences-interface.png", "InterfacePage", "0interfacePage", None], "viewmanagerPage": [self.tr("Viewmanager"), "preferences-viewmanager.png", "ViewmanagerPage", "0interfacePage", None], } try: from PyQt5 import QtWebKit # __IGNORE_WARNING__ self.configItems.update({ "helpAppearancePage": [self.tr("Appearance"), "preferences-styles.png", "HelpAppearancePage", "0helpPage", None], "helpFlashCookieManagerPage": [self.tr("Flash Cookie Manager"), "flashCookie16.png", "HelpFlashCookieManagerPage", "0helpPage", None], "helpVirusTotalPage": [self.tr("VirusTotal Interface"), "virustotal.png", "HelpVirusTotalPage", "0helpPage", None], "helpWebBrowserPage": [self.tr("eric6 Web Browser"), "ericWeb.png", "HelpWebBrowserPage", "0helpPage", None], }) except ImportError: pass self.configItems.update( e5App().getObject("PluginManager").getPluginConfigData()) elif displayMode == ConfigurationWidget.HelpBrowserMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "interfacePage": [self.tr("Interface"), "preferences-interface.png", "HelpInterfacePage", None, None], "networkPage": [self.tr("Network"), "preferences-network.png", "NetworkPage", None, None], "printerPage": [self.tr("Printer"), "preferences-printer.png", "PrinterPage", None, None], "securityPage": [self.tr("Security"), "preferences-security.png", "SecurityPage", None, None], "0helpPage": [self.tr("Help"), "preferences-help.png", None, None, None], "helpDocumentationPage": [self.tr("Help Documentation"), "preferences-helpdocumentation.png", "HelpDocumentationPage", "0helpPage", None], } try: from PyQt5 import QtWebKit # __IGNORE_WARNING__ self.configItems.update({ "helpAppearancePage": [self.tr("Appearance"), "preferences-styles.png", "HelpAppearancePage", "0helpPage", None], "helpFlashCookieManagerPage": [self.tr("Flash Cookie Manager"), "flashCookie16.png", "HelpFlashCookieManagerPage", "0helpPage", None], "helpVirusTotalPage": [self.tr("VirusTotal Interface"), "virustotal.png", "HelpVirusTotalPage", "0helpPage", None], "helpWebBrowserPage": [self.tr("eric6 Web Browser"), "ericWeb.png", "HelpWebBrowserPage", "0helpPage", None], }) except ImportError: pass elif displayMode == ConfigurationWidget.TrayStarterMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "trayStarterPage": [self.tr("Tray Starter"), "erict.png", "TrayStarterPage", None, None], } elif displayMode == ConfigurationWidget.HexEditorMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "hexEditorPage": [self.tr("Hex Editor"), "hexEditor.png", "HexEditorPage", None, None], } else: raise RuntimeError("Illegal mode value: {0}".format(displayMode)) # generate the list entries self.__expandedEntries = [] for key in sorted(self.configItems.keys()): pageData = self.configItems[key] if pageData[3]: if pageData[3] in self.itmDict: pitm = self.itmDict[pageData[3]] # get the parent item else: continue else: pitm = self.configList self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key, pageData[1]) self.itmDict[key].setData(0, Qt.UserRole, key) if (not self.fromEric or displayMode != ConfigurationWidget.DefaultMode or key in expandedEntries): self.itmDict[key].setExpanded(True) self.configList.sortByColumn(0, Qt.AscendingOrder) # set the initial size of the splitter self.configSplitter.setSizes([200, 600]) self.configList.itemActivated.connect(self.__showConfigurationPage) self.configList.itemClicked.connect(self.__showConfigurationPage) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.rejected) if displayMode in [ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode, ConfigurationWidget.HexEditorMode]: self.configListSearch.hide() if displayMode not in [ConfigurationWidget.TrayStarterMode, ConfigurationWidget.HexEditorMode]: self.__initLexers() def accept(self): """ Public slot to accept the buttonBox accept signal. """ if not isMacPlatform(): wdg = self.focusWidget() if wdg == self.configList: return self.accepted.emit() def __setupUi(self): """ Private method to perform the general setup of the configuration widget. """ self.setObjectName("ConfigurationDialog") self.resize(900, 650) self.verticalLayout_2 = QVBoxLayout(self) self.verticalLayout_2.setSpacing(6) self.verticalLayout_2.setContentsMargins(6, 6, 6, 6) self.verticalLayout_2.setObjectName("verticalLayout_2") self.configSplitter = QSplitter(self) self.configSplitter.setOrientation(Qt.Horizontal) self.configSplitter.setObjectName("configSplitter") self.configListWidget = QWidget(self.configSplitter) self.leftVBoxLayout = QVBoxLayout(self.configListWidget) self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0) self.leftVBoxLayout.setSpacing(0) self.leftVBoxLayout.setObjectName("leftVBoxLayout") self.configListSearch = E5ClearableLineEdit( self, self.tr("Enter search text...")) self.configListSearch.setObjectName("configListSearch") self.leftVBoxLayout.addWidget(self.configListSearch) self.configList = QTreeWidget() self.configList.setObjectName("configList") self.leftVBoxLayout.addWidget(self.configList) self.configListSearch.textChanged.connect(self.__searchTextChanged) self.scrollArea = QScrollArea(self.configSplitter) self.scrollArea.setFrameShape(QFrame.NoFrame) self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scrollArea.setWidgetResizable(False) self.scrollArea.setObjectName("scrollArea") self.configStack = QStackedWidget() self.configStack.setFrameShape(QFrame.Box) self.configStack.setFrameShadow(QFrame.Sunken) self.configStack.setObjectName("configStack") self.scrollArea.setWidget(self.configStack) self.emptyPage = QWidget() self.emptyPage.setGeometry(QRect(0, 0, 372, 591)) self.emptyPage.setObjectName("emptyPage") self.vboxlayout = QVBoxLayout(self.emptyPage) self.vboxlayout.setSpacing(6) self.vboxlayout.setContentsMargins(6, 6, 6, 6) self.vboxlayout.setObjectName("vboxlayout") spacerItem = QSpacerItem( 20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem) self.emptyPagePixmap = QLabel(self.emptyPage) self.emptyPagePixmap.setAlignment(Qt.AlignCenter) self.emptyPagePixmap.setObjectName("emptyPagePixmap") self.emptyPagePixmap.setPixmap( QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png'))) self.vboxlayout.addWidget(self.emptyPagePixmap) self.textLabel1 = QLabel(self.emptyPage) self.textLabel1.setAlignment(Qt.AlignCenter) self.textLabel1.setObjectName("textLabel1") self.vboxlayout.addWidget(self.textLabel1) spacerItem1 = QSpacerItem( 20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem1) self.configStack.addWidget(self.emptyPage) self.verticalLayout_2.addWidget(self.configSplitter) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.Apply | QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Reset) self.buttonBox.setObjectName("buttonBox") if not self.fromEric and \ self.displayMode == ConfigurationWidget.DefaultMode: self.buttonBox.button(QDialogButtonBox.Apply).hide() self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False) self.verticalLayout_2.addWidget(self.buttonBox) self.setWindowTitle(self.tr("Preferences")) self.configList.header().hide() self.configList.header().setSortIndicator(0, Qt.AscendingOrder) self.configList.setSortingEnabled(True) self.textLabel1.setText( self.tr("Please select an entry of the list \n" "to display the configuration page.")) QMetaObject.connectSlotsByName(self) self.setTabOrder(self.configList, self.configStack) self.configStack.setCurrentWidget(self.emptyPage) self.configList.setFocus() def __searchTextChanged(self, text): """ Private slot to handle a change of the search text. @param text text to search for (string) """ self.__searchChildItems(self.configList.invisibleRootItem(), text) def __searchChildItems(self, parent, text): """ Private method to enable child items based on a search string. @param parent reference to the parent item (QTreeWidgetItem) @param text text to search for (string) @return flag indicating an enabled child item (boolean) """ childEnabled = False text = text.lower() for index in range(parent.childCount()): itm = parent.child(index) if itm.childCount() > 0: enable = self.__searchChildItems(itm, text) or \ text == "" or text in itm.text(0).lower() else: enable = text == "" or text in itm.text(0).lower() if enable: childEnabled = True itm.setDisabled(not enable) return childEnabled def __initLexers(self): """ Private method to initialize the dictionary of preferences lexers. """ import QScintilla.Lexers from .PreferencesLexer import PreferencesLexer, \ PreferencesLexerLanguageError self.lexers = {} for language in QScintilla.Lexers.getSupportedLanguages(): if language not in self.lexers: try: self.lexers[language] = PreferencesLexer(language, self) except PreferencesLexerLanguageError: pass def __importConfigurationPage(self, name): """ Private method to import a configuration page module. @param name name of the configuration page module (string) @return reference to the configuration page module """ modName = "Preferences.ConfigurationPages.{0}".format(name) try: mod = __import__(modName) components = modName.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod except ImportError: E5MessageBox.critical( self, self.tr("Configuration Page Error"), self.tr("""<p>The configuration page <b>{0}</b>""" """ could not be loaded.</p>""").format(name)) return None def __showConfigurationPage(self, itm, column): """ Private slot to show a selected configuration page. @param itm reference to the selected item (QTreeWidgetItem) @param column column that was selected (integer) (ignored) """ pageName = itm.getPageName() self.showConfigurationPageByName(pageName, setCurrent=False) def __initPage(self, pageData): """ Private method to initialize a configuration page. @param pageData data structure for the page to initialize @return reference to the initialized page """ page = None if isinstance(pageData[2], types.FunctionType): page = pageData[2](self) else: mod = self.__importConfigurationPage(pageData[2]) if mod: page = mod.create(self) if page is not None: self.configStack.addWidget(page) pageData[-1] = page try: page.setMode(self.displayMode) except AttributeError: pass return page def showConfigurationPageByName(self, pageName, setCurrent=True): """ Public slot to show a named configuration page. @param pageName name of the configuration page to show (string) @param setCurrent flag indicating to set the current item (boolean) """ if pageName == "empty" or pageName not in self.configItems: page = self.emptyPage else: pageData = self.configItems[pageName] if pageData[-1] is None and pageData[2] is not None: # the page was not loaded yet, create it page = self.__initPage(pageData) else: page = pageData[-1] if page is None: page = self.emptyPage elif setCurrent: items = self.configList.findItems( pageData[0], Qt.MatchFixedString | Qt.MatchRecursive) for item in items: if item.data(0, Qt.UserRole) == pageName: self.configList.setCurrentItem(item) self.configStack.setCurrentWidget(page) ssize = self.scrollArea.size() if self.scrollArea.horizontalScrollBar(): ssize.setHeight( ssize.height() - self.scrollArea.horizontalScrollBar().height() - 2) if self.scrollArea.verticalScrollBar(): ssize.setWidth( ssize.width() - self.scrollArea.verticalScrollBar().width() - 2) psize = page.minimumSizeHint() self.configStack.resize(max(ssize.width(), psize.width()), max(ssize.height(), psize.height())) if page != self.emptyPage: page.polishPage() self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True) else: self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False) # reset scrollbars for sb in [self.scrollArea.horizontalScrollBar(), self.scrollArea.verticalScrollBar()]: if sb: sb.setValue(0) self.__currentConfigurationPageName = pageName def getConfigurationPageName(self): """ Public method to get the page name of the current page. @return page name of the current page (string) """ return self.__currentConfigurationPageName def calledFromEric(self): """ Public method to check, if invoked from within eric. @return flag indicating invocation from within eric (boolean) """ return self.fromEric def getPage(self, pageName): """ Public method to get a reference to the named page. @param pageName name of the configuration page (string) @return reference to the page or None, indicating page was not loaded yet """ return self.configItems[pageName][-1] def getLexers(self): """ Public method to get a reference to the lexers dictionary. @return reference to the lexers dictionary """ return self.lexers def setPreferences(self): """ Public method called to store the selected values into the preferences storage. """ for key, pageData in list(self.configItems.items()): if pageData[-1]: pageData[-1].save() # page was loaded (and possibly modified) QApplication.processEvents() # ensure HMI is responsive def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Apply): self.on_applyButton_clicked() elif button == self.buttonBox.button(QDialogButtonBox.Reset): self.on_resetButton_clicked() @pyqtSlot() def on_applyButton_clicked(self): """ Private slot called to apply the settings of the current page. """ if self.configStack.currentWidget() != self.emptyPage: page = self.configStack.currentWidget() savedState = page.saveState() page.save() self.preferencesChanged.emit() if savedState is not None: page.setState(savedState) page.polishPage() @pyqtSlot() def on_resetButton_clicked(self): """ Private slot called to reset the settings of the current page. """ if self.configStack.currentWidget() != self.emptyPage: currentPage = self.configStack.currentWidget() savedState = currentPage.saveState() pageName = self.configList.currentItem().getPageName() self.configStack.removeWidget(currentPage) if pageName == "editorHighlightingStylesPage": self.__initLexers() self.configItems[pageName][-1] = None self.showConfigurationPageByName(pageName) if savedState is not None: self.configStack.currentWidget().setState(savedState) def getExpandedEntries(self): """ Public method to get a list of expanded entries. @return list of expanded entries (list of string) """ return self.__expandedEntries @pyqtSlot(QTreeWidgetItem) def on_configList_itemCollapsed(self, item): """ Private slot handling a list entry being collapsed. @param item reference to the collapsed item (QTreeWidgetItem) """ pageName = item.data(0, Qt.UserRole) if pageName in self.__expandedEntries: self.__expandedEntries.remove(pageName) @pyqtSlot(QTreeWidgetItem) def on_configList_itemExpanded(self, item): """ Private slot handling a list entry being expanded. @param item reference to the expanded item (QTreeWidgetItem) """ pageName = item.data(0, Qt.UserRole) if pageName not in self.__expandedEntries: self.__expandedEntries.append(pageName)