def __init__(self, session, ui_area): from PyQt5.QtWidgets import QBoxLayout self.session = session from chimerax.core.commands import run from .options import CategorizedSettingsPanel self.options_widget = CategorizedSettingsPanel(help_cb=lambda *, category=None, ses=session, run=run: run(ses, "help help:user/preferences.html" + ("" if category is None else "#" + category.replace(' ', '').lower()))) self.options = {} for setting, setting_info in self.settings_info.items(): opt_name, category, opt_class, updater, converter, balloon, set_setting = setting_info if isinstance(opt_class, tuple): opt_class, kw = opt_class if 'session' in kw: kw['session'] = self.session else: kw = {} opt = opt_class(opt_name, getattr(core_settings, setting), self._opt_cb, attr_name=setting, settings=core_settings, balloon=balloon, auto_set_attr=set_setting, **kw) self.options_widget.add_option(category, opt) self.options[setting] = opt core_settings.triggers.add_handler('setting changed', self._core_setting_changed) layout = QBoxLayout(QBoxLayout.TopToBottom) layout.setSpacing(5) layout.addWidget(self.options_widget, 1) layout.setContentsMargins(0, 0, 0, 0) ui_area.setLayout(layout)
def createLayout(self, orientation, widget): layout = QBoxLayout(QBoxLayout.LeftToRight, widget) if (orientation == Qt.Vertical): layout.setDirection(QBoxLayout.TopToBottom) layout.setSpacing(20) layout.setContentsMargins(0, 0, 0, 0) return layout
def __init__(self): super(FlowBoardEditorToolBar, self).__init__() self.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)) boardbox = QBoxLayout(QBoxLayout.TopToBottom) boardbox.setSpacing(2) self._sizelist = QComboBox() for s in range(5, 16): self._sizelist.addItem("{0}x{0}".format(s), s) self._sizelist.setCurrentIndex(2) boardbox.addWidget(self._sizelist) self._sizelist.currentIndexChanged.connect(self._sizelistChanged) self._clearbutton = QPushButton("clear") boardbox.addWidget(self._clearbutton) self._clearbutton.clicked.connect(self._clearClicked) boardboxwidget = QWidget() boardboxwidget.setLayout(boardbox) self.addWidget(boardboxwidget) self._toolchooser = FlowToolChooser() self.addWidget(self._toolchooser) self._toolchooser.changed.connect(self._toolChanged)
def __init__(self, parent=None): super(FlowSolvingPopup, self).__init__(parent) layout = QBoxLayout(QBoxLayout.TopToBottom) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self._solverWidget = FlowSolverWidget() self._solverWidget.finished.connect(self._solverFinished) layout.addWidget(self._solverWidget) status = QStatusBar() status.setSizeGripEnabled(False) self._againButton = QPushButton("next") self._againButton.setVisible(False) self._againButton.clicked.connect(self._againClicked) status.addPermanentWidget(self._againButton) self._abortButton = QPushButton("close") self._abortButton.clicked.connect(self._abortClicked) status.addPermanentWidget(self._abortButton) self._messageLabel = QLabel("ready") status.addWidget(self._messageLabel) layout.addWidget(status) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self._timer = QTimer() self._timer.timeout.connect(self._timerTick)
def __init__(self, viewport): super().__init__() self.viewport = viewport self.moduleName = "QViewportHeader" self.setContentsMargins(0, 0, 0, 0) boxLayout = QBoxLayout(QBoxLayout.LeftToRight) boxLayout.setContentsMargins(0, 0, 0, 0) boxLayout.setSpacing(0) self.setLayout(boxLayout) titleBtn = QToolButton() titleBtn.setAutoRaise(True) titleBtn.setToolButtonStyle(Qt.ToolButtonTextOnly) titleBtn.setPopupMode(QToolButton.InstantPopup) self.titleBtn = titleBtn pivotSnapping = QToolButton() pivotSnapping.setToolTip("Pivot Snapping") pivotSnapping.setAutoRaise(True) pivotSnapping.setCheckable(True) self.pivotSnapping = pivotSnapping boxLayout.addWidget(titleBtn, 1) boxLayout.addStretch(1)
class MainWidget(QWidget): def __init__(self, urls, toggle_sequence): super(MainWidget, self).__init__() self._connection = connection.Connection(self.set_captive_portal_url) self._captive_portal_url = '' self._urls = cycle(urls) self._current_url = next(self._urls) self._browser_widget = browser_widget.BrowserWidget(self._current_url) self._is_captive_portal_visible = False self._captive_portal_message = captive_portal_message.CaptivePortalMessage( self._toggle_captive_portal) self._layout = QBoxLayout(QBoxLayout.BottomToTop) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self._layout.addWidget(self._browser_widget) QShortcut(toggle_sequence, self).activated.connect(self._load_next_url) self.setLayout(self._layout) self.show() self._connection.start_daemon() def set_captive_portal_url(self, url): self._captive_portal_url = url if url == '' and not self._is_captive_portal_visible: self._captive_portal_message.setParent(None) else: self._update_captive_portal_message() self._layout.addWidget(self._captive_portal_message) # Private def _load_next_url(self): if self._is_captive_portal_visible: self._browser_widget.load(self._current_url) self._is_captive_portal_visible = False self._update_captive_portal_message() else: self._current_url = next(self._urls) self._browser_widget.load(self._current_url) def _toggle_captive_portal(self): if self._is_captive_portal_visible: if not self._connection.is_captive(): self._captive_portal_message.setParent(None) self._browser_widget.load(self._current_url) else: self._browser_widget.load(QUrl(self._captive_portal_url)) self._is_captive_portal_visible = not self._is_captive_portal_visible self._update_captive_portal_message() def _update_captive_portal_message(self): if self._is_captive_portal_visible: self._captive_portal_message.setCloseMessage( self._connection.is_captive()) else: self._captive_portal_message.setOpenMessage()
def styleHelper(self): layout = QBoxLayout(QBoxLayout.LeftToRight) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) for item in TOOL_ICONS.items(): _name, _attr = item self.items[_name] = ToolBarIcon(self, item) layout.addWidget(self.items[_name], 0, Qt.AlignJustify) pass self.setLayout(layout) # self.setFixedSize(*CFG.SIZE_TOPBAR_MAIN()) self.setVisible(False) self.setStyleSheet(CFG.STYLESHEET(self)) pass
class InputArea(QFrame): def __init__(self, name, field): QFrame.__init__(self) self.setObjectName('input_area') self.layout = QBoxLayout(QBoxLayout.LeftToRight) self.layout.setSpacing(0) #self.layout.setMargin(5) self.label = QLabel(name) self.label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.label.setObjectName('input_label') self.field = field self.field.setObjectName('input_field') self.layout.addWidget(self.label) self.layout.addWidget(self.field) self.setLayout(self.layout)
def __init__(self): super(FlowSolverAppWindow, self).__init__() self.setWindowTitle("flow solver") self.setAcceptDrops(True) # toolbars can be hidden/toggled by some kind of default context menu. # this seems to be the only way to make them un-hide-able. self.setContextMenuPolicy(Qt.NoContextMenu) self._editor = FlowBoardEditor() self._editor.toolbar.setFloatable(False) self._editor.toolbar.setMovable(False) self._editor.boardChanged.connect(self._boardChanged) self.addToolBar(self._editor.toolbar) editorcontainer = QSquareWidgetContainer() editorcontainer.setMargin(20) editorcontainer.setWidget(self._editor) editorcontainer.setBackgroundColor(QColor(0, 0, 0)) self.setCentralWidget(editorcontainer) tb = self.addToolBar("solve") tb.setFloatable(False) tb.setMovable(False) self._solveButton = QPushButton("solve") self._solveButton.clicked.connect(self._solveClicked) self._solveButton.setEnabled(self._editor.boardIsValid) actionbox = QBoxLayout(QBoxLayout.TopToBottom) actionbox.setSpacing(2) actionbox.addWidget(self._solveButton) actionswidget = QWidget() actionswidget.setLayout(actionbox) tb.addWidget(actionswidget) mb = QMenuBar() filemenu = mb.addMenu("File") filemenu.addAction("Open").triggered.connect(self._openClicked) filemenu.addAction("Save As").triggered.connect(self._saveClicked) self.setMenuBar(mb) self._solvepopup = FlowSolvingPopup(self) self._solvepopup.setModal(True)
def only_(self): self.lala = QLabel(self) self.lala.setText("Welcome") self.lala.setAlignment(Qt.AlignCenter) self.lala.setFont(QFont("Times", 25, QFont.Bold)) self.redbull = QPushButton('Sign-In', self) self.bluebull = QPushButton('Sign-Up', self) asasasas = QBoxLayout(QBoxLayout.TopToBottom) asasasas.addWidget(self.lala) boxeraa = QBoxLayout(QBoxLayout.LeftToRight) boxeraa.stretch(1) boxeraa.setSpacing(1) asasasas.addWidget(self.bull) boxeraa.addWidget(self.redbull) boxeraa.addWidget(self.bluebull) asasasas.addLayout(boxeraa) self.dummy.setLayout(asasasas)
def install_layout_for_widget(widget, orientation=None, margins=None, spacing=None): """ Installs a layout to widget, if it does not have it already. :param widget: target widget :param orientation: Qt.Vertical (default) / Qt.Horizontal :param margins: layout margins = (11, 11, 11, 11) from Qt docs, style dependent :param spacing: spacing between items in layout :return: None """ if widget.layout() is not None: logger.debug('Widget {0} already has a layout, skipping'.format(widget.windowTitle())) return # already has a layout direction = QBoxLayout.TopToBottom if orientation == Qt.Horizontal: direction = QBoxLayout.LeftToRight l = QBoxLayout(direction) if margins is not None: l.setContentsMargins(margins[0], margins[1], margins[2], margins[3]) if spacing is not None: l.setSpacing(spacing) widget.setLayout(l)
def orange(self): try: d = 'ss' #self.setStyleSheet("QPushButton { margin: 10px,4ex; }") self.label1 = QLabel(self) self.label1.setText("Welcome") self.label1.setAlignment(Qt.AlignCenter) self.label1.setFont(QFont("Times", 25, QFont.Bold)) self.label2 = QLabel(self) self.label2.setText(" Login") self.label2.setAlignment(Qt.AlignRight) self.label2.setFont(QFont("Times", 10, QFont.Bold)) self.log = QLabel(self) self.log.setText("**Enter your credentials to login") self.log.setAlignment(Qt.AlignLeft) self.log.setFont(QFont("Times", 10, QFont.Bold)) self.bel2 = QLabel(self) self.bel2.setText("Username ") self.bel2.setAlignment(Qt.AlignLeft) self.bel2.setFont(QFont("Times", 10, QFont.Bold)) self.bel3 = QLabel(self) self.bel3.setText("Password ") self.bel3.setAlignment(Qt.AlignCenter) self.bel3.setFont(QFont("Times", 10, QFont.Bold)) self.entry1 = QLineEdit(self) self.entry1.setText("Username") self.entry1.setAlignment(Qt.AlignCenter) self.entry2 = QLineEdit(self) self.entry2.setText("Passwor") self.entry2.setAlignment(Qt.AlignCenter) self.entry2.setEchoMode(QLineEdit.Password) self.try1 = QLineEdit(self) self.try1.setText("Roll Number") self.try1.setAlignment(Qt.AlignCenter) self.rol_1 = QLabel(self) self.rol_1.setText("Roll Number ") self.rol_1.setAlignment(Qt.AlignLeft) self.rol_1.setFont(QFont("Times", 9.8, QFont.Bold)) self.button = QPushButton('Sign-In', self) self.button.setToolTip('Click here if you are an existing user') self.button.clicked.connect(lambda: self.on_signin()) self.button3 = QPushButton('Forgot Password', self) self.button3.setToolTip( "Click here if you don't remember your password") self.button3.clicked.connect(self.on_forget) self.button22 = QPushButton('Reset', self) self.button22.setToolTip('Click here To Reset Form') self.c = str('logclear') self.button22.clicked.connect(lambda: self.on_reset1(self.c)) lay1 = QBoxLayout(QBoxLayout.LeftToRight) lay2 = QBoxLayout(QBoxLayout.LeftToRight) lay3 = QBoxLayout(QBoxLayout.LeftToRight) lay4 = QBoxLayout(QBoxLayout.LeftToRight) lay5 = QBoxLayout(QBoxLayout.LeftToRight) lay6 = QBoxLayout(QBoxLayout.LeftToRight) lay1.addWidget(self.label1) lay2.addWidget(self.label2) lay2.addWidget(self.log) lay3.addWidget(self.bel2) lay3.addWidget(self.entry1) lay4.addWidget(self.bel3) lay4.addWidget(self.entry2) lay6.addWidget(self.rol_1) lay6.addWidget(self.try1) lay5.addWidget(self.button) lay5.addWidget(self.button22) lay5.addWidget(self.button3) box1a = QBoxLayout(QBoxLayout.TopToBottom) boxnew = QBoxLayout(QBoxLayout.TopToBottom) box1a.stretch(1) box1a.setSpacing(50) #box1a.setContentsMargins(0.44*sw, 0.08*sh, 0.44*sw,0.2*sh) box1a.addLayout(lay1) box1a.addLayout(lay2) box1a.addLayout(lay3) box1a.addLayout(lay4) box1a.addLayout(lay6) box1a.addLayout(lay5) #box1a.addLayout(self.newbeta.boxer) self.lo.setLayout(box1a) except Exception as dumm: print(dumm)
def initUI(self): boxlayout = QBoxLayout(QBoxLayout.TopToBottom) self.setLayout(boxlayout) lblWelcome = QLabel('Welcome to the earthquake simulation system') lblWelcome.setFont(gui.QFont("Verdana", 14)) lblSubtitle = QLabel('Upload your .smc files here') lblSubtitle.setFont(gui.QFont("Verdana", 10)) canvas = Canvas(self, width=10, height=10) path = QDir.rootPath() treeview = QTreeView() listview = QListView() dirModel = QFileSystemModel() dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) treeview.setModel(dirModel) fileModel = QFileSystemModel() fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) listview.setModel(fileModel) treeview.setRootIndex(dirModel.index(path)) listview.setRootIndex(fileModel.index(path)) btnUpload = QPushButton('Upload files') btnUpload.setFixedSize(100, 40) btnUpload.setFont(gui.QFont("Verdana", 10)) btnUpload.clicked.connect(self.openFileChooser) btnSimulate = QPushButton('Simulate') btnSimulate.setFixedSize(100, 40) btnSimulate.setFont(gui.QFont("Verdana", 10)) btnSimulate.clicked.connect(self.simulate) hbox_FileChooser = QHBoxLayout() hbox_FileChooser.addWidget(btnUpload) hbox_FileChooser.addWidget(self.lblFileName) vbox_treeViews = QVBoxLayout() vbox_treeViews.addWidget(treeview) vbox_treeViews.addWidget(listview) hbox_Graphics = QHBoxLayout() hbox_Graphics.addLayout(vbox_treeViews) hbox_Graphics.addWidget(canvas) boxlayout.addWidget(lblWelcome, 0, cor.Qt.AlignCenter) boxlayout.addWidget(lblSubtitle, 0, cor.Qt.AlignCenter) boxlayout.addLayout(hbox_FileChooser, 0) boxlayout.addWidget(btnSimulate, 0, cor.Qt.AlignCenter) boxlayout.setAlignment(cor.Qt.AlignCenter) boxlayout.setSpacing(20) boxlayout.addLayout(hbox_Graphics, 0) btnUpload = QPushButton('Upload files') btnUpload.setFixedSize(100, 40) btnUpload.setFont(gui.QFont("Verdana", 10)) btnUpload.clicked.connect(self.openFileChooser) self.resize(800, 500) self.setWindowTitle('Earthquake Simulator') self.show()
class QPageWidget(QScrollArea): """ The QPageWidget provides a stack widget with animated page transitions. """ #Emits currentChanged = pyqtSignal() def __init__(self, parent=None, direction="ltr", rtf=False): """ Creates a new QPageWidget on given parent object. parent: QWidget parent direction: "ltr" -> Left To Right "ttb" -> Top To Bottom rtf: Return to first, if its True it flips to the first page when next page requested at the last page """ # First initialize, QPageWidget is based on QScrollArea QScrollArea.__init__(self, parent) # Properties for QScrollArea self.setFrameShape(QFrame.NoFrame) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setWidgetResizable(True) # Main widget, which stores all Pages in it self.widget = QWidget(self) # Layout based on QBoxLayout which supports Vertical or Horizontal layout if direction == "ltr": self.layout = QBoxLayout(QBoxLayout.LeftToRight, self.widget) self.__scrollBar = self.horizontalScrollBar() self.__base_value = self.width else: self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget) self.__scrollBar = self.verticalScrollBar() self.__base_value = self.height self.layout.setSpacing(0) #qboxlayout setmargin özelliği yok #self.layout.setMargin(0) # Return to first self.__return_to_first = rtf # TMP_PAGE, its using as last page in stack # A workaround for a QScrollArea bug self.__tmp_page = Page(QWidget(self.widget)) self.__pages = [self.__tmp_page] self.__current = 0 self.__last = 0 # Set main widget self.setWidget(self.widget) # Animation TimeLine self.__timeline = QTimeLine() self.__timeline.setUpdateInterval(2) # Updates scrollbar position when frame changed self.__timeline.frameChanged.connect( lambda x: self.__scrollBar.setValue(x)) # End of the animation self.__timeline.finished.connect(self._animateFinished) # Initialize animation self.setAnimation() self.setDuration() def _animateFinished(self): """ Its called by TimeLine when animation finished. It first runs the outMethod of last Page and then the inMethod of current Page Finally tt gives the focus to the current page and fixes the scrollBar """ # Disable other widgets for page in self.__pages: if not page == self.__pages[self.__current]: page.widget.setEnabled(False) # Run last page's outMethod if exists if self.__pages[self.__last].outMethod: self.__pages[self.__last].outMethod() # Run new page's inMethod if exists if self.__pages[self.__current].inMethod: self.__pages[self.__current].inMethod() # Give focus to the current Page self.__pages[self.__current].widget.setFocus() # Update scrollbar position for current page self.__scrollBar.setValue(self.__current * self.__base_value()) # Emit currentChanged SIGNAL self.currentChanged.emit() def event(self, event): """ Overrides the main event handler to catch resize events """ # Catch Resize event if event.type() == QEvent.Resize: # Update each page size limits to mainwidget's new size for page in self.__pages: page.widget.setMinimumSize(self.size()) page.widget.setMaximumSize(self.size()) # Update viewport size limits to mainwidget's new size # It's a workaround for QScrollArea updateGeometry bug self.viewport().setMinimumSize(self.size()) self.viewport().setMaximumSize(self.size()) # Update scrollbar position for current page self.__scrollBar.setValue(self.__current * self.__base_value()) # Return the Event return QScrollArea.event(self, event) def keyPressEvent(self, event): """ Overrides the keyPressEvent to ignore them """ pass def wheelEvent(self, event): """ Overrides the wheelEvent to ignore them """ pass def createPage(self, widget, inMethod=None, outMethod=None): """ Creates and adds new Page for given widget with given in/out methods. widget: A QWidget which is the mainwidget for this Page inMethod: (optional) QPageWidget triggers this method when the Page appear outMethod: (optional) QPageWidget triggers this method when the Page disappear """ self.addPage(Page(widget, inMethod, outMethod)) def addPage(self, page): """ Adds the given Page to the stack. page: A Page object """ # First remove the last page; its __tmp_page self.__pages.pop() # Add new page self.__pages.append(page) self.layout.addWidget(page.widget) # Add __tmp_page to end self.__pages.append(self.__tmp_page) self.layout.addWidget(self.__tmp_page.widget) # Create connections for page navigation signals from new page try: page.widget.pageNext.connect(self.next) page.widget.pagePrevious.connect(self.prev) page.widget.setCurrent[int].connect(self.setCurrent) except: pass def __setCurrent(self, pageNumber): """ Internal method to set current page index. """ self.__last = self.__current self.__current = min(max(0, pageNumber), len(self.__pages) - 2) if pageNumber == len(self.__pages) - 1 and self.__return_to_first: self.__current = 0 def setCurrent(self, pageNumber=0): """ Set and flip the page with given pageNumber. pageNumber: index number of Page (default is 0) """ self.__setCurrent(pageNumber) self.flipPage() def getCurrent(self): """ Returns current page index. """ return self.__current def getCurrentWidget(self): """ Returns current page widget. """ return self.getWidget(self.getCurrent()) def getWidget(self, pageNumber): """ Returns widget for given page index pageNumber: index number of Page """ try: return self.__pages[pageNumber].widget except: return None def count(self): """ Returns number of pages. """ return len(self.__pages) - 1 def setAnimation(self, animation=35): """ Set the transition animation with the given animation. animation: the number represents predefined QEasingCurves List of predefined QEasingCurves can be found from: http://doc.qt.nokia.com/4/qeasingcurve.html#Type-enum Default is QEasingCurve::InOutBack (35) """ self.__animation = animation self.__timeline.setEasingCurve(QEasingCurve(self.__animation)) def setDuration(self, duration=400): """ Set the transition duration. duration: duration time in ms """ self.__duration = duration self.__timeline.setDuration(self.__duration) def flipPage(self, direction=0): """ Flip the page with given direction. direction: can be -1, 0 or +1 -1: previous page (if exists) 0: just flip to current page +1: next page (if exists) """ # Enable all widgets for page in self.__pages: page.widget.setEnabled(True) # Check given direction direction = direction if direction == 0 else max(min(1, direction), -1) # If direction is equal to zero no need to re-set current if not direction == 0: self.__setCurrent(self.__current + direction) # If last page is different from new page, flip it ! if not self.__last == self.__current: self.__timeline.setFrameRange(self.__scrollBar.value(), self.__current * self.__base_value()) self.__timeline.start() def next(self): """ Helper method to flip next page. """ self.flipPage(1) def prev(self): """ Helper method to flip previous page. """ self.flipPage(-1)
window = QWidget() btn1 = QPushButton("One") btn2 = QPushButton("Two") btn3 = QPushButton("Three") # Set the layout box = QBoxLayout(QBoxLayout.Direction(0)) # TODO box.addWidget(btn1) box.addWidget(btn2) box.addWidget(btn3) box.setContentsMargins(0, 0, 0, 0) # set the spacing around the layout (in pixels) box.setSpacing(0) # set the spacing between elements (in pixels) window.setLayout(box) # Show window.show() # The mainloop of the application. The event handling starts from this point. # The exec_() method has an underscore. It is because the exec is a Python keyword. And thus, exec_() was used instead. exit_code = app.exec_() # The sys.exit() method ensures a clean exit. # The environment will be informed, how the application ended. sys.exit(exit_code)
class Demo(QWidget): def __init__(self): super().__init__() self.setWindowTitle("测试") # 窗口大小 self.resize(1400, 800) # self.setFixedSize(1500, 600) # 设置窗口为固定尺寸, 此时窗口不可调整大小 # self.setMinimumSize(1800, 1000) # 设置窗口最大尺寸 # self.setMaximumSize(900, 300) # 设置窗口最小尺寸 # self.setWindowFlag(Qt.WindowStaysOnTopHint) # 设置窗口顶层显示 # self.setWindowFlags(Qt.FramelessWindowHint) # 设置无边框窗口样式,不显示最上面的标题栏 self.content_font = QFont("微软雅黑", 12, QFont.Medium) # 定义字体样式 self.center() self.__setup_ui__() # 控制窗口显示在屏幕中心的方法 def center(self): # 获得窗口 qr = self.frameGeometry() # 获得屏幕中心点 cp = QDesktopWidget().availableGeometry().center() # 显示到屏幕中心 qr.moveCenter(cp) self.move(qr.topLeft()) # 关闭窗口的时候,触发了QCloseEvent,需要重写closeEvent()事件处理程序,这样就可以弹出是否退出的确认窗口 def closeEvent(self, event): reply = QMessageBox.question( self, "退出程序", # 提示框标题 "确定退出xxxx程序吗?", # 消息对话框中显示的文本 QMessageBox.Yes | QMessageBox.No, # 指定按钮的组合 Yes和No QMessageBox.No # 默认的按钮焦点,这里默认是No按钮 ) # 判断按钮的选择 if reply == QMessageBox.Yes: event.accept() else: event.ignore() def __setup_ui__(self): # 工具栏 self.frame_tool = QFrame(self) self.frame_tool.setObjectName("frame_tool") self.frame_tool.setGeometry(0, 0, self.width(), 25) self.frame_tool.setStyleSheet("border-color: rgb(0, 0, 0);") self.frame_tool.setFrameShape(QFrame.Panel) self.frame_tool.setFrameShadow(QFrame.Raised) # 1.1 界面1按钮 self.window1_btn = QToolButton(self.frame_tool) self.window1_btn.setCheckable(True) self.window1_btn.setText("window1") self.window1_btn.setObjectName("menu_btn") self.window1_btn.resize(100, 25) self.window1_btn.clicked.connect(self.click_window1) self.window1_btn.setAutoRaise( True) # 去掉工具按钮的边框线如果是QPushButton按钮的话,就是用setFlat(True)这个方法,用法相同 # 1.2 界面2按钮 self.window2_btn = QToolButton(self.frame_tool) self.window2_btn.setCheckable(True) self.window2_btn.setText("window2") self.window2_btn.setObjectName("menu_btn") self.window2_btn.resize(100, 25) self.window2_btn.move(self.window1_btn.width(), 0) self.window2_btn.clicked.connect(self.click_window2) self.window2_btn.setAutoRaise(True) self.btn_group = QButtonGroup(self.frame_tool) self.btn_group.addButton(self.window1_btn, 1) self.btn_group.addButton(self.window2_btn, 2) # 1.3 帮助下拉菜单栏 # 创建帮助工具按钮 help_btn = QToolButton(self.frame_tool) help_btn.setText("帮助") help_btn.setObjectName("menu_btn") help_btn.resize(100, 25) help_btn.move(self.window2_btn.x() + self.window2_btn.width(), 0) help_btn.setAutoRaise(True) help_btn.setPopupMode(QToolButton.InstantPopup) # 创建关于菜单 help_menu = QMenu("帮助", self.frame_tool) feedback_action = QAction(QIcon("xxx.png"), "反馈", help_menu) feedback_action.triggered.connect(self.click_feedback) about_action = QAction(QIcon("xxx.png"), "关于", help_menu) about_action.triggered.connect(self.click_about) # 把两个QAction放入help_menu help_menu.addAction(feedback_action) help_menu.addAction(about_action) # 把help_menu放入help_btn help_btn.setMenu(help_menu) # 2. 工作区域 self.main_frame = QFrame(self) self.main_frame.setGeometry(0, 25, self.width(), self.height() - self.frame_tool.height()) # self.main_frame.setStyleSheet("background-color: rgb(65, 95, 255)") # 创建堆叠布局 self.stacked_layout = QStackedLayout(self.main_frame) # 第一个布局 self.main_frame1 = QMainWindow() self.frame1_bar = QStatusBar() self.frame1_bar.setObjectName("frame1_bar") self.main_frame1.setStatusBar(self.frame1_bar) self.frame1_bar.showMessage("欢迎进入frame1") rom_frame = QFrame(self.main_frame1) rom_frame.setGeometry(0, 0, self.width(), self.main_frame.height() - 25) rom_frame.setFrameShape(QFrame.Panel) rom_frame.setFrameShadow(QFrame.Raised) # 超链接 self.super_link = QLabel(rom_frame) self.super_link.setText(""" 超链接: <a href="https://blog.csdn.net/s_daqing">点击打开查看</a> """) self.super_link.setGeometry(20, 30, 300, 25) self.super_link.setFont(self.content_font) # 使用字体样式 self.super_link.setOpenExternalLinks(True) # 使其成为超链接 self.super_link.setTextInteractionFlags( Qt.TextBrowserInteraction) # 双击可以复制文本 self.start_btn = QPushButton("开 始", rom_frame) self.start_btn.setGeometry(self.width() * 0.7, self.height() * 0.8, 100, 40) # self.start_btn.clicked.connect(self.start_btn_click) self.quit_btn = QPushButton("退 出", rom_frame) self.quit_btn.setGeometry(self.width() * 0.85, self.height() * 0.8, 100, 40) self.quit_btn.setStatusTip("点击关闭程序") # self.quit_btn.clicked.connect(QCoreApplication.instance().quit) # 点击退出可以直接退出 self.quit_btn.clicked.connect(self.close) # 点击退出按钮的退出槽函数 #rom_frame1 = QFrame() #rom_frame1.setFrameShape(QFrame.Panel) #rom_frame1.setFrameShadow(QFrame.Raised) #rom_frame2 = QFrame() #rom_frame2.setFrameShape(QFrame.Panel) #rom_frame2.setFrameShadow(QFrame.Raised) # 创建布局管理器 self.layout1 = QBoxLayout(QBoxLayout.TopToBottom) # 给管理器对象设置父控件 rom_frame.setLayout(self.layout1) self.main_frame1.setCentralWidget(rom_frame) # 把子控件添加到布局管理器中 #self.layout1.addWidget(rom_frame1, 1) #self.layout1.addWidget(rom_frame2, 1) self.layout1.setContentsMargins(0, 0, 0, 0) # 设置布局的左上右下外边距 self.layout1.setSpacing(0) # 设置子控件的内边距 frame1_bar_frame = QFrame(self.main_frame1) frame1_bar_frame.setGeometry(0, self.main_frame.height(), self.width(), 25) # 第二个布局 self.main_frame2 = QMainWindow() self.frame2_bar = QStatusBar() self.frame2_bar.setObjectName("frame2_bar") self.main_frame2.setStatusBar(self.frame2_bar) self.frame2_bar.showMessage("欢迎进入frame2") custom_frame = QFrame(self.main_frame2) custom_frame.setGeometry(0, 0, self.width(), self.main_frame.height() - 25) custom_frame.setFrameShape(QFrame.Panel) custom_frame.setFrameShadow(QFrame.Raised) custom_frame1 = QFrame() custom_frame1.setFrameShape(QFrame.Panel) custom_frame1.setFrameShadow(QFrame.Raised) custom_frame2 = QFrame() custom_frame2.setFrameShape(QFrame.Panel) custom_frame2.setFrameShadow(QFrame.Raised) custom_frame3 = QFrame() custom_frame3.setFrameShape(QFrame.Panel) custom_frame3.setFrameShadow(QFrame.Raised) # 创建布局管理器 self.layout2 = QBoxLayout(QBoxLayout.TopToBottom) # 给管理器对象设置父控件 custom_frame.setLayout(self.layout2) """ 使用了父类为QMainWindow的话,在里面使用布局类,QGridLayout, QHBoxLayout ,QVBoxLayout 等等时,发现不好用, 加上下面这句代码就可以了,QMainWindow对象.setCentralWidget(这里填布局管理器的父控件对象) """ self.main_frame2.setCentralWidget(custom_frame) # 把子控件添加到布局管理器中 self.layout2.addWidget(custom_frame1, 1) self.layout2.addWidget(custom_frame2, 1) self.layout2.addWidget(custom_frame3, 1) self.layout2.setContentsMargins(0, 0, 0, 0) # 设置布局的左上右下外边距 self.layout2.setSpacing(0) # 设置子控件的内边距 frame2_bar_frame = QFrame(self.main_frame2) frame2_bar_frame.setGeometry(0, self.main_frame.height(), self.width(), 25) # 把两个布局放进去 self.stacked_layout.addWidget(self.main_frame1) self.stacked_layout.addWidget(self.main_frame2) def click_window1(self): if self.stacked_layout.currentIndex() != 0: self.stacked_layout.setCurrentIndex(0) self.frame1_bar.showMessage("欢迎进入frame1") def click_window2(self): if self.stacked_layout.currentIndex() != 1: self.stacked_layout.setCurrentIndex(1) self.frame2_bar.showMessage("欢迎进入frame2") QDesktopServices.openUrl(QUrl("https://www.csdn.net/") ) # 点击window2按钮后,执行这个槽函数的时候,会在浏览器自动打开这个网址 def click_feedback(self, event): QMessageBox.about(self, "反馈", "使用过程中如有疑问,请联系:xxxx.163.com\r\n\r\n版本:V1.0.1") def click_about(self, event): QMessageBox.about(self, "关于", "使用文档,请参考:xxxxxx")
class QPageWidget(QScrollArea): """ The QPageWidget provides a stack widget with animated page transitions. """ #Emits currentChanged = pyqtSignal() def __init__(self, parent = None, direction = "ltr", rtf = False): """ Creates a new QPageWidget on given parent object. parent: QWidget parent direction: "ltr" -> Left To Right "ttb" -> Top To Bottom rtf: Return to first, if its True it flips to the first page when next page requested at the last page """ # First initialize, QPageWidget is based on QScrollArea QScrollArea.__init__(self, parent) # Properties for QScrollArea self.setFrameShape(QFrame.NoFrame) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setWidgetResizable(True) # Main widget, which stores all Pages in it self.widget = QWidget(self) # Layout based on QBoxLayout which supports Vertical or Horizontal layout if direction == "ltr": self.layout = QBoxLayout(QBoxLayout.LeftToRight, self.widget) self.__scrollBar = self.horizontalScrollBar() self.__base_value = self.width else: self.layout = QBoxLayout(QBoxLayout.TopToBottom, self.widget) self.__scrollBar = self.verticalScrollBar() self.__base_value = self.height self.layout.setSpacing(0) #qboxlayout setmargin özelliği yok #self.layout.setMargin(0) # Return to first self.__return_to_first = rtf # TMP_PAGE, its using as last page in stack # A workaround for a QScrollArea bug self.__tmp_page = Page(QWidget(self.widget)) self.__pages = [self.__tmp_page] self.__current = 0 self.__last = 0 # Set main widget self.setWidget(self.widget) # Animation TimeLine self.__timeline = QTimeLine() self.__timeline.setUpdateInterval(2) # Updates scrollbar position when frame changed self.__timeline.frameChanged.connect(lambda x: self.__scrollBar.setValue(x)) # End of the animation self.__timeline.finished.connect(self._animateFinished) # Initialize animation self.setAnimation() self.setDuration() def _animateFinished(self): """ Its called by TimeLine when animation finished. It first runs the outMethod of last Page and then the inMethod of current Page Finally tt gives the focus to the current page and fixes the scrollBar """ # Disable other widgets for page in self.__pages: if not page == self.__pages[self.__current]: page.widget.setEnabled(False) # Run last page's outMethod if exists if self.__pages[self.__last].outMethod: self.__pages[self.__last].outMethod() # Run new page's inMethod if exists if self.__pages[self.__current].inMethod: self.__pages[self.__current].inMethod() # Give focus to the current Page self.__pages[self.__current].widget.setFocus() # Update scrollbar position for current page self.__scrollBar.setValue(self.__current * self.__base_value()) # Emit currentChanged SIGNAL self.currentChanged.emit() def event(self, event): """ Overrides the main event handler to catch resize events """ # Catch Resize event if event.type() == QEvent.Resize: # Update each page size limits to mainwidget's new size for page in self.__pages: page.widget.setMinimumSize(self.size()) page.widget.setMaximumSize(self.size()) # Update viewport size limits to mainwidget's new size # It's a workaround for QScrollArea updateGeometry bug self.viewport().setMinimumSize(self.size()) self.viewport().setMaximumSize(self.size()) # Update scrollbar position for current page self.__scrollBar.setValue(self.__current * self.__base_value()) # Return the Event return QScrollArea.event(self, event) def keyPressEvent(self, event): """ Overrides the keyPressEvent to ignore them """ pass def wheelEvent(self, event): """ Overrides the wheelEvent to ignore them """ pass def createPage(self, widget, inMethod = None, outMethod = None): """ Creates and adds new Page for given widget with given in/out methods. widget: A QWidget which is the mainwidget for this Page inMethod: (optional) QPageWidget triggers this method when the Page appear outMethod: (optional) QPageWidget triggers this method when the Page disappear """ self.addPage(Page(widget, inMethod, outMethod)) def addPage(self, page): """ Adds the given Page to the stack. page: A Page object """ # First remove the last page; its __tmp_page self.__pages.pop() # Add new page self.__pages.append(page) self.layout.addWidget(page.widget) # Add __tmp_page to end self.__pages.append(self.__tmp_page) self.layout.addWidget(self.__tmp_page.widget) # Create connections for page navigation signals from new page try: page.widget.pageNext.connect(self.next) page.widget.pagePrevious.connect(self.prev) page.widget.setCurrent[int].connect(self.setCurrent) except: pass def __setCurrent(self, pageNumber): """ Internal method to set current page index. """ self.__last = self.__current self.__current = min(max(0, pageNumber), len(self.__pages) - 2) if pageNumber == len(self.__pages) - 1 and self.__return_to_first: self.__current = 0 def setCurrent(self, pageNumber = 0): """ Set and flip the page with given pageNumber. pageNumber: index number of Page (default is 0) """ self.__setCurrent(pageNumber) self.flipPage() def getCurrent(self): """ Returns current page index. """ return self.__current def getCurrentWidget(self): """ Returns current page widget. """ return self.getWidget(self.getCurrent()) def getWidget(self, pageNumber): """ Returns widget for given page index pageNumber: index number of Page """ try: return self.__pages[pageNumber].widget except: return None def count(self): """ Returns number of pages. """ return len(self.__pages) - 1 def setAnimation(self, animation = 35): """ Set the transition animation with the given animation. animation: the number represents predefined QEasingCurves List of predefined QEasingCurves can be found from: http://doc.qt.nokia.com/4/qeasingcurve.html#Type-enum Default is QEasingCurve::InOutBack (35) """ self.__animation = animation self.__timeline.setEasingCurve(QEasingCurve(self.__animation)) def setDuration(self, duration = 400): """ Set the transition duration. duration: duration time in ms """ self.__duration = duration self.__timeline.setDuration(self.__duration) def flipPage(self, direction=0): """ Flip the page with given direction. direction: can be -1, 0 or +1 -1: previous page (if exists) 0: just flip to current page +1: next page (if exists) """ # Enable all widgets for page in self.__pages: page.widget.setEnabled(True) # Check given direction direction = direction if direction == 0 else max(min(1, direction), -1) # If direction is equal to zero no need to re-set current if not direction == 0: self.__setCurrent(self.__current + direction) # If last page is different from new page, flip it ! if not self.__last == self.__current: self.__timeline.setFrameRange(self.__scrollBar.value(), self.__current * self.__base_value()) self.__timeline.start() def next(self): """ Helper method to flip next page. """ self.flipPage(1) def prev(self): """ Helper method to flip previous page. """ self.flipPage(-1)
class QCustomWindowFrame(QFrame): contentsChanged = pyqtSignal(QWidget) def __init__(self): super(QCustomWindowFrame, self).__init__(None) self.titleBar = None self.contents = None self.sizeGrip = None self.resizeMargin = 4 self.setMouseTracking(True) self.layout = QBoxLayout(QBoxLayout.TopToBottom) self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) def __del__(self): pass @staticmethod def wrapWidget(w): windowFrame = QCustomWindowFrame() windowFrame.internalSetContents(w) return windowFrame def ensureTitleBar(self): if self.titleBar is None: self.titleBar = QCustomTitleBar(self) def internalSetContents(self, widget, useContentsGeometry=True): if self.contents != None: if self.contents.parentWidget() == self: self.contents.setParent(None) self.layout.removeWidget(self.sizeGrip) self.layout.removeWidget(self.contents) self.layout.removeWidget(self.titleBar) self.contents.removeEventFilter(self) self.contents.windowTitleChanged.disconnect(self.setWindowTitle) self.contents.windowIconChanged.disconnect(self.onIconChange) self.contents = widget if self.contents != None: self.contents.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) if self.contents.testAttribute(QtCore.Qt.WA_QuitOnClose): self.contents.setAttribute(QtCore.Qt.WA_QuitOnClose, False) self.setAttribute(QtCore.Qt.WA_QuitOnClose) self.setAttribute( QtCore.Qt.WA_DeleteOnClose, self.contents.testAttribute(QtCore.Qt.WA_DeleteOnClose)) self.setWindowTitle(self.contents.windowTitle()) self.setWindowIcon(self.contents.windowIcon()) self.contents.installEventFilter(self) self.contents.windowTitleChanged.connect(self.setWindowTitle) self.contents.windowIconChanged.connect(self.onIconChange) if useContentsGeometry: self.contents.show() self.setGeometry(self.contents.geometry()) self.contents.setParent(self) else: self.contents.setParent(self) self.contents.show() self.updateWindowFlags() self.ensureTitleBar() self.layout.addWidget(self.titleBar) self.layout.addWidget(self.contents) if self.sizeGrip == None: self.sizeGrip = QSizeGrip(self) self.sizeGrip.setMaximumHeight(2) import sys if sys.platform == 'darwin': self.layout.addWidget(self.sizeGrip, 2) # osx else: self.layout.addWidget(self.sizeGrip, 2, QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight) # window self.contentsChanged.emit(self.contents) # def nativeEvent ( self, eventType, message, result ): # if not self.titleBar: # return False # return super ().nativeEvent ( eventType, message, result ) def event(self, e): if e.type() == QEvent.Show: if not self.contents.isVisibleTo(self): self.contents.show() if e.type() == QEvent.Hide: if self.contents != None: if self.contents.isVisibleTo(self) and self.windowState( ) != QtCore.Qt.WindowMinimized: self.contents.hide() return super().event(e) def closeEvent(self, e): if self.contents != None and self.contents.isVisibleTo(self): if not self.contents.close(): e.ignore() super().closeEvent(e) def changeEvent(self, e): if (e.type() == QEvent.WindowStateChange or e.type() == QEvent.ActivationChange ) and getMainWindow() and getMainWindow().windowState( ) == QtCore.Qt.WindowMinimized: getMainWindow().setWindowState(QtCore.Qt.WindowNoState) if self.titleBar != None: self.titleBar.updateWindowStateButtons() super().changeEvent(e) def eventFilter(self, o, e): if o == self.contents: if self.contents.parentWidget() == self: if e.type() == QEvent.Close: self.close() elif e.type() == QEvent.HideToParent: if self.isVisible(): self.hide() elif e.type() == QEvent.ShowToParent: if not self.isVisible(): self.show() return super().eventFilter(o, e) def mouseReleaseEvent(self, e): if self.titleBar is None: e.ignore() return if e.button() == QtCore.Qt.LeftButton: self.titleBar.dragging = False super().mouseReleaseEvent(e) # def nudgeWindow ( self ): # pass def calcFrameWindowFlags(self): flags = self.windowFlags() if self.contents: # Get all window flags from contents, excluding WindowType flags. flags = (flags & QtCore.Qt.WindowType_Mask) | ( self.contents.windowFlags() & ~QtCore.Qt.WindowType_Mask) import sys if sys.platform == 'darwin': return flags | QtCore.Qt.FramelessWindowHint # osx FIXME: CustomizeWindowHint flag will show cocoa title bar. else: return flags | QtCore.Qt.FramelessWindowHint | QtCore.Qt.CustomizeWindowHint # windows def updateWindowFlags(self): if self.contents != None: contentsWindowType = self.contents.windowFlags( ) & QtCore.Qt.WindowType_Mask # Contents has window type set, assign them it to us. if contentsWindowType != QtCore.Qt.Widget: # Clear window type flags self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowType_Mask) # Set window type from contents' flags, then clear contents' window type flags. self.setWindowFlags(self.windowFlags() | contentsWindowType) self.contents.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowType_Mask) # No window type has been set on the contents, and we don't have any window flags elif (self.windowFlags() & QtCore.Qt.WindowType_Mask) == QtCore.Qt.Widget: self.setWindowFlags(self.windowFlags() | QtCore.Qt.Window) self.setWindowFlags(self.calcFrameWindowFlags()) def onIconChange(self): if self.contents != None and self.windowIcon().cacheKey( ) != self.contents.windowIcon().cacheKey(): self.setWindowIcon(self.contents.windowIcon()) def getResizeMargin(self): return self.resizeMargin def setResizeMargin(self, resizeMargin): self.resizeMargin = resizeMargin
class E5SideBar(QWidget): """ Class implementing a sidebar with a widget area, that is hidden or shown, if the current tab is clicked again. """ Version = 1 North = 0 East = 1 South = 2 West = 3 def __init__(self, orientation=None, delay=200, parent=None): """ Constructor @param orientation orientation of the sidebar widget (North, East, South, West) @param delay value for the expand/shrink delay in milliseconds (integer) @param parent parent widget (QWidget) """ super(E5SideBar, self).__init__(parent) self.__tabBar = QTabBar() self.__tabBar.setDrawBase(True) self.__tabBar.setShape(QTabBar.RoundedNorth) self.__tabBar.setUsesScrollButtons(True) self.__tabBar.setDrawBase(False) self.__stackedWidget = QStackedWidget(self) self.__stackedWidget.setContentsMargins(0, 0, 0, 0) self.__autoHideButton = QToolButton() self.__autoHideButton.setCheckable(True) self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOff.png")) self.__autoHideButton.setChecked(True) self.__autoHideButton.setToolTip( self.tr("Deselect to activate automatic collapsing")) self.barLayout = QBoxLayout(QBoxLayout.LeftToRight) self.barLayout.setContentsMargins(0, 0, 0, 0) self.layout = QBoxLayout(QBoxLayout.TopToBottom) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.barLayout.addWidget(self.__autoHideButton) self.barLayout.addWidget(self.__tabBar) self.layout.addLayout(self.barLayout) self.layout.addWidget(self.__stackedWidget) self.setLayout(self.layout) # initialize the delay timer self.__actionMethod = None self.__delayTimer = QTimer(self) self.__delayTimer.setSingleShot(True) self.__delayTimer.setInterval(delay) self.__delayTimer.timeout.connect(self.__delayedAction) self.__minimized = False self.__minSize = 0 self.__maxSize = 0 self.__bigSize = QSize() self.splitter = None self.splitterSizes = [] self.__hasFocus = False # flag storing if this widget or any child has the focus self.__autoHide = False self.__tabBar.installEventFilter(self) self.__orientation = E5SideBar.North if orientation is None: orientation = E5SideBar.North self.setOrientation(orientation) self.__tabBar.currentChanged[int].connect( self.__stackedWidget.setCurrentIndex) e5App().focusChanged[QWidget, QWidget].connect(self.__appFocusChanged) self.__autoHideButton.toggled[bool].connect(self.__autoHideToggled) def setSplitter(self, splitter): """ Public method to set the splitter managing the sidebar. @param splitter reference to the splitter (QSplitter) """ self.splitter = splitter self.splitter.splitterMoved.connect(self.__splitterMoved) self.splitter.setChildrenCollapsible(False) index = self.splitter.indexOf(self) self.splitter.setCollapsible(index, False) def __splitterMoved(self, pos, index): """ Private slot to react on splitter moves. @param pos new position of the splitter handle (integer) @param index index of the splitter handle (integer) """ if self.splitter: self.splitterSizes = self.splitter.sizes() def __delayedAction(self): """ Private slot to handle the firing of the delay timer. """ if self.__actionMethod is not None: self.__actionMethod() def setDelay(self, delay): """ Public method to set the delay value for the expand/shrink delay in milliseconds. @param delay value for the expand/shrink delay in milliseconds (integer) """ self.__delayTimer.setInterval(delay) def delay(self): """ Public method to get the delay value for the expand/shrink delay in milliseconds. @return value for the expand/shrink delay in milliseconds (integer) """ return self.__delayTimer.interval() def __cancelDelayTimer(self): """ Private method to cancel the current delay timer. """ self.__delayTimer.stop() self.__actionMethod = None def shrink(self): """ Public method to record a shrink request. """ self.__delayTimer.stop() self.__actionMethod = self.__shrinkIt self.__delayTimer.start() def __shrinkIt(self): """ Private method to shrink the sidebar. """ self.__minimized = True self.__bigSize = self.size() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() self.__maxSize = self.maximumHeight() else: self.__minSize = self.minimumSizeHint().width() self.__maxSize = self.maximumWidth() if self.splitter: self.splitterSizes = self.splitter.sizes() self.__stackedWidget.hide() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.setFixedHeight(self.__tabBar.minimumSizeHint().height()) else: self.setFixedWidth(self.__tabBar.minimumSizeHint().width()) self.__actionMethod = None def expand(self): """ Public method to record a expand request. """ self.__delayTimer.stop() self.__actionMethod = self.__expandIt self.__delayTimer.start() def __expandIt(self): """ Private method to expand the sidebar. """ self.__minimized = False self.__stackedWidget.show() self.resize(self.__bigSize) if self.__orientation in [E5SideBar.North, E5SideBar.South]: minSize = max(self.__minSize, self.minimumSizeHint().height()) self.setMinimumHeight(minSize) self.setMaximumHeight(self.__maxSize) else: minSize = max(self.__minSize, self.minimumSizeHint().width()) self.setMinimumWidth(minSize) self.setMaximumWidth(self.__maxSize) if self.splitter: self.splitter.setSizes(self.splitterSizes) self.__actionMethod = None def isMinimized(self): """ Public method to check the minimized state. @return flag indicating the minimized state (boolean) """ return self.__minimized def isAutoHiding(self): """ Public method to check, if the auto hide function is active. @return flag indicating the state of auto hiding (boolean) """ return self.__autoHide def eventFilter(self, obj, evt): """ Public method to handle some events for the tabbar. @param obj reference to the object (QObject) @param evt reference to the event object (QEvent) @return flag indicating, if the event was handled (boolean) """ if obj == self.__tabBar: if evt.type() == QEvent.MouseButtonPress: pos = evt.pos() for i in range(self.__tabBar.count()): if self.__tabBar.tabRect(i).contains(pos): break if i == self.__tabBar.currentIndex(): if self.isMinimized(): self.expand() else: self.shrink() return True elif self.isMinimized(): self.expand() elif evt.type() == QEvent.Wheel: if qVersion() >= "5.0.0": delta = evt.angleDelta().y() else: delta = evt.delta() if delta > 0: self.prevTab() else: self.nextTab() return True return QWidget.eventFilter(self, obj, evt) def addTab(self, widget, iconOrLabel, label=None): """ Public method to add a tab to the sidebar. @param widget reference to the widget to add (QWidget) @param iconOrLabel reference to the icon or the label text of the tab (QIcon, string) @param label the labeltext of the tab (string) (only to be used, if the second parameter is a QIcon) """ if label: index = self.__tabBar.addTab(iconOrLabel, label) self.__tabBar.setTabToolTip(index, label) else: index = self.__tabBar.addTab(iconOrLabel) self.__tabBar.setTabToolTip(index, iconOrLabel) self.__stackedWidget.addWidget(widget) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def insertTab(self, index, widget, iconOrLabel, label=None): """ Public method to insert a tab into the sidebar. @param index the index to insert the tab at (integer) @param widget reference to the widget to insert (QWidget) @param iconOrLabel reference to the icon or the labeltext of the tab (QIcon, string) @param label the labeltext of the tab (string) (only to be used, if the second parameter is a QIcon) """ if label: index = self.__tabBar.insertTab(index, iconOrLabel, label) self.__tabBar.setTabToolTip(index, label) else: index = self.__tabBar.insertTab(index, iconOrLabel) self.__tabBar.setTabToolTip(index, iconOrLabel) self.__stackedWidget.insertWidget(index, widget) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def removeTab(self, index): """ Public method to remove a tab. @param index the index of the tab to remove (integer) """ self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index)) self.__tabBar.removeTab(index) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def clear(self): """ Public method to remove all tabs. """ while self.count() > 0: self.removeTab(0) def prevTab(self): """ Public slot used to show the previous tab. """ ind = self.currentIndex() - 1 if ind == -1: ind = self.count() - 1 self.setCurrentIndex(ind) self.currentWidget().setFocus() def nextTab(self): """ Public slot used to show the next tab. """ ind = self.currentIndex() + 1 if ind == self.count(): ind = 0 self.setCurrentIndex(ind) self.currentWidget().setFocus() def count(self): """ Public method to get the number of tabs. @return number of tabs in the sidebar (integer) """ return self.__tabBar.count() def currentIndex(self): """ Public method to get the index of the current tab. @return index of the current tab (integer) """ return self.__stackedWidget.currentIndex() def setCurrentIndex(self, index): """ Public slot to set the current index. @param index the index to set as the current index (integer) """ self.__tabBar.setCurrentIndex(index) self.__stackedWidget.setCurrentIndex(index) if self.isMinimized(): self.expand() def currentWidget(self): """ Public method to get a reference to the current widget. @return reference to the current widget (QWidget) """ return self.__stackedWidget.currentWidget() def setCurrentWidget(self, widget): """ Public slot to set the current widget. @param widget reference to the widget to become the current widget (QWidget) """ self.__stackedWidget.setCurrentWidget(widget) self.__tabBar.setCurrentIndex(self.__stackedWidget.currentIndex()) if self.isMinimized(): self.expand() def indexOf(self, widget): """ Public method to get the index of the given widget. @param widget reference to the widget to get the index of (QWidget) @return index of the given widget (integer) """ return self.__stackedWidget.indexOf(widget) def isTabEnabled(self, index): """ Public method to check, if a tab is enabled. @param index index of the tab to check (integer) @return flag indicating the enabled state (boolean) """ return self.__tabBar.isTabEnabled(index) def setTabEnabled(self, index, enabled): """ Public method to set the enabled state of a tab. @param index index of the tab to set (integer) @param enabled enabled state to set (boolean) """ self.__tabBar.setTabEnabled(index, enabled) def orientation(self): """ Public method to get the orientation of the sidebar. @return orientation of the sidebar (North, East, South, West) """ return self.__orientation def setOrientation(self, orient): """ Public method to set the orientation of the sidebar. @param orient orientation of the sidebar (North, East, South, West) """ if orient == E5SideBar.North: self.__tabBar.setShape(QTabBar.RoundedNorth) self.__tabBar.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred) self.barLayout.setDirection(QBoxLayout.LeftToRight) self.layout.setDirection(QBoxLayout.TopToBottom) self.layout.setAlignment(self.barLayout, Qt.AlignLeft) elif orient == E5SideBar.East: self.__tabBar.setShape(QTabBar.RoundedEast) self.__tabBar.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Expanding) self.barLayout.setDirection(QBoxLayout.TopToBottom) self.layout.setDirection(QBoxLayout.RightToLeft) self.layout.setAlignment(self.barLayout, Qt.AlignTop) elif orient == E5SideBar.South: self.__tabBar.setShape(QTabBar.RoundedSouth) self.__tabBar.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred) self.barLayout.setDirection(QBoxLayout.LeftToRight) self.layout.setDirection(QBoxLayout.BottomToTop) self.layout.setAlignment(self.barLayout, Qt.AlignLeft) elif orient == E5SideBar.West: self.__tabBar.setShape(QTabBar.RoundedWest) self.__tabBar.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Expanding) self.barLayout.setDirection(QBoxLayout.TopToBottom) self.layout.setDirection(QBoxLayout.LeftToRight) self.layout.setAlignment(self.barLayout, Qt.AlignTop) self.__orientation = orient def tabIcon(self, index): """ Public method to get the icon of a tab. @param index index of the tab (integer) @return icon of the tab (QIcon) """ return self.__tabBar.tabIcon(index) def setTabIcon(self, index, icon): """ Public method to set the icon of a tab. @param index index of the tab (integer) @param icon icon to be set (QIcon) """ self.__tabBar.setTabIcon(index, icon) def tabText(self, index): """ Public method to get the text of a tab. @param index index of the tab (integer) @return text of the tab (string) """ return self.__tabBar.tabText(index) def setTabText(self, index, text): """ Public method to set the text of a tab. @param index index of the tab (integer) @param text text to set (string) """ self.__tabBar.setTabText(index, text) def tabToolTip(self, index): """ Public method to get the tooltip text of a tab. @param index index of the tab (integer) @return tooltip text of the tab (string) """ return self.__tabBar.tabToolTip(index) def setTabToolTip(self, index, tip): """ Public method to set the tooltip text of a tab. @param index index of the tab (integer) @param tip tooltip text to set (string) """ self.__tabBar.setTabToolTip(index, tip) def tabWhatsThis(self, index): """ Public method to get the WhatsThis text of a tab. @param index index of the tab (integer) @return WhatsThis text of the tab (string) """ return self.__tabBar.tabWhatsThis(index) def setTabWhatsThis(self, index, text): """ Public method to set the WhatsThis text of a tab. @param index index of the tab (integer) @param text WhatsThis text to set (string) """ self.__tabBar.setTabWhatsThis(index, text) def widget(self, index): """ Public method to get a reference to the widget associated with a tab. @param index index of the tab (integer) @return reference to the widget (QWidget) """ return self.__stackedWidget.widget(index) def saveState(self): """ Public method to save the state of the sidebar. @return saved state as a byte array (QByteArray) """ if len(self.splitterSizes) == 0: if self.splitter: self.splitterSizes = self.splitter.sizes() self.__bigSize = self.size() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() self.__maxSize = self.maximumHeight() else: self.__minSize = self.minimumSizeHint().width() self.__maxSize = self.maximumWidth() data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) stream.writeUInt16(self.Version) stream.writeBool(self.__minimized) stream << self.__bigSize stream.writeUInt16(self.__minSize) stream.writeUInt16(self.__maxSize) stream.writeUInt16(len(self.splitterSizes)) for size in self.splitterSizes: stream.writeUInt16(size) stream.writeBool(self.__autoHide) return data def restoreState(self, state): """ Public method to restore the state of the sidebar. @param state byte array containing the saved state (QByteArray) @return flag indicating success (boolean) """ if state.isEmpty(): return False if self.__orientation in [E5SideBar.North, E5SideBar.South]: minSize = self.layout.minimumSize().height() maxSize = self.maximumHeight() else: minSize = self.layout.minimumSize().width() maxSize = self.maximumWidth() data = QByteArray(state) stream = QDataStream(data, QIODevice.ReadOnly) stream.setVersion(QDataStream.Qt_4_6) stream.readUInt16() # version minimized = stream.readBool() if minimized and not self.__minimized: self.shrink() stream >> self.__bigSize self.__minSize = max(stream.readUInt16(), minSize) self.__maxSize = max(stream.readUInt16(), maxSize) count = stream.readUInt16() self.splitterSizes = [] for i in range(count): self.splitterSizes.append(stream.readUInt16()) self.__autoHide = stream.readBool() self.__autoHideButton.setChecked(not self.__autoHide) if not minimized: self.expand() return True ####################################################################### ## methods below implement the autohide functionality ####################################################################### def __autoHideToggled(self, checked): """ Private slot to handle the toggling of the autohide button. @param checked flag indicating the checked state of the button (boolean) """ self.__autoHide = not checked if self.__autoHide: self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOn.png")) else: self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOff.png")) def __appFocusChanged(self, old, now): """ Private slot to handle a change of the focus. @param old reference to the widget, that lost focus (QWidget or None) @param now reference to the widget having the focus (QWidget or None) """ self.__hasFocus = self.isAncestorOf(now) if self.__autoHide and not self.__hasFocus and not self.isMinimized(): self.shrink() elif self.__autoHide and self.__hasFocus and self.isMinimized(): self.expand() def enterEvent(self, event): """ Protected method to handle the mouse entering this widget. @param event reference to the event (QEvent) """ if self.__autoHide and self.isMinimized(): self.expand() else: self.__cancelDelayTimer() def leaveEvent(self, event): """ Protected method to handle the mouse leaving this widget. @param event reference to the event (QEvent) """ if self.__autoHide and not self.__hasFocus and not self.isMinimized(): self.shrink() else: self.__cancelDelayTimer() def shutdown(self): """ Public method to shut down the object. This method does some preparations so the object can be deleted properly. It disconnects from the focusChanged signal in order to avoid trouble later on. """ e5App().focusChanged[QWidget, QWidget].disconnect( self.__appFocusChanged)
def load_settings_widgets_from_pipeline_groupbox(self, position): """ Extracts all widgets from a single algorithm and returns a QBoxLayout Args: alg: the alg instance we extract from Returns: a QBoxLayout containing all widgets for this particular alg. """ alg = self.pipeline.executed_cats[position].active_algorithm print("alg " + str(alg)) print("cat " + str(self.pipeline.executed_cats[position])) empty_flag = True groupOfSliders = QGroupBox() sp = QSizePolicy() sp.setVerticalPolicy(QSizePolicy.Preferred) # groupOfSliders.setSizePolicy(sp) groupOfSliderssLayout = QBoxLayout(QBoxLayout.TopToBottom) groupOfSliderssLayout.setContentsMargins(0, -0, -0, 0) groupOfSliderssLayout.setAlignment(Qt.AlignTop) groupOfSliderssLayout.setSpacing(0) print("Build Slider @ "+ str(position)) # create integer sliders for slider in alg.integer_sliders: empty_flag = False print("slider.value " + str(slider.value)) print("slider " + str(slider)) #print(alg.get_name() + ": add slider (int).") groupOfSliderssLayout.addWidget( SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value, slider.set_value, False)) # create float sliders for slider in alg.float_sliders: empty_flag = False #print(alg.get_name() + ": add slider (float).") groupOfSliderssLayout.addWidget( SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value, slider.set_value, True), 0, Qt.AlignTop) # create checkboxes for checkbox in alg.checkboxes: empty_flag = False #print(alg.get_name() + ": add checkbox.") groupOfSliderssLayout.addWidget(CheckBoxWidget(checkbox.name, checkbox.value, checkbox.set_value), 0, Qt.AlignTop) # create dropdowns for combobox in alg.drop_downs: empty_flag = False #print(alg.get_name() + ": add combobox.") groupOfSliderssLayout.addWidget( ComboBoxWidget(combobox.name, combobox.options, combobox.set_value, combobox.value), 0, Qt.AlignTop) if empty_flag: label = QLabel() label.setText("This algorithm has no Settings.") groupOfSliderssLayout.addWidget(label, 0, Qt.AlignHCenter) groupOfSliders.setLayout(groupOfSliderssLayout) return groupOfSliders
def newbeta(self): #self.setStyleSheet("QPushButton { margin: 450pxself.setLayout(self.box) try: self.labe = QLabel(self) self.labe.setText("Welcome") self.labe.setAlignment(Qt.AlignCenter) self.labe.setFont(lf) self.labe.resize(160, 100) self.label = QLabel(self) self.label.setText("**Enter your credentials to login to Register") self.l1 = QLabel(self) self.l1.setText(' Registration Form') self.l1.resize(150, 100) self.l2 = QLabel(self) self.l2.setText(' Full Name') self.l2.resize(150, 100) self.l2.move(0.32 * sw, 0.22 * sh) self.fnme = QLineEdit(self) self.fnme.setText("Full Name") self.l3 = QLabel(self) self.l3.setText(' Username') self.us = QLineEdit(self) self.us.setText("Username") self.l4 = QLabel(self) self.l4.setText(' Password') self.us1 = QLineEdit(self) self.us1.setText("Password") self.us1.setEchoMode(QLineEdit.PasswordEchoOnEdit) self.l5 = QLabel(self) self.l5.setText(' Confirm Password') self.l5.resize(150, 100) self.l5.move(0.32 * sw, 0.40 * sh) self.us2 = QLineEdit(self) self.us2.setText("Confirm ") self.us2.setEchoMode(QLineEdit.Password) self.l6 = QLabel(self) self.l6.setText(' Roll No') self.us3 = QLineEdit(self) self.us3.setText("Roll No") self.l7 = QLabel(self) self.l7.setText(' Gender') self.gen = QComboBox(self) self.gen.addItem(" Male", ) self.gen.addItem(" Female", ) self.gen.addItem(" Others", ) self.current = 'None' self.gen.activated.connect(self.handleActivated) self.l8 = QLabel(self) self.l8.setText(' Date of Birth') self.dt = QPushButton('Calendar', self) self.dt.setToolTip('Click Here to see the Calendar ') #self.dt.clicked.connect(dante) self.l9 = QLabel(self) self.l9.setText(' email ID') self.us6 = QLineEdit(self) self.us6.setText(" email ID") self.ag = QCheckBox("I Agree To Terms And Condition", self) self.but1 = QPushButton('Reset', self) self.but1.setToolTip('Click Here To Go Back To Sign-In Form') self.but1.resize(170, 20) self.but1.clicked.connect(lambda: self.on_reset1('regclear')) self.butt2 = QPushButton('Back', self) self.butt2.setToolTip('Click Here to Reset The Form') self.butt2.clicked.connect(lambda: self.on_back) self.butt3 = QPushButton('Register', self) self.butt3.setToolTip('Click here to Register And use the App') self.butt3.clicked.connect(self.on_yes) box = QBoxLayout(QBoxLayout.LeftToRight) box.stretch(1) box.setSpacing(1) box.addWidget(self.but1) box.addWidget(self.butt2) box.addWidget(self.butt3) ay1 = QBoxLayout(QBoxLayout.LeftToRight) aya = QBoxLayout(QBoxLayout.LeftToRight) ay2 = QBoxLayout(QBoxLayout.LeftToRight) ay3 = QBoxLayout(QBoxLayout.LeftToRight) ay4 = QBoxLayout(QBoxLayout.LeftToRight) ay5 = QBoxLayout(QBoxLayout.LeftToRight) ay6 = QBoxLayout(QBoxLayout.LeftToRight) ay7 = QBoxLayout(QBoxLayout.LeftToRight) ay8 = QBoxLayout(QBoxLayout.LeftToRight) ay9 = QBoxLayout(QBoxLayout.LeftToRight) ay10 = QBoxLayout(QBoxLayout.LeftToRight) ay1.addWidget(self.labe) aya.addWidget(self.label) aya.addWidget(self.l1) ay2.addWidget(self.l2) ay2.addWidget(self.fnme) ay3.addWidget(self.l3) ay3.addWidget(self.us) ay4.addWidget(self.l4) ay4.addWidget(self.us1) ay5.addWidget(self.l5) ay5.addWidget(self.us2) ay6.addWidget(self.l6) ay6.addWidget(self.us3) ay7.addWidget(self.l7) ay7.addWidget(self.gen) ay8.addWidget(self.l8) ay8.addWidget(self.dt) #ay8.addWidget(self.us5) ay9.addWidget(self.l9) ay9.addWidget(self.us6) ay10.addWidget(self.ag) #self.la.setContentsMargins(0.44*sw, 0.2*sh, 0.44*sw,0 box1 = QVBoxLayout() box1.stretch(1) box1.setSpacing(8) #box1.setContentsMargins(0.44*sw, 0.1*sh, 0.44*sw,0.1*sh) box1.addLayout(ay1) box1.addLayout(aya) box1.addLayout(ay2) box1.addLayout(ay3) box1.addLayout(ay4) box1.addLayout(ay5) box1.addLayout(ay6) box1.addLayout(ay7) box1.addLayout(ay8) box1.addLayout(ay9) box1.addLayout(ay10) box1.addLayout(box) self.reGGG.setLayout(box1) except Exception as dumm1: print(dumm1)
class E5SideBar(QWidget): """ Class implementing a sidebar with a widget area, that is hidden or shown, if the current tab is clicked again. """ Version = 1 North = 0 East = 1 South = 2 West = 3 def __init__(self, orientation=None, delay=200, parent=None): """ Constructor @param orientation orientation of the sidebar widget (North, East, South, West) @param delay value for the expand/shrink delay in milliseconds (integer) @param parent parent widget (QWidget) """ super(E5SideBar, self).__init__(parent) self.__tabBar = QTabBar() self.__tabBar.setDrawBase(True) self.__tabBar.setShape(QTabBar.RoundedNorth) self.__tabBar.setUsesScrollButtons(True) self.__tabBar.setDrawBase(False) self.__stackedWidget = QStackedWidget(self) self.__stackedWidget.setContentsMargins(0, 0, 0, 0) self.__autoHideButton = QToolButton() self.__autoHideButton.setCheckable(True) self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOff.png")) self.__autoHideButton.setChecked(True) self.__autoHideButton.setToolTip( self.tr("Deselect to activate automatic collapsing")) self.barLayout = QBoxLayout(QBoxLayout.LeftToRight) self.barLayout.setContentsMargins(0, 0, 0, 0) self.layout = QBoxLayout(QBoxLayout.TopToBottom) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.barLayout.addWidget(self.__autoHideButton) self.barLayout.addWidget(self.__tabBar) self.layout.addLayout(self.barLayout) self.layout.addWidget(self.__stackedWidget) self.setLayout(self.layout) # initialize the delay timer self.__actionMethod = None self.__delayTimer = QTimer(self) self.__delayTimer.setSingleShot(True) self.__delayTimer.setInterval(delay) self.__delayTimer.timeout.connect(self.__delayedAction) self.__minimized = False self.__minSize = 0 self.__maxSize = 0 self.__bigSize = QSize() self.splitter = None self.splitterSizes = [] self.__hasFocus = False # flag storing if this widget or any child has the focus self.__autoHide = False self.__tabBar.installEventFilter(self) self.__orientation = E5SideBar.North if orientation is None: orientation = E5SideBar.North self.setOrientation(orientation) self.__tabBar.currentChanged[int].connect( self.__stackedWidget.setCurrentIndex) e5App().focusChanged.connect(self.__appFocusChanged) self.__autoHideButton.toggled[bool].connect(self.__autoHideToggled) def setSplitter(self, splitter): """ Public method to set the splitter managing the sidebar. @param splitter reference to the splitter (QSplitter) """ self.splitter = splitter self.splitter.splitterMoved.connect(self.__splitterMoved) self.splitter.setChildrenCollapsible(False) index = self.splitter.indexOf(self) self.splitter.setCollapsible(index, False) def __splitterMoved(self, pos, index): """ Private slot to react on splitter moves. @param pos new position of the splitter handle (integer) @param index index of the splitter handle (integer) """ if self.splitter: self.splitterSizes = self.splitter.sizes() def __delayedAction(self): """ Private slot to handle the firing of the delay timer. """ if self.__actionMethod is not None: self.__actionMethod() def setDelay(self, delay): """ Public method to set the delay value for the expand/shrink delay in milliseconds. @param delay value for the expand/shrink delay in milliseconds (integer) """ self.__delayTimer.setInterval(delay) def delay(self): """ Public method to get the delay value for the expand/shrink delay in milliseconds. @return value for the expand/shrink delay in milliseconds (integer) """ return self.__delayTimer.interval() def __cancelDelayTimer(self): """ Private method to cancel the current delay timer. """ self.__delayTimer.stop() self.__actionMethod = None def shrink(self): """ Public method to record a shrink request. """ self.__delayTimer.stop() self.__actionMethod = self.__shrinkIt self.__delayTimer.start() def __shrinkIt(self): """ Private method to shrink the sidebar. """ self.__minimized = True self.__bigSize = self.size() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() self.__maxSize = self.maximumHeight() else: self.__minSize = self.minimumSizeHint().width() self.__maxSize = self.maximumWidth() if self.splitter: self.splitterSizes = self.splitter.sizes() self.__stackedWidget.hide() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.setFixedHeight(self.__tabBar.minimumSizeHint().height()) else: self.setFixedWidth(self.__tabBar.minimumSizeHint().width()) self.__actionMethod = None def expand(self): """ Public method to record a expand request. """ self.__delayTimer.stop() self.__actionMethod = self.__expandIt self.__delayTimer.start() def __expandIt(self): """ Private method to expand the sidebar. """ self.__minimized = False self.__stackedWidget.show() self.resize(self.__bigSize) if self.__orientation in [E5SideBar.North, E5SideBar.South]: minSize = max(self.__minSize, self.minimumSizeHint().height()) self.setMinimumHeight(minSize) self.setMaximumHeight(self.__maxSize) else: minSize = max(self.__minSize, self.minimumSizeHint().width()) self.setMinimumWidth(minSize) self.setMaximumWidth(self.__maxSize) if self.splitter: self.splitter.setSizes(self.splitterSizes) self.__actionMethod = None def isMinimized(self): """ Public method to check the minimized state. @return flag indicating the minimized state (boolean) """ return self.__minimized def isAutoHiding(self): """ Public method to check, if the auto hide function is active. @return flag indicating the state of auto hiding (boolean) """ return self.__autoHide def eventFilter(self, obj, evt): """ Public method to handle some events for the tabbar. @param obj reference to the object (QObject) @param evt reference to the event object (QEvent) @return flag indicating, if the event was handled (boolean) """ if obj == self.__tabBar: if evt.type() == QEvent.MouseButtonPress: pos = evt.pos() for i in range(self.__tabBar.count()): if self.__tabBar.tabRect(i).contains(pos): break if i == self.__tabBar.currentIndex(): if self.isMinimized(): self.expand() else: self.shrink() return True elif self.isMinimized(): self.expand() elif evt.type() == QEvent.Wheel: if qVersion() >= "5.0.0": delta = evt.angleDelta().y() else: delta = evt.delta() if delta > 0: self.prevTab() else: self.nextTab() return True return QWidget.eventFilter(self, obj, evt) def addTab(self, widget, iconOrLabel, label=None): """ Public method to add a tab to the sidebar. @param widget reference to the widget to add (QWidget) @param iconOrLabel reference to the icon or the label text of the tab (QIcon, string) @param label the labeltext of the tab (string) (only to be used, if the second parameter is a QIcon) """ if label: index = self.__tabBar.addTab(iconOrLabel, label) self.__tabBar.setTabToolTip(index, label) else: index = self.__tabBar.addTab(iconOrLabel) self.__tabBar.setTabToolTip(index, iconOrLabel) self.__stackedWidget.addWidget(widget) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def insertTab(self, index, widget, iconOrLabel, label=None): """ Public method to insert a tab into the sidebar. @param index the index to insert the tab at (integer) @param widget reference to the widget to insert (QWidget) @param iconOrLabel reference to the icon or the labeltext of the tab (QIcon, string) @param label the labeltext of the tab (string) (only to be used, if the second parameter is a QIcon) """ if label: index = self.__tabBar.insertTab(index, iconOrLabel, label) self.__tabBar.setTabToolTip(index, label) else: index = self.__tabBar.insertTab(index, iconOrLabel) self.__tabBar.setTabToolTip(index, iconOrLabel) self.__stackedWidget.insertWidget(index, widget) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def removeTab(self, index): """ Public method to remove a tab. @param index the index of the tab to remove (integer) """ self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index)) self.__tabBar.removeTab(index) if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() else: self.__minSize = self.minimumSizeHint().width() def clear(self): """ Public method to remove all tabs. """ while self.count() > 0: self.removeTab(0) def prevTab(self): """ Public slot used to show the previous tab. """ ind = self.currentIndex() - 1 if ind == -1: ind = self.count() - 1 self.setCurrentIndex(ind) self.currentWidget().setFocus() def nextTab(self): """ Public slot used to show the next tab. """ ind = self.currentIndex() + 1 if ind == self.count(): ind = 0 self.setCurrentIndex(ind) self.currentWidget().setFocus() def count(self): """ Public method to get the number of tabs. @return number of tabs in the sidebar (integer) """ return self.__tabBar.count() def currentIndex(self): """ Public method to get the index of the current tab. @return index of the current tab (integer) """ return self.__stackedWidget.currentIndex() def setCurrentIndex(self, index): """ Public slot to set the current index. @param index the index to set as the current index (integer) """ self.__tabBar.setCurrentIndex(index) self.__stackedWidget.setCurrentIndex(index) if self.isMinimized(): self.expand() def currentWidget(self): """ Public method to get a reference to the current widget. @return reference to the current widget (QWidget) """ return self.__stackedWidget.currentWidget() def setCurrentWidget(self, widget): """ Public slot to set the current widget. @param widget reference to the widget to become the current widget (QWidget) """ self.__stackedWidget.setCurrentWidget(widget) self.__tabBar.setCurrentIndex(self.__stackedWidget.currentIndex()) if self.isMinimized(): self.expand() def indexOf(self, widget): """ Public method to get the index of the given widget. @param widget reference to the widget to get the index of (QWidget) @return index of the given widget (integer) """ return self.__stackedWidget.indexOf(widget) def isTabEnabled(self, index): """ Public method to check, if a tab is enabled. @param index index of the tab to check (integer) @return flag indicating the enabled state (boolean) """ return self.__tabBar.isTabEnabled(index) def setTabEnabled(self, index, enabled): """ Public method to set the enabled state of a tab. @param index index of the tab to set (integer) @param enabled enabled state to set (boolean) """ self.__tabBar.setTabEnabled(index, enabled) def orientation(self): """ Public method to get the orientation of the sidebar. @return orientation of the sidebar (North, East, South, West) """ return self.__orientation def setOrientation(self, orient): """ Public method to set the orientation of the sidebar. @param orient orientation of the sidebar (North, East, South, West) """ if orient == E5SideBar.North: self.__tabBar.setShape(QTabBar.RoundedNorth) self.__tabBar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.barLayout.setDirection(QBoxLayout.LeftToRight) self.layout.setDirection(QBoxLayout.TopToBottom) self.layout.setAlignment(self.barLayout, Qt.AlignLeft) elif orient == E5SideBar.East: self.__tabBar.setShape(QTabBar.RoundedEast) self.__tabBar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.barLayout.setDirection(QBoxLayout.TopToBottom) self.layout.setDirection(QBoxLayout.RightToLeft) self.layout.setAlignment(self.barLayout, Qt.AlignTop) elif orient == E5SideBar.South: self.__tabBar.setShape(QTabBar.RoundedSouth) self.__tabBar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.barLayout.setDirection(QBoxLayout.LeftToRight) self.layout.setDirection(QBoxLayout.BottomToTop) self.layout.setAlignment(self.barLayout, Qt.AlignLeft) elif orient == E5SideBar.West: self.__tabBar.setShape(QTabBar.RoundedWest) self.__tabBar.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.barLayout.setDirection(QBoxLayout.TopToBottom) self.layout.setDirection(QBoxLayout.LeftToRight) self.layout.setAlignment(self.barLayout, Qt.AlignTop) self.__orientation = orient def tabIcon(self, index): """ Public method to get the icon of a tab. @param index index of the tab (integer) @return icon of the tab (QIcon) """ return self.__tabBar.tabIcon(index) def setTabIcon(self, index, icon): """ Public method to set the icon of a tab. @param index index of the tab (integer) @param icon icon to be set (QIcon) """ self.__tabBar.setTabIcon(index, icon) def tabText(self, index): """ Public method to get the text of a tab. @param index index of the tab (integer) @return text of the tab (string) """ return self.__tabBar.tabText(index) def setTabText(self, index, text): """ Public method to set the text of a tab. @param index index of the tab (integer) @param text text to set (string) """ self.__tabBar.setTabText(index, text) def tabToolTip(self, index): """ Public method to get the tooltip text of a tab. @param index index of the tab (integer) @return tooltip text of the tab (string) """ return self.__tabBar.tabToolTip(index) def setTabToolTip(self, index, tip): """ Public method to set the tooltip text of a tab. @param index index of the tab (integer) @param tip tooltip text to set (string) """ self.__tabBar.setTabToolTip(index, tip) def tabWhatsThis(self, index): """ Public method to get the WhatsThis text of a tab. @param index index of the tab (integer) @return WhatsThis text of the tab (string) """ return self.__tabBar.tabWhatsThis(index) def setTabWhatsThis(self, index, text): """ Public method to set the WhatsThis text of a tab. @param index index of the tab (integer) @param text WhatsThis text to set (string) """ self.__tabBar.setTabWhatsThis(index, text) def widget(self, index): """ Public method to get a reference to the widget associated with a tab. @param index index of the tab (integer) @return reference to the widget (QWidget) """ return self.__stackedWidget.widget(index) def saveState(self): """ Public method to save the state of the sidebar. @return saved state as a byte array (QByteArray) """ if len(self.splitterSizes) == 0: if self.splitter: self.splitterSizes = self.splitter.sizes() self.__bigSize = self.size() if self.__orientation in [E5SideBar.North, E5SideBar.South]: self.__minSize = self.minimumSizeHint().height() self.__maxSize = self.maximumHeight() else: self.__minSize = self.minimumSizeHint().width() self.__maxSize = self.maximumWidth() data = QByteArray() stream = QDataStream(data, QIODevice.WriteOnly) stream.setVersion(QDataStream.Qt_4_6) stream.writeUInt16(self.Version) stream.writeBool(self.__minimized) stream << self.__bigSize stream.writeUInt16(self.__minSize) stream.writeUInt16(self.__maxSize) stream.writeUInt16(len(self.splitterSizes)) for size in self.splitterSizes: stream.writeUInt16(size) stream.writeBool(self.__autoHide) return data def restoreState(self, state): """ Public method to restore the state of the sidebar. @param state byte array containing the saved state (QByteArray) @return flag indicating success (boolean) """ if state.isEmpty(): return False if self.__orientation in [E5SideBar.North, E5SideBar.South]: minSize = self.layout.minimumSize().height() maxSize = self.maximumHeight() else: minSize = self.layout.minimumSize().width() maxSize = self.maximumWidth() data = QByteArray(state) stream = QDataStream(data, QIODevice.ReadOnly) stream.setVersion(QDataStream.Qt_4_6) stream.readUInt16() # version minimized = stream.readBool() if minimized and not self.__minimized: self.shrink() stream >> self.__bigSize self.__minSize = max(stream.readUInt16(), minSize) self.__maxSize = max(stream.readUInt16(), maxSize) count = stream.readUInt16() self.splitterSizes = [] for i in range(count): self.splitterSizes.append(stream.readUInt16()) self.__autoHide = stream.readBool() self.__autoHideButton.setChecked(not self.__autoHide) if not minimized: self.expand() return True ####################################################################### ## methods below implement the autohide functionality ####################################################################### def __autoHideToggled(self, checked): """ Private slot to handle the toggling of the autohide button. @param checked flag indicating the checked state of the button (boolean) """ self.__autoHide = not checked if self.__autoHide: self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOn.png")) else: self.__autoHideButton.setIcon( UI.PixmapCache.getIcon("autoHideOff.png")) def __appFocusChanged(self, old, now): """ Private slot to handle a change of the focus. @param old reference to the widget, that lost focus (QWidget or None) @param now reference to the widget having the focus (QWidget or None) """ self.__hasFocus = self.isAncestorOf(now) if self.__autoHide and not self.__hasFocus and not self.isMinimized(): self.shrink() elif self.__autoHide and self.__hasFocus and self.isMinimized(): self.expand() def enterEvent(self, event): """ Protected method to handle the mouse entering this widget. @param event reference to the event (QEvent) """ if self.__autoHide and self.isMinimized(): self.expand() else: self.__cancelDelayTimer() def leaveEvent(self, event): """ Protected method to handle the mouse leaving this widget. @param event reference to the event (QEvent) """ if self.__autoHide and not self.__hasFocus and not self.isMinimized(): self.shrink() else: self.__cancelDelayTimer() def shutdown(self): """ Public method to shut down the object. This method does some preparations so the object can be deleted properly. It disconnects from the focusChanged signal in order to avoid trouble later on. """ e5App().focusChanged.disconnect(self.__appFocusChanged)
class CToolBarArea(QWidget): signalDragStart = pyqtSignal() signalDragEnd = pyqtSignal() signalItemDropped = pyqtSignal(CToolBarAreaItem, QWidget, int) def __init__(self, parent, orientation): super().__init__(parent) self.editor = parent self.orientation = orientation self.dropTargetSpacer = None self.actionContextPosition = QPoint() self.isLocked = False if self.orientation == Qt.Horizontal: self.layout_ = QBoxLayout(QBoxLayout.LeftToRight) else: self.layout_ = QBoxLayout(QBoxLayout.TopToBottom) self.layout_.setSpacing(0) self.layout_.setContentsMargins(0, 0, 0, 0) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.setLayout(self.layout_) self.setAcceptDrops(True) self.setContextMenuPolicy(Qt.CustomContextMenu) # print ( "CToolBarArea.__init__", parent ) def getOrientation(self): return self.orientation def getToolBars(self): items = getAllItems(self) toolBarItems = [] for item in items: if item.getType() != CToolBarAreaType.ToolBar: continue toolBarItems.append(item) return toolBarItems def getLargestItemMinimumSize(self): minSize = self.minimumSize() items = getAllItems(self) for item in items: minSize = minSize.expandedTo(item.getMinimumSize()) return minSize def setOrientation(self, orientation): self.orientation = orientation self.layout_.setDirection(QBoxLayout.LeftToRight if self.orientation == Qt.Horizontal else QBoxLayout.TopToBottom) self.updateLayoutAlignment() items = getAllItems(self) for item in items: item.setOrientation(self.orientation) def setActionContextPosition(self, actionContextPosition): self.actionContextPosition = actionContextPosition def fillContextMenu(self, menu): pass def addItem(self, item, targetIndex): item.signalDragStart.connect(self.onDragStart) item.signalDragEnd.connect(self.onDragEnd) item.setOrientation(self.orientation) item.setLocked(self.isLocked) self.layout_.insertWidget(targetIndex, item) item.setArea(self) def addToolBar(self, toolBar, targetIndex): self.addItem(CToolBarItem(self, toolBar, self.orientation), targetIndex) def addSpacer(self, spacerType, targetIndex): self.addItem(CSpacerItem(self, spacerType, self.orientation), targetIndex) if spacerType == CSpacerType.Expanding: self.layout_.setAlignment(0) def removeItem(self, item): self.layout_.removeWidget(item) item.signalDragStart.disconnect(self) item.signalDragEnd.disconnect(self) self.updateLayoutAlignment(item) def deleteToolBar(self, toolBarItem): if self.isAncestorOf(toolBarItem): qWarning("Trying to remove non-owned toolbar from area") return toolBarItem.deleteLater() def hideAll(self): items = getAllItems(self) for item in items: item.setVisible(False) def findToolBarByName(self, szToolBarName): toolBarItems = self.findChildren(CToolBarItem, "", Qt.FindDirectChildrenOnly) for toolBarItem in toolBarItems: if toolBarItem.getName() == szToolBarName: return toolBarItem print("Toolbar not found: %s" % szToolBarName) return None def setLocked(self, isLocked): self.isLocked = isLocked items = getAllItems(self) for item in items: item.setLocked(isLocked) def getState(self): pass def setState(self, state): pass def dragEnterEvent(self, event): print("CToolBarArea.dragEnterEvent", event) dragDropData = CDragDropData.fromMimeData(event.mimeData()) if dragDropData.hasCustomData(CToolBarAreaItem.getMimeType()): byteArray = dragDropData.getCustomData( CToolBarAreaItem.getMimeType()) stream = QDataStream(byteArray) value = None stream >> value draggedItem = value if isinstance(value, CToolBarAreaItem) else None if not self.parentWidget().isAncestorOf(draggedItem): return event.acceptProposedAction() self.setProperty("dragHover", True) self.style().unpolish(self) self.style().polish(self) def dragMoveEvent(self, event): dragDropData = CDragDropData.fromMimeData(event.mimeData()) if dragDropData.hasCustomData(CToolBarAreaItem.getMimeType()): targetIndex = self.getPlacementIndexFromPosition( self.mapToGlobal(event.pos())) event.acceptProposedAction() if self.dropTargetSpacer and targetIndex == self.layout_.indexOf( self.dropTargetSpacer): return byteArray = dragDropData.getCustomData( CToolBarAreaItem.getMimeType()) stream = QDataStream(byteArray) value = None stream >> value draggedItem = value if isinstance(value, CToolBarAreaItem) else None if not self.parentWidget().isAncestorOf(draggedItem): return spacerWidth = draggedItem.width() spacerHeight = draggedItem.height() if draggedItem.getOrientation() != self.orientation: tempWidth = spacerWidth spacerWidth = spacerHeight spacerHeight = tempWidth if self.dropTargetSpacer == None: self.dropTargetSpacer = QSpacerItem(spacerWidth, spacerHeight, QSizePolicy.Fixed, QSizePolicy.Fixed) else: spacerIndex = self.layout_.indexOf(self.dropTargetSpacer) if spacerIndex == targetIndex - 1 or ( targetIndex == -1 and spacerIndex == self.layout_.count() - 1): return self.removeDropTargetSpacer() self.dropTargetSpacer = QSpacerItem(spacerWidth, spacerHeight, QSizePolicy.Fixed, QSizePolicy.Fixed) self.layout_.insertSpacerItem(targetIndex, self.dropTargetSpacer) def dragLeaveEvent(self, event): self.removeDropTargetSpacer() self.setProperty("dragHover", False) self.style().unpolish(self) self.style().polish(self) def dropEvent(self, event): dragDropData = CDragDropData.fromMimeData(event.mimeData()) if dragDropData.hasCustomData(CToolBarAreaItem.getMimeType()): event.acceptProposedAction() byteArray = dragDropData.getCustomData( CToolBarAreaItem.getMimeType()) stream = QDataStream(byteArray) value = None stream >> value item = value if isinstance(value, CToolBarAreaItem) else None targetIndex = -1 if self.dropTargetSpacer: targetIndex = self.layout_.indexOf(self.dropTargetSpacer) containerIndex = self.layout_.indexOf(item) if containerIndex >= 0 and containerIndex < targetIndex: targetIndex -= 1 self.removeDropTargetSpacer() if targetIndex >= self.layout_.count(): targetIndex = -1 self.signalItemDropped.emit(item, self, targetIndex) def customEvent(self, event): pass def paintEvent(self, event): styleOption = QStyleOption() styleOption.initFrom(self) painter = QPainter(self) self.style().drawPrimitive(QStyle.PE_Widget, styleOption, painter, self) def onDragStart(self, item): self.updateLayoutAlignment(item) item.setVisiable(False) self.signalDragStart.emit() def onDragEnd(self, item): item.setVisiable(True) self.signalDragEnd.emit() def removeDropTargetSpacer(self): if self.dropTargetSpacer: self.layout_.removeItem(self.dropTargetSpacer) self.dropTargetSpacer = None def indexForItem(self, item): return self.layout_.indexOf(item) def moveItem(self, item, destinationIndex): sourceIndex = self.indexForItem(item) if sourceIndex == destinationIndex: return self.layout_.insertWidget(destinationIndex, item) def updateLayoutAlignment(self, itemToBeRemoved=None): spacers = self.findChildren(CSpacerItem, "", Qt.FindDirectChildrenOnly) expandingSpacers = [] for spacer in spacers: if spacer.getSpacerType() == CSpacerType.Expanding: expandingSpacers.append(spacer) if len(expandingSpacers) == 0 or len(expandingSpacers) != 0 or ( len(expandingSpacers) == 1 and expandingSpacers[0] == itemToBeRemoved): if self.orientation == Qt.Horizontal: self.layout_.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) else: self.layout_.setAlignment(Qt.AlignTop | Qt.AlignHCenter) def getItemAtPosition(self, globalPos): object = QApplication.widgetAt(globalPos) if object == None or object == self: return None item = object if isinstance(object, CToolBarAreaItem) else None while item == None and object.parent(): object = object.parent() item = object if isinstance(object, CToolBarAreaItem) else None return item def getPlacementIndexFromPosition(self, globalPos): targetIndex = -1 item = self.getItemAtPosition(globalPos) if item == None: localPos = self.mapFromGlobal(globalPos) if self.dropTargetSpacer: geom = self.dropTargetSpacer.geometry() if geom.contains(localPos): targetIndex = self.layout_.indexOf(self.dropTargetSpacer) return targetIndex targetIndex = self.indexForItem(item) if self.orientation == Qt.Horizontal and item.mapFromGlobal( globalPos).x() > item.width() / 2: targetIndex += 1 elif self.orientation == Qt.Vertical and item.mapFromGlobal( globalPos).y() > item.height() / 2: targetIndex += 1 if targetIndex >= self.layout_.count(): targetIndex = -1 return targetIndex
class CToolBarAreaItem(QWidget): signalDragStart = pyqtSignal(QWidget) signalDragEnd = pyqtSignal(QWidget) def __init__(self, area, orientation): super().__init__() self.area = area self.orientation = orientation self.content = None self.layout_ = QBoxLayout(QBoxLayout.LeftToRight if ( orientation == Qt.Horizontal) else QBoxLayout.TopToBottom) self.layout_.setContentsMargins(0, 0, 0, 0) self.layout_.setSpacing(0) def setArea(self, area): self.area = area def setLocked(self, isLocked): self.dragHandle.setVisiable(not isLocked) def setOrientation(self, orientation): self.orientation = orientation self.layout_.setDirection(QBoxLayout.LeftToRight if ( orientation == Qt.Horizontal) else QBoxLayout.TopToBottom) self.dragHandle.setOrientation(orientation) def getType(self): pass def getArea(self): return self.area def getOrientation(self): return self.orientation def getMinimumSize(self): return self.minimumSize() def getMimeType(self): return "CToolBarAreaItem" def onDragStart(self): self.signalDragStart.emit(self) def onDragEnd(self): self.signalDragEnd.emit(self) def setContent(self, newContent): if self.content == None: self.content = newContent self.layout_.addWidget(self.content) self.layout_.replaceWidget(self.content, newContent) self.content.setVisiable(False) newContent.setVisiable(True) self.content.deleteLater() self.content = newContent def paintEvent(self, event): styleOption = QStyleOption() styleOption.initFrom(self) painter = QPainter(self) self.style().drawPrimitive(QStyle.PE_Widget, styleOption, painter, self)