class SideBarWidget(QFrame): """ """ def __init__(self, parent): super().__init__(parent) self.setAcceptDrops(True) self.parent_widget = parent self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self._widget_layout = QHBoxLayout(self) # widget stuff self._d_widget = QWidget(self) self._d_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self._widget_layout.addWidget(self._d_widget) self.main_layout = QVBoxLayout(self._d_widget) self.main_layout.setSpacing(0) self.main_layout.setContentsMargins(0,0,0,0) self.arrow_handle = misc.ArrowHandle(self) self.arrow_handle.CLICKED.connect(self.slide) self._widget_layout.addWidget(self.arrow_handle) self.setContentsMargins(0,0,-self.arrow_handle.width(),0) self.show_all_galleries_btn = QPushButton("Show all galleries") self.show_all_galleries_btn.clicked.connect(lambda:parent.manga_list_view.sort_model.set_gallery_list()) self.show_all_galleries_btn.clicked.connect(self.show_all_galleries_btn.hide) self.show_all_galleries_btn.setIcon(app_constants.CROSS_ICON_WH) self.show_all_galleries_btn.hide() self.main_layout.addWidget(self.show_all_galleries_btn) self.main_buttons_layout = QHBoxLayout() self.main_layout.addLayout(self.main_buttons_layout) # buttons bgroup = QButtonGroup(self) bgroup.setExclusive(True) self.lists_btn = QPushButton("") self.lists_btn.setIcon(app_constants.G_LISTS_ICON_WH) self.lists_btn.setCheckable(True) bgroup.addButton(self.lists_btn) self.artist_btn = QPushButton("") self.artist_btn.setIcon(app_constants.ARTISTS_ICON) self.artist_btn.setCheckable(True) bgroup.addButton(self.artist_btn) self.ns_tags_btn = QPushButton("") self.ns_tags_btn.setIcon(app_constants.NSTAGS_ICON) self.ns_tags_btn.setCheckable(True) bgroup.addButton(self.ns_tags_btn) self.lists_btn.setChecked(True) self.main_buttons_layout.addWidget(self.lists_btn) self.main_buttons_layout.addWidget(self.artist_btn) self.main_buttons_layout.addWidget(self.ns_tags_btn) # buttons contents self.stacked_layout = QStackedLayout() self.main_layout.addLayout(self.stacked_layout) # lists gallery_lists_dummy = QWidget(self) self.lists = GalleryLists(self) create_new_list_btn = QPushButton() create_new_list_btn.setIcon(QIcon(app_constants.PLUS_ICON)) create_new_list_btn.setIconSize(QSize(15, 15)) create_new_list_btn.clicked.connect(lambda: self.lists.create_new_list()) create_new_list_btn.adjustSize() create_new_list_btn.setFixedSize(create_new_list_btn.width(), create_new_list_btn.height()) create_new_list_btn.setToolTip("Create a new list!") lists_l = QVBoxLayout(gallery_lists_dummy) lists_l.setContentsMargins(0,0,0,0) lists_l.setSpacing(0) lists_l.addWidget(self.lists) lists_l.addWidget(create_new_list_btn) lists_index = self.stacked_layout.addWidget(gallery_lists_dummy) self.lists.GALLERY_LIST_CLICKED.connect(parent.manga_list_view.sort_model.set_gallery_list) self.lists.GALLERY_LIST_CLICKED.connect(self.show_all_galleries_btn.show) self.lists.GALLERY_LIST_REMOVED.connect(self.show_all_galleries_btn.click) self.lists_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(lists_index)) self.show_all_galleries_btn.clicked.connect(self.lists.clearSelection) self.show_all_galleries_btn.clicked.connect(self.lists._reset_selected) # artists self.artists_list = GalleryArtistsList(parent.manga_list_view.gallery_model, self) self.artists_list.artist_clicked.connect(lambda a: parent.search('artist:"{}"'.format(a))) artists_list_index = self.stacked_layout.addWidget(self.artists_list) self.artist_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(artists_list_index)) #self.lists.GALLERY_LIST_CLICKED.connect(self.artists_list.set_current_glist) self.show_all_galleries_btn.clicked.connect(self.artists_list.clearSelection) #self.show_all_galleries_btn.clicked.connect(lambda:self.artists_list.set_current_glist()) # ns_tags self.tags_tree = TagsTreeView(self) self.tags_tree.TAG_SEARCH.connect(parent.search) self.tags_tree.NEW_LIST.connect(self.lists.create_new_list) self.tags_tree.setHeaderHidden(True) self.show_all_galleries_btn.clicked.connect(self.tags_tree.clearSelection) self.tags_layout = QVBoxLayout(self.tags_tree) ns_tags_index = self.stacked_layout.addWidget(self.tags_tree) self.ns_tags_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(ns_tags_index)) self.slide_animation = misc.create_animation(self, "maximumSize") self.slide_animation.stateChanged.connect(self._slide_hide) self.slide_animation.setEasingCurve(QEasingCurve.InOutQuad) def _slide_hide(self, state): size = self.sizeHint() if state == self.slide_animation.Stopped: if self.arrow_handle.current_arrow == self.arrow_handle.OUT: self._d_widget.hide() elif self.slide_animation.Running: if self.arrow_handle.current_arrow == self.arrow_handle.IN: if not self.parent_widget.current_manga_view.allow_sidebarwidget: self.arrow_handle.current_arrow = self.arrow_handle.OUT self.arrow_handle.update() else: self._d_widget.show() def slide(self, state): self.slide_animation.setEndValue(QSize(self.arrow_handle.width() * 2, self.height())) if state: self.slide_animation.setDirection(self.slide_animation.Forward) self.slide_animation.start() else: self.slide_animation.setDirection(self.slide_animation.Backward) self.slide_animation.start() def showEvent(self, event): super().showEvent(event) if not app_constants.SHOW_SIDEBAR_WIDGET: self.arrow_handle.click() def _init_size(self, event=None): h = self.parent_widget.height() self._max_width = 250 self.updateGeometry() self.setMaximumWidth(self._max_width) self.slide_animation.setStartValue(QSize(self._max_width, h)) def resizeEvent(self, event): self._init_size(event) return super().resizeEvent(event)
def __init__(self, **kwargs): super(SplitManager, self).__init__(**kwargs) self.root = self.SplitterClass(orientation=Qt.Horizontal) layout = QStackedLayout() self.setLayout(layout) layout.addWidget(self.root) self.optimizeTimer = QTimer() self.optimizeTimer.setInterval(0) self.optimizeTimer.setSingleShot(True) self.optimizeTimer.timeout.connect(self._optimize) self.addCategory('splitmanager')
def __init__(self, parent=None): super(ProjectTreeColumn, self).__init__(parent, Qt.WindowStaysOnTopHint) vbox = QVBoxLayout(self) vbox.setSizeConstraint(QVBoxLayout.SetDefaultConstraint) vbox.setContentsMargins(0, 0, 0, 0) self._buttons = [] self._combo_project = QComboBox() self._combo_project.setMinimumHeight(30) self._combo_project.setContextMenuPolicy(Qt.CustomContextMenu) vbox.addWidget(self._combo_project) self._projects_area = QStackedLayout() logger.debug("This is the projects area") logger.debug(self._projects_area) vbox.addLayout(self._projects_area) self.projects = [] self._combo_project.currentIndexChanged[int].connect(self._change_current_project) self._combo_project.customContextMenuRequested['const QPoint &'].connect(self.context_menu_for_root) connections = ( {'target': 'main_container', 'signal_name': 'addToProject',#(QString) 'slot': self._add_file_to_project}, {'target': 'main_container', 'signal_name': 'showFileInExplorer',#(QString) 'slot': self._show_file_in_explorer}, ) IDE.register_service('projects_explorer', self) IDE.register_signals('projects_explorer', connections) ExplorerContainer.register_tab(translations.TR_TAB_PROJECTS, self)
def __init__(self, original=False): super(ComboEditor, self).__init__(None, Qt.WindowStaysOnTopHint) self.__original = original self.__undocked = [] self._symbols_index = [] vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.bar = ActionBar(main_combo=original) vbox.addWidget(self.bar) self.stacked = QStackedLayout() vbox.addLayout(self.stacked) self._main_container = IDE.get_service('main_container') if not self.__original: self._main_container.fileOpened.connect(self._file_opened_by_main) self.bar.combo.showComboSelector.connect(self._main_container.change_tab) self.bar.changeCurrent.connect(self._set_current) self.bar.editorSplited.connect(self.split_editor) self.bar.runFile[str].connect(self._run_file) self.bar.closeFile.connect(lambda: self.closeSplit.emit(self)) self.bar.addToProject[str].connect(self._add_to_project) self.bar.showFileInExplorer.connect(self._show_file_in_explorer) self.bar.goToSymbol.connect(self._go_to_symbol) self.bar.undockEditor.connect(self.undock_editor) self.bar.reopenTab[str].connect(self._main_container.open_file) self.bar.recentTabsModified.connect(self._main_container.recent_files_changed) self.bar.code_navigator.btnPrevious.clicked['bool'].connect(lambda: self._navigate_code(self.NAVIGATE.prev)) self.bar.code_navigator.btnNext.clicked['bool'].connect(lambda: self._navigate_code(self.NAVIGATE.prev))
def __init__(self, win_id, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._option = None self._hbox = QHBoxLayout(self) self.set_hbox_padding() objreg.get('config').changed.connect(self.set_hbox_padding) self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self.prompt = prompt.Prompt(win_id) self._stack.addWidget(self.prompt) self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() prompter = objreg.get('prompter', scope='window', window=self._win_id) prompter.show_prompt.connect(self._show_prompt_widget) prompter.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) self.tabindex = tabindex.TabIndex() self._hbox.addWidget(self.tabindex) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) objreg.get('config').changed.connect(self.maybe_hide) QTimer.singleShot(0, self.maybe_hide)
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.actionAuswahl = QComboBox() self.actionAuswahl.addItem("Einen Sportler bearbeiten") self.actionAuswahl.addItem("Liste aller Sportler anzeigen") self.actionAuswahl.addItem("Eine Ergebnissliste bearbeiten") self.actionAuswahl.addItem("Ergebnisse & Urkunden drucken") self.actionAuswahl.addItem("Ergebnissvorlagen drucken") self.actionAuswahl.setEditable(False) self.actionAuswahl.activated.connect(self.setAction) self.actionSportlerEdit = SportlerEdit() self.actionSportlerShow = SportlerShow() self.actionErgebnissListe = ErgebnissListe() self.actionErgebnisseDrucken = ErgebnisseDrucken() self.actionErgebnissVorlage = ErgebnissVorlage() self.actionLayout = QStackedLayout() self.actionLayout.addWidget(self.actionSportlerEdit) self.actionLayout.addWidget(self.actionSportlerShow) self.actionLayout.addWidget(self.actionErgebnissListe) self.actionLayout.addWidget(self.actionErgebnisseDrucken) self.actionLayout.addWidget(self.actionErgebnissVorlage) self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.actionAuswahl) self.mainLayout.addStretch(0) self.mainLayout.addLayout(self.actionLayout) self.mainLayout.addStretch(0) self.setLayout(self.mainLayout) self.show()
def initUI(self): main_layout = QVBoxLayout(self) sub_layout = QHBoxLayout() # Left Panel left_panel = QListWidget() left_panel.setViewMode(left_panel.ListMode) #left_panel.setIconSize(QSize(40,40)) left_panel.setTextElideMode(Qt.ElideRight) left_panel.setMaximumWidth(200) left_panel.itemClicked.connect(self.change) #web.setText('Web') self.application = QListWidgetItem() self.application.setText('Application') self.web = QListWidgetItem() self.web.setText('Web') self.visual = QListWidgetItem() self.visual.setText('Visual') self.advanced = QListWidgetItem() self.advanced.setText('Advanced') self.about = QListWidgetItem() self.about.setText('About') #main.setIcon(QIcon(os.path.join(app_constants.static_dir, 'plus2.png'))) left_panel.addItem(self.application) left_panel.addItem(self.web) left_panel.addItem(self.visual) left_panel.addItem(self.advanced) left_panel.addItem(self.about) left_panel.setMaximumWidth(100) # right panel self.right_panel = QStackedLayout() self.init_right_panel() # bottom bottom_layout = QHBoxLayout() ok_btn = QPushButton('Ok') ok_btn.clicked.connect(self.accept) cancel_btn = QPushButton('Cancel') cancel_btn.clicked.connect(self.close) info_lbl = QLabel() info_lbl.setText('<a href="https://github.com/Pewpews/happypanda">'+ 'Visit GitHub Repo</a> | Options marked with * requires application restart.') info_lbl.setTextFormat(Qt.RichText) info_lbl.setTextInteractionFlags(Qt.TextBrowserInteraction) info_lbl.setOpenExternalLinks(True) self.spacer = QWidget() self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) bottom_layout.addWidget(info_lbl, 0, Qt.AlignLeft) bottom_layout.addWidget(self.spacer) bottom_layout.addWidget(ok_btn, 0, Qt.AlignRight) bottom_layout.addWidget(cancel_btn, 0, Qt.AlignRight) sub_layout.addWidget(left_panel) sub_layout.addLayout(self.right_panel) main_layout.addLayout(sub_layout) main_layout.addLayout(bottom_layout) self.restore_options()
def __init__(self, main_window, items): """ Widget contains items with inputs. """ super().__init__(main_window) stacked_layout = QStackedLayout() main_window.communication.item_selected.connect(stacked_layout.setCurrentIndex) self.setLayout(stacked_layout) self.showEvent = self._get_show_event(main_window) for item in items: frame = AttributesFrame(main_window=main_window, item=item) stacked_layout.addWidget(frame)
def __init__(self, parent=None): super().__init__(parent) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._option = None self._last_text_time = None self._hbox = QHBoxLayout(self) self._hbox.setContentsMargins(0, 0, 0, 0) self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self._cmd = command.Command() objreg.register('status-command', self._cmd) self._stack.addWidget(self._cmd) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self._timer_was_active = False self._text_queue = collections.deque() self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop') self._text_pop_timer.timeout.connect(self._pop_text) self.set_pop_timer_interval() config.on_change(self.set_pop_timer_interval, 'ui', 'message-timeout') self.prompt = prompt.Prompt() self._stack.addWidget(self.prompt) self._previous_widget = PreviousWidget.none self._cmd.show_cmd.connect(self._show_cmd_widget) self._cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() prompter = objreg.get('prompter') prompter.show_prompt.connect(self._show_prompt_widget) prompter.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog)
def __init__(self, parent=None): super(ProjectTreeColumn, self).__init__(parent) vbox = QVBoxLayout(self) vbox.setSizeConstraint(QVBoxLayout.SetDefaultConstraint) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self._buttons = [] frame = QFrame() frame.setObjectName("actionbar") box = QVBoxLayout(frame) box.setContentsMargins(1, 1, 1, 1) box.setSpacing(0) self._combo_project = QComboBox() self._combo_project.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed) self._combo_project.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self._combo_project.setObjectName("combo_projects") box.addWidget(self._combo_project) vbox.addWidget(frame) self._combo_project.setContextMenuPolicy(Qt.CustomContextMenu) self._projects_area = QStackedLayout() logger.debug("This is the projects area") vbox.addLayout(self._projects_area) # Empty widget self._empty_proj = QLabel(translations.TR_NO_PROJECTS) self._empty_proj.setAlignment(Qt.AlignCenter) self._empty_proj.setAutoFillBackground(True) self._empty_proj.setBackgroundRole(QPalette.Base) self._projects_area.addWidget(self._empty_proj) self._projects_area.setCurrentWidget(self._empty_proj) self.projects = [] self._combo_project.activated.connect( self._change_current_project) self._combo_project.customContextMenuRequested[ 'const QPoint&'].connect(self.context_menu_for_root) connections = ( { "target": "main_container", "signal_name": "addToProject", "slot": self._add_file_to_project }, { "target": "main_container", "signal_name": "showFileInExplorer", "slot": self._show_file_in_explorer }, ) IDE.register_service('projects_explorer', self) IDE.register_signals('projects_explorer', connections) ExplorerContainer.register_tab(translations.TR_TAB_PROJECTS, self)
def __init__(self, parent=None): super().__init__(parent) self.setAcceptDrops(True) self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) self.stack = QStackedLayout() self.stack.setStackingMode(QStackedLayout.StackAll) self._vbox.addLayout(self.stack) self.splitter = dynamic_splitter.DynamicSplitter() self._files_handler = files_handler.FilesHandler(self) # Code Navigation self.__code_back = [] self.__code_forward = [] self.__operations = { 0: self._navigate_code_jumps, 1: self._navigate_bookmarks } # Recent files list self.__last_opened_files = [] # QML UI self._add_file_folder = add_file_folder.AddFileFolderWidget(self) if settings.SHOW_START_PAGE: self.show_start_page() IDE.register_service("main_container", self) # Register signals connections connections = ( # { # "target": "main_container", # "signal_name": "updateLocator", # "slot": self._explore_code # }, { "target": "filesystem", "signal_name": "projectOpened", "slot": self._explore_code }, # { # "target": "projects_explore", # "signal_name": "updateLocator", # "slot": self._explore_code # } { "target": "filesystem", "signal_name": "projectClosed", "slot": self._explore_code } ) IDE.register_signals("main_container", connections) fhandler_short = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Tab), self) fhandler_short.activated.connect(self.show_files_handler)
def __init__(self, main_window, items): super().__init__() self.items = items self.visible_items = [] self.layout = QStackedLayout() self.menu_layout = QVBoxLayout() self.templates_layout = QStackedLayout() self.showEvent = self._get_show_event(main_window) self.menu_wrapper = QVBoxLayout() try: self.ACTION_BTN_ICON except AttributeError: self.ACTION_BTN_ICON = "" self.setLayout(self.layout) self.layout.addWidget(self._get_static_widgets())
def initUI(self): self.center = QWidget() self.display = QStackedLayout() self.center.setLayout(self.display) # init the manga view variables self.manga_display() log_d("Create manga display: OK") # init the chapter view variables # self.chapter_display() self.m_l_view_index = self.display.addWidget(self.manga_list_main) self.m_t_view_index = self.display.addWidget(self.manga_table_view) # init toolbar self.init_toolbar() log_d("Create toolbar: OK") # init status bar self.init_stat_bar() log_d("Create statusbar: OK") self.system_tray = misc.SystemTray(QIcon(gui_constants.APP_ICO_PATH), self) gui_constants.SYSTEM_TRAY = self.system_tray tray_menu = QMenu(self) self.system_tray.setContextMenu(tray_menu) self.system_tray.setToolTip("Happypanda {}".format(gui_constants.vs)) tray_quit = QAction("Quit", tray_menu) tray_menu.addAction(tray_quit) tray_quit.triggered.connect(self.close) self.system_tray.show() log_d("Create system tray: OK") # self.display.addWidget(self.chapter_main) self.setCentralWidget(self.center) self.setWindowTitle("Happypanda") self.setWindowIcon(QIcon(gui_constants.APP_ICO_PATH)) props = settings.win_read(self, "AppWindow") if props.resize: x, y = props.resize self.resize(x, y) else: self.resize(gui_constants.MAIN_W, gui_constants.MAIN_H) posx, posy = props.pos self.move(posx, posy) self.show() log_d("Show window: OK") self.notification_bar = misc.NotificationOverlay(self) p = self.toolbar.pos() self.notification_bar.move(p.x(), p.y() + self.toolbar.height()) self.notification_bar.resize(self.width()) gui_constants.NOTIF_BAR = self.notification_bar log_d("Create notificationbar: OK") log_d("Window Create: OK")
def __init__(self, main_window, items): super().__init__() self.items = items self.layout = QStackedLayout() self._switch_user = self._get_switch_user_func(main_window) self.setLayout(self.layout) self._hide_action_button = lambda: main_window.communication.action_button_toggle.emit(False, '', None) self._create_layout(main_window)
def __init__(self, parent=None): super().__init__(parent) layout = QVBoxLayout() self.setLayout(layout) self.center = QStackedLayout() self.camview = widgets.CamView((640, 480), self, draw_logo=True) self.label_up = QLabel() self.label_down = QLabel() self.center.addWidget(self.camview) layout.addLayout(self.center) layout.addWidget(self.label_up) layout.addWidget(self.label_down) self.adjustSize() self.setFixedSize(self.sizeHint())
def __init__(self, parent=None): super().__init__(parent, Qt.Dialog) self.setWindowTitle(translations.TR_PREFERENCES_TITLE) self.setMinimumSize(900, 650) box = QVBoxLayout(self) box.setContentsMargins(3, 3, 3, 3) self.setAutoFillBackground(True) # Header self._header_label = QLabel("") header_font = self._header_label.font() header_font.setBold(True) header_font.setPointSize(header_font.pointSize() + 4) self._header_label.setFont(header_font) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.tree = QTreeWidget() self.tree.header().setHidden(True) self.tree.setSelectionMode(QTreeWidget.SingleSelection) self.tree.setAnimated(True) self.tree.header().setSectionResizeMode( 0, QHeaderView.ResizeToContents) self.tree.setFixedWidth(200) hbox.addWidget(self.tree) self.stacked = QStackedLayout() header_layout = QVBoxLayout() header_layout.setContentsMargins(0, 0, 0, 0) header_layout.addWidget(self._header_label) header_layout.addLayout(self.stacked) hbox.addLayout(header_layout) box.addLayout(hbox) # Footer buttons button_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) box.addWidget(button_box) # Connections button_box.rejected.connect(self.close) button_box.accepted.connect(self._save_preferences) self.tree.selectionModel().currentRowChanged.connect( self._change_current) self.load_ui()
def __init__(self, editor): super(CodeCompletionWidget, self).__init__( None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self._revision = 0 self._block = 0 self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = {'a': resources.IMAGES['attribute'], 'f': resources.IMAGES['function'], 'c': resources.IMAGES['class'], 'm': resources.IMAGES['module']} self.cc = code_completion.CodeCompletion() self._completion_results = {} self._prefix = '' self.setVisible(False) self.source = '' self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } self.desktop = QApplication.instance().desktop() self.completion_list.itemClicked['QListWidgetItem*'].connect(self.pre_key_insert_completion) self._editor.document().cursorPositionChanged['const QTextCursor &'].connect(self.update_metadata)
def __init__(self, original=False): super(ComboEditor, self).__init__(None) self.__original = original self.__undocked = [] self._symbols_index = [] vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.bar = ActionBar(main_combo=original) vbox.addWidget(self.bar) # Info bar # self.info_bar = InfoBar(self) # self.info_bar.setVisible(False) # vbox.addWidget(self.info_bar) self.stacked = QStackedLayout() vbox.addLayout(self.stacked) self._main_container = IDE.get_service('main_container') if not self.__original: self._main_container.fileOpened['QString'].connect( self._file_opened_by_main) self.bar.combo_files.showComboSelector.connect( self._main_container.show_files_handler) self.bar.combo_files.hideComboSelector.connect( self._main_container.hide_files_handler) self.bar.change_current['PyQt_PyObject', int].connect(self._set_current) self.bar.splitEditor[bool].connect(self.split_editor) self.bar.runFile['QString'].connect(self._run_file) self.bar.closeSplit.connect(lambda: self.closeSplit.emit(self)) self.bar.addToProject['QString'].connect(self._add_to_project) self.bar.showFileInExplorer['QString'].connect( self._show_file_in_explorer) self.bar.goToSymbol[int].connect(self._go_to_symbol) self.bar.undockEditor.connect(self.undock_editor) self.bar.reopenTab['QString'].connect( lambda path: self._main_container.open_file(path)) self.bar.closeImageViewer.connect(self._close_image) self.bar.code_navigator.previousPressed.connect(self._navigate_code) self.bar.code_navigator.nextPressed.connect(self._navigate_code)
def __init__(self, items): """ Init gui. Connect signals. Create layout. """ super().__init__() self.items = items self.user = None self.communication = Communication() self.frames_layout = QStackedLayout() self.data_frame_index = None self.top_system_frame_height = 0 self._init_gui() self._set_shortcuts()
def __init__(self, *, win_id, private, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) config.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._color_flags = ColorFlags() self._color_flags.private = private self._hbox = QHBoxLayout(self) self._set_hbox_padding() self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(private=private, win_id=win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() self.url = url.UrlText() self.percentage = percentage.Percentage() self.backforward = backforward.Backforward() self.tabindex = tabindex.TabIndex() self.keystring = keystring.KeyString() self.prog = progress.Progress(self) self._draw_widgets() config.instance.changed.connect(self._on_config_changed) QTimer.singleShot(0, self.maybe_hide)
def __init__(self, parent, task, new=False): QWidget.__init__(self, parent) self.task = task self.new = new self.layout = QStackedLayout(self) self.label = QLabel(self) self.label.setTextFormat(Qt.RichText) self.label.setOpenExternalLinks(True) self._update() self.label.setWordWrap(True) self.layout.addWidget(self.label) self.editor = TaskEditorLineEdit(self, parent.mfile) self.layout.addWidget(self.editor) self.setLayout(self.layout) self.layout.setCurrentIndex(0) self.editor.focusOut.connect(self.editFinished) self.task.modified.connect(self._update)
def __init__(self): super().__init__() self.center = QWidget() self.display = QStackedLayout() self.center.setLayout(self.display) # init the manga view variables self.manga_display() # init the chapter view variables self.chapter_display() # init toolbar self.init_toolbar() # init status bar self.init_stat_bar() self.display.addWidget(self.manga_main) self.display.addWidget(self.chapter_main) self.setCentralWidget(self.center) self.setWindowTitle("Happypanda") self.resize(1029, 650) self.show()
def __init__(self, parent=None): super(Preferences, self).__init__(parent, Qt.Dialog) self.setWindowTitle(translations.TR_PREFERENCES_TITLE) self.setMinimumSize(QSize(900, 600)) vbox = QVBoxLayout(self) hbox = QHBoxLayout() vbox.setContentsMargins(0, 0, 5, 5) hbox.setContentsMargins(0, 0, 0, 0) # self.tree = QTreeWidget() self.tree.header().setHidden(True) self.tree.setSelectionMode(QTreeWidget.SingleSelection) self.tree.setAnimated(True) self.tree.header().setHorizontalScrollMode( QAbstractItemView.ScrollPerPixel) self.tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) self.tree.setFixedWidth(200) self.stacked = QStackedLayout() hbox.addWidget(self.tree) hbox.addLayout(self.stacked) vbox.addLayout(hbox) # hbox_footer = QHBoxLayout() self._btnSave = QPushButton(translations.TR_SAVE) self._btnCancel = QPushButton(translations.TR_CANCEL) hbox_footer.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_footer.addWidget(self._btnCancel) hbox_footer.addWidget(self._btnSave) vbox.addLayout(hbox_footer) # self.tree.itemSelectionChanged.connect(self._change_current) self._btnCancel.clicked['bool'].connect(self.close) self._btnSave.clicked['bool'].connect(self._save_preferences) # self.load_ui() self.tree.setCurrentItem(self.tree.topLevelItem(0))
def __init__(self, parent=None): super(MusicPreviewWidget, self).__init__(parent) self._lastbuildtime = 10.0 self._running = None self._current = None self._chooserLabel = QLabel() self._chooser = QComboBox(self, activated=self.selectDocument) self._log = log.Log() self._view = popplerview.View() self._progress = widgets.progressbar.TimedProgressBar() self._stack = QStackedLayout() self._top = QWidget() layout = QVBoxLayout() self.setLayout(layout) layout.addWidget(self._top) layout.addLayout(self._stack) layout.addWidget(self._progress) top = QHBoxLayout() top.setContentsMargins(0, 0, 0, 0) top.setSpacing(2) self._top.setLayout(top) top.addWidget(self._chooserLabel) top.addWidget(self._chooser) top.addStretch(1) self._stack.addWidget(self._log) self._stack.addWidget(self._view) self._top.hide() app.aboutToQuit.connect(self.cleanup) app.translateUI(self)
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _win_id: The window ID the statusbar is associated with. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move to the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _severity = None _color_flags = None STYLESHEET = _generate_stylesheet() def __init__(self, *, win_id, private, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) config.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._color_flags = ColorFlags() self._color_flags.private = private self._hbox = QHBoxLayout(self) self._set_hbox_padding() self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(private=private, win_id=win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() self.url = url.UrlText() self.percentage = percentage.Percentage() self.backforward = backforward.Backforward() self.tabindex = tabindex.TabIndex() self.keystring = keystring.KeyString() self.prog = progress.Progress(self) self._draw_widgets() config.instance.changed.connect(self._on_config_changed) QTimer.singleShot(0, self.maybe_hide) def __repr__(self): return utils.get_repr(self) @pyqtSlot(str) def _on_config_changed(self, option): if option == 'statusbar.hide': self.maybe_hide() elif option == 'statusbar.padding': self._set_hbox_padding() elif option == 'statusbar.widgets': self._draw_widgets() def _draw_widgets(self): """Draw statusbar widgets.""" # Start with widgets hidden and show them when needed for widget in [ self.url, self.percentage, self.backforward, self.tabindex, self.keystring, self.prog ]: widget.hide() self._hbox.removeWidget(widget) tab = self._current_tab() # Read the list and set widgets accordingly for segment in config.val.statusbar.widgets: if segment == 'url': self._hbox.addWidget(self.url) self.url.show() elif segment == 'scroll': self._hbox.addWidget(self.percentage) self.percentage.show() elif segment == 'scroll_raw': self._hbox.addWidget(self.percentage) self.percentage.set_raw() self.percentage.show() elif segment == 'history': self._hbox.addWidget(self.backforward) self.backforward.enabled = True if tab: self.backforward.on_tab_changed(tab) elif segment == 'tabs': self._hbox.addWidget(self.tabindex) self.tabindex.show() elif segment == 'keypress': self._hbox.addWidget(self.keystring) self.keystring.show() elif segment == 'progress': self._hbox.addWidget(self.prog) self.prog.enabled = True if tab: self.prog.on_tab_changed(tab) @pyqtSlot() def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" tab = self._current_tab() hide = config.val.statusbar.hide if hide or (tab is not None and tab.data.fullscreen): self.hide() else: self.show() def _set_hbox_padding(self): padding = config.val.statusbar.padding self._hbox.setContentsMargins(padding.left, 0, padding.right, 0) @pyqtProperty('QStringList') def color_flags(self): """Getter for self.color_flags, so it can be used as Qt property.""" return self._color_flags.to_stringlist() def _current_tab(self): """Get the currently displayed tab.""" window = objreg.get('tabbed-browser', scope='window', window=self._win_id) return window.widget.currentWidget() def set_mode_active(self, mode, val): """Setter for self.{insert,command,caret}_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if mode == usertypes.KeyMode.insert: log.statusbar.debug("Setting insert flag to {}".format(val)) self._color_flags.insert = val if mode == usertypes.KeyMode.passthrough: log.statusbar.debug("Setting passthrough flag to {}".format(val)) self._color_flags.passthrough = val if mode == usertypes.KeyMode.command: log.statusbar.debug("Setting command flag to {}".format(val)) self._color_flags.command = val elif mode in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]: log.statusbar.debug("Setting prompt flag to {}".format(val)) self._color_flags.prompt = val elif mode == usertypes.KeyMode.caret: if not val: # Turning on is handled in on_current_caret_selection_toggled log.statusbar.debug("Setting caret mode off") self._color_flags.caret = ColorFlags.CaretMode.off config.set_register_stylesheet(self, update=False) def _set_mode_text(self, mode): """Set the mode text.""" if mode == 'passthrough': key_instance = config.key_instance all_bindings = key_instance.get_reverse_bindings_for('passthrough') bindings = all_bindings.get('leave-mode') if bindings: suffix = ' ({} to leave)'.format(' or '.join(bindings)) else: suffix = '' else: suffix = '' text = "-- {} MODE --{}".format(mode.upper(), suffix) self.txt.set_text(self.txt.Text.normal, text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._stack.setCurrentWidget(self.cmd) self.show() def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget") self._stack.setCurrentWidget(self.txt) self.maybe_hide() @pyqtSlot(str) def set_text(self, val): """Set a normal (persistent) text in the status bar.""" self.txt.set_text(self.txt.Text.normal, val) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[mode].passthrough: self._set_mode_text(mode.name) if mode in [ usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough ]: self.set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): """Clear marked mode.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[old_mode].passthrough: if keyparsers[new_mode].passthrough: self._set_mode_text(new_mode.name) else: self.txt.set_text(self.txt.Text.normal, '') if old_mode in [ usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough ]: self.set_mode_active(old_mode, False) @pyqtSlot(browsertab.AbstractTab) def on_tab_changed(self, tab): """Notify sub-widgets when the tab has been changed.""" self.url.on_tab_changed(tab) self.prog.on_tab_changed(tab) self.percentage.on_tab_changed(tab) self.backforward.on_tab_changed(tab) self.maybe_hide() assert tab.is_private == self._color_flags.private @pyqtSlot(bool) def on_caret_selection_toggled(self, selection): """Update the statusbar when entering/leaving caret selection mode.""" log.statusbar.debug("Setting caret selection {}".format(selection)) if selection: self._set_mode_text("caret selection") self._color_flags.caret = ColorFlags.CaretMode.selection else: self._set_mode_text("caret") self._color_flags.caret = ColorFlags.CaretMode.on config.set_register_stylesheet(self, update=False) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos()) def minimumSizeHint(self): """Set the minimum height to the text height plus some padding.""" padding = config.cache['statusbar.padding'] width = super().minimumSizeHint().width() height = self.fontMetrics().height() + padding.top + padding.bottom return QSize(width, height)
def CreateApp(self): self.setWindowIcon(QtGui.QIcon('logo.jpg')) self.layout = QVBoxLayout() self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) #create tabs self.tabbar = QTabBar(movable=True, tabsClosable=True) self.tabbar.tabCloseRequested.connect(self.CloseTab) self.tabbar.tabBarClicked.connect(self.SwitchTab) self.tabbar.setCurrentIndex(0) self.tabbar.setDrawBase(False) self.tabbar.setLayoutDirection(Qt.LeftToRight) self.tabbar.setElideMode(Qt.ElideLeft) # Keep Track of Tabs self.tabCount = 0 self.tabs = [] #create Address bar self.Toolbar = QWidget() self.Toolbar.setObjectName("Toolbar") self.ToolbarLayout = QHBoxLayout() self.addressbar = AddressBar() self.AddTabButton = QPushButton("+") #New Tab Button self.addressbar.returnPressed.connect(self.BrowseTo) self.AddTabButton.clicked.connect(self.AddTab) #set toolbar buttons self.BackButton = QPushButton("<") self.BackButton.clicked.connect(self.GoBack) self.ForwardButton = QPushButton(">") self.ForwardButton.clicked.connect(self.GoForward) self.ReloadButton = QPushButton("R") self.ReloadButton.clicked.connect(self.ReloadPage) #Build Toolbar self.Toolbar.setLayout(self.ToolbarLayout) self.ToolbarLayout.addWidget(self.BackButton) self.ToolbarLayout.addWidget(self.ForwardButton) self.ToolbarLayout.addWidget(self.ReloadButton) self.ToolbarLayout.addWidget(self.addressbar) self.ToolbarLayout.addWidget(self.AddTabButton) #Set Main view self.container = QWidget() self.container.layout = QStackedLayout() self.container.setLayout(self.container.layout) #construct main view from top level elements self.layout.addWidget(self.tabbar) self.layout.addWidget(self.Toolbar) self.layout.addWidget(self.container) self.setLayout(self.layout) self.AddTab() self.show()
class DeviceManagementWidget(WidgetBase): # noinspection PyArgumentList,PyUnresolvedReferences def __init__(self, parent: typing.Optional[QWidget], on_connection_request: ConnectionRequestCallback, on_disconnection_request: DisconnectionRequestCallback): super(DeviceManagementWidget, self).__init__(parent) self.setAttribute( Qt.WA_DeleteOnClose) # This is required to stop background timers! self._port_discoverer = PortDiscoverer() self._port_mapping: typing.Dict[str:str] = {} self._port_combo = QComboBox(self) self._port_combo.setEditable(True) self._port_combo.setInsertPolicy(QComboBox.NoInsert) self._port_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) self._port_combo.setFont(get_monospace_font()) self._port_combo.lineEdit().returnPressed.connect( self._on_confirmation) self._connect_button = make_button(self, 'Connect', 'disconnected', on_clicked=self._on_confirmation) self._connect_button.setEnabled( False) # Empty by default, therefore disabled self._port_combo.currentTextChanged.connect( lambda: self._connect_button.setEnabled( bool(self._port_combo.currentText().strip()))) self._status_text = QLabel(self) self._status_text.setText(_STATUS_WHEN_NOT_CONNECTED) self._status_text.setWordWrap(True) self._device_info_widget = LittleBobbyTablesWidget(self) combo_completer = QCompleter() combo_completer.setCaseSensitivity(Qt.CaseInsensitive) combo_completer.setModel(self._port_combo.model()) self._port_combo.setCompleter(combo_completer) self._update_timer = QTimer(self) self._update_timer.timeout.connect(self._update_ports) self._update_timer.start(2000) self._connection_progress_bar = QProgressBar(self) self._connection_progress_bar.setMinimum(0) self._connection_progress_bar.setMaximum(100) self._connection_established = False self._last_task: typing.Optional[asyncio.Task] = None self._connection_request_callback: ConnectionRequestCallback = on_connection_request self._disconnection_request_callback: DisconnectionRequestCallback = on_disconnection_request # Layout self._overlay = QStackedLayout(self) self._init_overlay_widgets() self.setLayout(self._overlay) # Initialization self._update_ports() def on_connection_loss(self, reason: str): """ This method should be invoked when the connection becomes lost. It will cause the widget to change its state accordingly. :param reason: Human-readable description of the reason in one line. """ if self._connection_established: self._switch_state_disconnected() self._status_text.setText( f'Connection lost: {reason.strip() or "Unknown reason"}') def on_connection_initialization_progress_report(self, stage_description: str, progress: float): """ This method should be periodically invoked while connection is being initialized. :param stage_description: Human-readable short string displaying what is currently being done. E.g. "Opening port" :param progress: A float in [0, 1] that displays how much of the work has been completed so far, where 0 - nothing, 1 - all done. """ if self._overlay.currentIndex() != 1: raise RuntimeError( 'Invalid usage: this method can only be invoked when connection initialization is ' 'in progress. Currently it is not.') # noinspection PyTypeChecker if not (0.0 <= progress <= 1.0): _logger.error( f'Connection progress estimate falls outside of [0, 1]: {progress}' ) stage_description = stage_description.strip() if stage_description[-1] in string.ascii_letters: stage_description += '...' self._connection_progress_bar.setValue(int(progress * 100)) self._connection_progress_bar.setFormat(stage_description) self._connection_progress_bar.setAlignment(Qt.AlignCenter) # noinspection PyArgumentList,PyUnresolvedReferences def _init_overlay_widgets(self): # Main widget operational = WidgetBase(self) operational_layout_top = QHBoxLayout() operational_layout_top.addWidget(QLabel('Port:')) operational_layout_top.addWidget(self._port_combo, stretch=1) operational_layout_top.addWidget(self._connect_button) operational_layout_bottom = QHBoxLayout() operational_layout_bottom.addWidget(self._status_text) operational_layout = QVBoxLayout() operational_layout.addLayout(operational_layout_top) operational_layout.addLayout(operational_layout_bottom) operational_layout.addWidget(self._device_info_widget, 1) operational.setLayout(operational_layout) self._overlay.addWidget(operational) # Progress widget - shown while connecting/disconnecting progress = WidgetBase(self) progress_layout = QVBoxLayout() progress_layout.addStretch(1) progress_layout.addWidget(self._connection_progress_bar) progress_layout.addStretch(1) progress.setLayout(progress_layout) self._overlay.addWidget(progress) def _update_ports(self): if self._connection_established: return # noinspection PyBroadException try: ports = self._port_discoverer.get_ports() except Exception as ex: _logger.exception('Could not list ports') self.flash(f'Could not list ports: {ex}', duration=10) ports = [] self._port_mapping = self._port_discoverer.display_ports( ports, self._port_combo) def _switch_state_connected(self, device_info: BasicDeviceInfo): self._connection_established = True self._overlay.setCurrentIndex(0) self._port_combo.setEnabled(False) self._connect_button.setEnabled(True) self._connect_button.setText('Disconnect') self._connect_button.setIcon(get_icon('connected')) self._status_text.setText('Connected') self._device_info_widget.set(device_info) def _switch_state_disconnected(self): self._connection_established = False self._overlay.setCurrentIndex(0) self._port_combo.setEnabled(True) self._connect_button.setEnabled(True) self._connect_button.setText('Connect') self._connect_button.setIcon(get_icon('disconnected')) self._device_info_widget.clear() self._status_text.setText(_STATUS_WHEN_NOT_CONNECTED) self._update_ports() async def _do_connect(self): _logger.info('Connection initialization task spawned') try: selected_port = self._port_mapping[str( self._port_combo.currentText()).strip()] except KeyError: selected_port = str(self._port_combo.currentText()).strip() # Activate the progress view and initialize it self._overlay.setCurrentIndex(1) self._connection_progress_bar.setValue(0) self._connection_progress_bar.setFormat('Requesting connection...') # noinspection PyBroadException try: device_info: BasicDeviceInfo = await self._connection_request_callback( selected_port) except Exception as ex: show_error( 'Could not connect', f'Connection via the port {selected_port} could not be established.', f'Reason: {str(ex)}', parent=self) self._switch_state_disconnected() else: assert device_info is not None self._switch_state_connected(device_info) async def _do_disconnect(self): _logger.info('Connection termination task spawned') # Activate the progress view and initialize it self._overlay.setCurrentIndex(1) self._connection_progress_bar.setValue(100) self._connection_progress_bar.setFormat( 'Disconnecting, please wait...') # noinspection PyBroadException try: await self._disconnection_request_callback() except Exception as ex: _logger.exception('Disconnect request failed') self.flash(f'Disconnection problem: {ex}', duration=10) self._switch_state_disconnected() def _on_confirmation(self): # Deactivate the controls in order to prevent accidental double-entry self._port_combo.setEnabled(False) self._connect_button.setEnabled(False) if (self._last_task is not None) and not self._last_task.done(): show_error( "I'm sorry Dave, I'm afraid I can't do that", 'Cannot connect/disconnect while another connection/disconnection operation is still running', f'Pending future: {self._last_task}', self) else: if not self._connection_established: self._last_task = asyncio.get_event_loop().create_task( self._do_connect()) else: self._last_task = asyncio.get_event_loop().create_task( self._do_disconnect())
class MusicPreviewWidget(QWidget): def __init__(self, parent=None): super(MusicPreviewWidget, self).__init__(parent) self._lastbuildtime = 10.0 self._running = None self._current = None self._chooserLabel = QLabel() self._chooser = QComboBox(self, activated=self.selectDocument) self._log = log.Log() self._view = popplerview.View() self._progress = widgets.progressbar.TimedProgressBar() self._stack = QStackedLayout() self._top = QWidget() layout = QVBoxLayout() self.setLayout(layout) layout.addWidget(self._top) layout.addLayout(self._stack) layout.addWidget(self._progress) top = QHBoxLayout() top.setContentsMargins(0, 0, 0, 0) top.setSpacing(2) self._top.setLayout(top) top.addWidget(self._chooserLabel) top.addWidget(self._chooser) top.addStretch(1) self._stack.addWidget(self._log) self._stack.addWidget(self._view) self._top.hide() app.aboutToQuit.connect(self.cleanup) app.translateUI(self) def translateUI(self): self._chooserLabel.setText(_("Document:")) def preview(self, text, title=None): """Runs LilyPond on the given text and shows the resulting PDF.""" j = self._running = MusicPreviewJob(text, title) j.done.connect(self._done) self._log.clear() self._log.connectJob(j) j.start() self._progress.start(self._lastbuildtime) def _done(self, success): self._progress.stop(False) pdfs = self._running.resultfiles() self.setDocuments(pdfs) if not pdfs: self._stack.setCurrentWidget(self._log) return self._lastbuildtime = self._running.elapsed_time() self._stack.setCurrentWidget(self._view) if self._current: self._current.cleanup() self._current = self._running # keep the tempdir self._running = None def setDocuments(self, pdfs): """Loads the given PDF path names in the UI.""" self._documents = [popplertools.Document(name) for name in pdfs] self._chooser.clear() self._chooser.addItems([d.name() for d in self._documents]) self._top.setVisible(len(self._documents) > 1) if pdfs: self._chooser.setCurrentIndex(0) self.selectDocument(0) else: self._view.clear() def selectDocument(self, index): doc = self._documents[index].document() if doc: self._view.load(doc) def cleanup(self): if self._running: self._running.abort() self._running.cleanup() self._running = None if self._current: self._current.cleanup() self._current = None self._stack.setCurrentWidget(self._log) self._top.hide() self._view.clear() def print_(self): """Prints the currently displayed document.""" if self._documents: doc = self._documents[self._chooser.currentIndex()] import popplerprint popplerprint.printDocument(doc, self)
class AbstractTemplateWidget(QFrame): """ TemplateWidget is used in reports and options tab. So it needs several common methods and common layout. But behavior is different. it should be defined in children classes. """ def __init__(self, main_window, items): super().__init__() self.items = items self.visible_items = [] self.layout = QStackedLayout() self.menu_layout = QVBoxLayout() self.templates_layout = QStackedLayout() self.showEvent = self._get_show_event(main_window) self.menu_wrapper = QVBoxLayout() try: self.ACTION_BTN_ICON except AttributeError: self.ACTION_BTN_ICON = "" self.setLayout(self.layout) self.layout.addWidget(self._get_static_widgets()) def _get_static_widgets(self): """ Create layout that does not depend on content. """ hbox = QHBoxLayout() self.menu_wrapper.addWidget(utils.get_scrollable(self.menu_layout)) hbox.addLayout(self.menu_wrapper, stretch=30) hbox.addLayout(self.templates_layout, stretch=70) widget = QWidget() widget.setLayout(hbox) widget.setGraphicsEffect(utils.get_shadow()) return widget def _iterate_items(self): """ Filter items if they has no values. """ pass def hideEvent(self, event): """ Clear menu and templates. """ utils.clear_layout(self.menu_layout) utils.clear_layout(self.templates_layout) def _get_show_event(self, main_window): """ Update templates list and re-select them. """ def show_event(event): utils.clear_layout(self.menu_layout) utils.clear_layout(self.templates_layout) self.visible_items = self._iterate_items() self._show_menu() self._show_templates() if not self.layout.currentIndex(): main_window.communication.action_button_toggle.emit( bool(self.visible_items), self.ACTION_BTN_ICON, self.action_btn_function ) return show_event def _show_menu(self): """ Update menu on showEvent. """ for i, item in enumerate(self.visible_items): b = QRadioButton(self._get_button_name(item)) b.setChecked(i == 0) b.clicked.connect(functools.partial(self.templates_layout.setCurrentIndex, i)) b.setObjectName("menu_button") self.menu_layout.addWidget(b) if not self.visible_items: self.menu_layout.addStretch() l = QLabel("Чтобы создать отчет\nначните заполнять данные") l.setAlignment(Qt.AlignCenter) self.menu_layout.addWidget(l) self.menu_layout.addStretch() def _show_templates(self): """ Update templates on shoeEvent. """ cols = 3 templates = template_module.Template.get_all() for j, item in enumerate(self.visible_items): if not templates[item.id]: l = QLabel("Нет шаблонов для данного объекта\nУправлять шаблонами можно на вкладке настроек") l.setAlignment(Qt.AlignCenter) self.templates_layout.addWidget(l) continue layouts = [QVBoxLayout() for _ in range(cols)] for i, each in enumerate(templates[item.id]): b = QRadioButton(each.name) b.setChecked(item.template == each) b.clicked.connect(functools.partial(self._template_clicked, j, each)) b.mouseDoubleClickEvent = functools.partial(self.open_template_edit_widget, j, each) layouts[i % cols].addWidget(b) wrapper = QHBoxLayout() for each in layouts: each.addStretch() wrapper.addLayout(each, stretch=int(100 / cols)) self.templates_layout.addWidget(utils.get_scrollable(wrapper)) def _template_selected(self, index, template): """ Change menu item name. Add template for the item. """ self.visible_items[index].template = template buttons = self.findChildren(QRadioButton, name="menu_button") buttons[index].setText(self._get_button_name(self.visible_items[index])) for i in range(len(self.visible_items)): ind = (i + index) % len(self.visible_items) if not self.visible_items[ind].template: self.templates_layout.setCurrentIndex(ind) buttons[ind].setChecked(True) buttons[index].setChecked(False) return def _get_button_name(self, item): pass def _double_click(self, index, template, event): pass def _template_clicked(self, index, template): pass def action_btn_function(self, event): pass def open_template_edit_widget(self, index, template, event): pass
class Demo(QWidget): def __init__(self): super().__init__() self.__setup_ui__() def __setup_ui__(self): self.setWindowTitle("测试") #窗口大小 self.resize(1400, 800) # 工具栏 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) # 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) # 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) 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) 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")
class Ui_home(QWidget): def __init__(self): super().__init__() self.init() def init(self): self.db = MyDatabase.DBModel() self.mainwindow() self.rightwindow() self.leftwindow() self.click_event() def mainwindow(self): self.setWindowIcon(QIcon('./src/whale.ico')) self.setFixedSize(1280, 720) self.setWindowTitle('木鲸图书馆管理系统') self.layout = QHBoxLayout() def rightwindow(self): self.rightFrame = QFrame(self) self.p_login = loginWindow() self.p_tools = tools() self.p_book_manage = book_manage() self.p_user_manage = user_manage() self.p_index = page_index() self.qsl = QStackedLayout(self.rightFrame) self.qsl.addWidget(self.p_login) self.qsl.addWidget(self.p_index) self.qsl.addWidget(self.p_tools) self.qsl.addWidget(self.p_book_manage) self.qsl.addWidget(self.p_user_manage) def leftwindow(self): self.label = QLabel(self) self.label.setPixmap(QPixmap('./src/whale.ico')) self.label.setFixedSize(200, 200) self.btn_login = QPushButton('登录') self.btn_tools = QPushButton('工具箱') self.btn_book_management = QPushButton('图书管理') self.btn_user_management = QPushButton('用户管理') self.btn_login.setFixedSize(200, 50) self.btn_tools.setFixedSize(200, 50) self.btn_book_management.setFixedSize(200, 50) self.btn_user_management.setFixedSize(200, 50) self.btn_login.setFont(QFont( "", 12, )) self.btn_tools.setFont(QFont( "", 12, )) self.btn_book_management.setFont(QFont( "", 12, )) self.btn_user_management.setFont(QFont( "", 12, )) leftBox = QVBoxLayout() leftBox.addWidget(self.label) leftBox.addWidget(self.btn_login) leftBox.addWidget(self.btn_tools) leftBox.addWidget(self.btn_book_management) leftBox.addWidget(self.btn_user_management) self.layout.addLayout(leftBox) self.layout.addWidget(self.rightFrame) self.setLayout(self.layout) def click_event(self): self.p_login._signal.connect(self.get_db) self.p_index._signal.connect(self.logout) self.btn_login.clicked.connect(lambda: self.to_page(0)) self.btn_tools.clicked.connect(lambda: self.to_page(1)) self.btn_book_management.clicked.connect(lambda: self.to_page(2)) self.btn_user_management.clicked.connect(lambda: self.to_page(3)) def to_page(self, num): status = self.test_db() if num == 0: if status: self.qsl.setCurrentIndex(1) else: self.qsl.setCurrentIndex(0) self.btn_login.setText('登录') elif num >= 1: if status: self.qsl.setCurrentIndex(1 + num) else: self.login_Error() def get_db(self, db): print('已登录') self.db = db self.btn_login.setText('个人信息') self.qsl.setCurrentIndex(1) self.set_child_db() def set_child_db(self): print("更新数据库对象...") self.p_index.setdb(self.db) self.p_tools.setdb(self.db) self.p_book_manage.setdb(self.db) self.p_user_manage.setdb(self.db) def logout(self): print('登出: home.logout') self.db = None self.btn_login.setText('登录') self.qsl.setCurrentIndex(0) def test_db(self): try: if self.db.status(0) != False: return True else: return False except: return False def login_Error(self): System.dialog(self, '错误', '请先登录') def closeEvent(self, event): print('退出事件') reply = QMessageBox.question(self, '警告', "确认退出?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: print('确认退出') event.accept() else: print('取消退出') event.ignore()
class RightPanel(QFrame): def __init__(self, app, parent=None): super().__init__(parent) self._app = app self._pixmap = None self._layout = QVBoxLayout(self) self._stacked_layout = QStackedLayout() self.scrollarea = ScrollArea(self._app, self) self.table_container = self.scrollarea.t self.bottom_panel = BottomPanel(app, self) self._setup_ui() def _setup_ui(self): self.scrollarea.setMinimumHeight(100) self._layout.addWidget(self.bottom_panel) self._layout.addLayout(self._stacked_layout) self._stacked_layout.addWidget(self.scrollarea) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) def show_songs(self, songs): self.set_body(self.scrollarea) self.table_container.show_songs(songs) def set_body(self, widget): """ .. versionadded:: 3.7.7 """ if widget is self.table_container: widget = self.scrollarea if widget is not self.scrollarea: self.show_background_image(None) # remove tmp widgets for i in range(self._stacked_layout.count()): w = self._stacked_layout.widget(i) if w not in (self.scrollarea, ): self._stacked_layout.removeWidget(w) self._stacked_layout.addWidget(widget) self._stacked_layout.setCurrentWidget(widget) def show_collection(self, coll, model_type): def _show_pure_albums_coll(coll): self.set_body(self.scrollarea) reader = wrap(coll.models) self.table_container.show_albums_coll(reader) def _show_pure_songs_coll(coll): self.set_body(self.scrollarea) self.table_container.show_collection(coll) def _show_pure_videos_coll(coll): from feeluown.gui.page_containers.table import VideosRenderer self.set_body(self.scrollarea) reader = wrap(coll.models) renderer = VideosRenderer(reader) aio.create_task(self.table_container.set_renderer(renderer)) if model_type == ModelType.song: _show_pure_songs_coll(coll) elif model_type == ModelType.album: _show_pure_albums_coll(coll) elif model_type == ModelType.video: _show_pure_videos_coll(coll) else: logger.warning("can't render this kind of collection") def show_background_image(self, pixmap): self._pixmap = pixmap self._adjust_meta_widget_height() self.update() def paintEvent(self, e): """ draw pixmap as a the background with a dark overlay HELP: currently, this cost much CPU """ painter = QPainter(self) painter.setPen(Qt.NoPen) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.SmoothPixmapTransform) # calculate available size draw_width = self.width() draw_height = 10 # spacing defined in table container draw_height += self.bottom_panel.height() if self.table_container.meta_widget.isVisible(): draw_height += self.table_container.meta_widget.height() extra = self.table_container.current_extra if extra is not None and extra.isVisible(): draw_height += extra.height() if self.table_container.toolbar.isVisible(): draw_height += self.table_container.toolbar.height() scrolled = self.scrollarea.verticalScrollBar().value() max_scroll_height = draw_height - self.bottom_panel.height() # Do not draw the pixmap when it is not shown. if scrolled >= max_scroll_height: painter.save() painter.setBrush(self.palette().brush(QPalette.Window)) painter.drawRect(self.bottom_panel.rect()) painter.restore() return if self._pixmap is not None: self._draw_pixmap(painter, draw_width, draw_height, scrolled) self._draw_pixmap_overlay(painter, draw_width, draw_height, scrolled) curve = QEasingCurve(QEasingCurve.OutCubic) alpha_ratio = min(scrolled / max_scroll_height, 1) alpha = int(250 * curve.valueForProgress(alpha_ratio)) painter.save() color = self.palette().color(QPalette.Window) color.setAlpha(alpha) painter.setBrush(color) painter.drawRect(self.bottom_panel.rect()) painter.restore() else: # draw gradient for widgets(bottom panel + meta_widget + ...) above table self._draw_overlay(painter, draw_width, draw_height, scrolled) # if scrolled height > 30, draw background to seperate bottom_panel and body if scrolled >= 30: painter.save() painter.setBrush(self.palette().brush(QPalette.Window)) painter.drawRect(self.bottom_panel.rect()) painter.restore() return # since the body's background color is palette(base), we use # the color to draw background for remain empty area painter.save() painter.setBrush(self.palette().brush(QPalette.Base)) painter.drawRect(0, draw_height, draw_width, self.height() - draw_height) painter.restore() painter.end() def _draw_pixmap_overlay(self, painter, draw_width, draw_height, scrolled): painter.save() rect = QRect(0, 0, draw_width, draw_height) painter.translate(0, -scrolled) gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft()) color = self.palette().color(QPalette.Base) if draw_height == self.height(): gradient.setColorAt(0, add_alpha(color, 180)) gradient.setColorAt(1, add_alpha(color, 230)) else: if self._app.theme_mgr.theme == Light: gradient.setColorAt(0, add_alpha(color, 220)) gradient.setColorAt(0.1, add_alpha(color, 180)) gradient.setColorAt(0.2, add_alpha(color, 140)) gradient.setColorAt(0.6, add_alpha(color, 140)) gradient.setColorAt(0.8, add_alpha(color, 200)) gradient.setColorAt(0.9, add_alpha(color, 240)) gradient.setColorAt(1, color) else: gradient.setColorAt(0, add_alpha(color, 50)) gradient.setColorAt(0.6, add_alpha(color, 100)) gradient.setColorAt(0.8, add_alpha(color, 200)) gradient.setColorAt(0.9, add_alpha(color, 240)) gradient.setColorAt(1, color) painter.setBrush(gradient) painter.drawRect(rect) painter.restore() def _draw_overlay(self, painter, draw_width, draw_height, scrolled): painter.save() rect = QRect(0, 0, draw_width, draw_height) painter.translate(0, -scrolled) gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft()) gradient.setColorAt(0, self.palette().color(QPalette.Window)) gradient.setColorAt(1, self.palette().color(QPalette.Base)) painter.setBrush(gradient) painter.drawRect(rect) painter.restore() def _draw_pixmap(self, painter, draw_width, draw_height, scrolled): # scale pixmap scaled_pixmap = self._pixmap.scaledToWidth( draw_width, mode=Qt.SmoothTransformation) pixmap_size = scaled_pixmap.size() # draw the center part of the pixmap on available rect painter.save() brush = QBrush(scaled_pixmap) painter.setBrush(brush) # note: in practice, most of the time, we can't show the # whole artist pixmap, as a result, the artist head will be cut, # which causes bad visual effect. So we render the top-center part # of the pixmap here. y = (pixmap_size.height() - draw_height) // 3 painter.translate(0, - y - scrolled) rect = QRect(0, y, draw_width, draw_height) painter.drawRect(rect) painter.restore() def sizeHint(self): size = super().sizeHint() return QSize(660, size.height()) def resizeEvent(self, e): super().resizeEvent(e) if self._pixmap is not None and e.oldSize().width() != e.size().width(): self._adjust_meta_widget_height() def _adjust_meta_widget_height(self): # HACK: adjust height of table_container's meta_widget to # adapt to background image. if self._pixmap is None: self.table_container.meta_widget.setMinimumHeight(0) else: height = (self._background_image_height_hint() - self.bottom_panel.height() - self.table_container.toolbar.height()) self.table_container.meta_widget.setMinimumHeight(height) def _background_image_height_hint(self): return self.width() * 5 // 9
class tools(QWidget): tool_list = ['推荐', '历史', 'tip', '公告'] def __init__(self): self.db = DBModel() super().__init__() self.init() def init(self): self.btn_recommend = QPushButton("推荐") self.btn_history = QPushButton("历史上的今天") self.btn_tip = QPushButton("小tip") self.btn_announce = QPushButton("公告") self.btn_tip.setFixedSize(250, 35) self.btn_history.setFixedSize(250, 35) self.btn_announce.setFixedSize(250, 35) self.btn_recommend.setFixedSize(250, 35) frame = QFrame(self) self.qsl = QStackedLayout(frame) toolbar = QHBoxLayout() layout = QVBoxLayout() toolbar.addWidget(self.btn_recommend) toolbar.addWidget(self.btn_history) toolbar.addWidget(self.btn_tip) toolbar.addWidget(self.btn_announce) self.loadPages() self.btn_event() layout.addLayout(toolbar) layout.addWidget(frame) self.setLayout(layout) def loadPages(self): self.history_page = history() self.recommend_page = recommend("recommend") self.tip_page = recommend("tips") self.annouce_page = recommend("annouce") self.qsl.addWidget(self.recommend_page) self.qsl.addWidget(self.history_page) self.qsl.addWidget(self.tip_page) self.qsl.addWidget(self.annouce_page) def setdb(self, db): self.db = db self.history_page.set_db(db) self.recommend_page.set_db(db) self.tip_page.set_db(db) self.annouce_page.set_db(db) def btn_event(self): self.btn_recommend.clicked.connect(lambda: self.to_page(0)) self.btn_history.clicked.connect(lambda: self.to_page(1)) self.btn_tip.clicked.connect(lambda: self.to_page(2)) self.btn_announce.clicked.connect(lambda: self.to_page(3)) def to_page(self, num): print('切换:', self.tool_list[num], '页') self.qsl.setCurrentIndex(num)
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _win_id: The window ID the statusbar is associated with. Class attributes: _prompt_active: If we're currently in prompt-mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _insert_active: If we're currently in insert mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _command_active: If we're currently in command mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _caret_mode: The current caret mode (off/on/selection). For some reason we need to have this as class attribute so pyqtProperty works correctly. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move to the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _severity = None _prompt_active = False _insert_active = False _command_active = False _caret_mode = CaretMode.off STYLESHEET = """ QWidget#StatusBar, QWidget#StatusBar QLabel, QWidget#StatusBar QLineEdit { font: {{ font['statusbar'] }}; background-color: {{ color['statusbar.bg'] }}; color: {{ color['statusbar.fg'] }}; } QWidget#StatusBar[caret_mode="on"], QWidget#StatusBar[caret_mode="on"] QLabel, QWidget#StatusBar[caret_mode="on"] QLineEdit { color: {{ color['statusbar.fg.caret'] }}; background-color: {{ color['statusbar.bg.caret'] }}; } QWidget#StatusBar[caret_mode="selection"], QWidget#StatusBar[caret_mode="selection"] QLabel, QWidget#StatusBar[caret_mode="selection"] QLineEdit { color: {{ color['statusbar.fg.caret-selection'] }}; background-color: {{ color['statusbar.bg.caret-selection'] }}; } QWidget#StatusBar[prompt_active="true"], QWidget#StatusBar[prompt_active="true"] QLabel, QWidget#StatusBar[prompt_active="true"] QLineEdit { color: {{ color['prompts.fg'] }}; background-color: {{ color['prompts.bg'] }}; } QWidget#StatusBar[insert_active="true"], QWidget#StatusBar[insert_active="true"] QLabel, QWidget#StatusBar[insert_active="true"] QLineEdit { color: {{ color['statusbar.fg.insert'] }}; background-color: {{ color['statusbar.bg.insert'] }}; } QWidget#StatusBar[command_active="true"], QWidget#StatusBar[command_active="true"] QLabel, QWidget#StatusBar[command_active="true"] QLineEdit { color: {{ color['statusbar.fg.command'] }}; background-color: {{ color['statusbar.bg.command'] }}; } """ def __init__(self, win_id, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._option = None self._hbox = QHBoxLayout(self) self.set_hbox_padding() objreg.get('config').changed.connect(self.set_hbox_padding) self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) self.tabindex = tabindex.TabIndex() self._hbox.addWidget(self.tabindex) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) objreg.get('config').changed.connect(self.maybe_hide) QTimer.singleShot(0, self.maybe_hide) def __repr__(self): return utils.get_repr(self) @config.change_filter('ui', 'hide-statusbar') def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" hide = config.get('ui', 'hide-statusbar') if hide: self.hide() else: self.show() @config.change_filter('ui', 'statusbar-padding') def set_hbox_padding(self): padding = config.get('ui', 'statusbar-padding') self._hbox.setContentsMargins(padding.left, 0, padding.right, 0) @pyqtProperty(bool) def prompt_active(self): """Getter for self.prompt_active, so it can be used as Qt property.""" return self._prompt_active @pyqtProperty(bool) def command_active(self): """Getter for self.command_active, so it can be used as Qt property.""" return self._command_active @pyqtProperty(bool) def insert_active(self): """Getter for self.insert_active, so it can be used as Qt property.""" return self._insert_active @pyqtProperty(str) def caret_mode(self): """Getter for self._caret_mode, so it can be used as Qt property.""" return self._caret_mode.name def set_mode_active(self, mode, val): """Setter for self.{insert,command,caret}_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if mode == usertypes.KeyMode.insert: log.statusbar.debug("Setting insert_active to {}".format(val)) self._insert_active = val if mode == usertypes.KeyMode.command: log.statusbar.debug("Setting command_active to {}".format(val)) self._command_active = val elif mode in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]: log.statusbar.debug("Setting prompt_active to {}".format(val)) self._prompt_active = val elif mode == usertypes.KeyMode.caret: tab = objreg.get('tabbed-browser', scope='window', window=self._win_id).currentWidget() log.statusbar.debug("Setting caret_mode - val {}, selection " "{}".format(val, tab.caret.selection_enabled)) if val: if tab.caret.selection_enabled: self._set_mode_text("{} selection".format(mode.name)) self._caret_mode = CaretMode.selection else: self._set_mode_text(mode.name) self._caret_mode = CaretMode.on else: self._caret_mode = CaretMode.off self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) def _set_mode_text(self, mode): """Set the mode text.""" text = "-- {} MODE --".format(mode.upper()) self.txt.set_text(self.txt.Text.normal, text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._stack.setCurrentWidget(self.cmd) self.show() def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget") self._stack.setCurrentWidget(self.txt) self.maybe_hide() @pyqtSlot(str) def set_text(self, val): """Set a normal (persistent) text in the status bar.""" self.txt.set_text(self.txt.Text.normal, val) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[mode].passthrough: self._set_mode_text(mode.name) if mode in [ usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno ]: self.set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): """Clear marked mode.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[old_mode].passthrough: if keyparsers[new_mode].passthrough: self._set_mode_text(new_mode.name) else: self.txt.set_text(self.txt.Text.normal, '') if old_mode in [ usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno ]: self.set_mode_active(old_mode, False) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos()) def minimumSizeHint(self): """Set the minimum height to the text height plus some padding.""" padding = config.get('ui', 'statusbar-padding') width = super().minimumSizeHint().width() height = self.fontMetrics().height() + padding.top + padding.bottom return QSize(width, height)
def __init__(self, parent): super().__init__(parent) self.setAcceptDrops(True) self.parent_widget = parent self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) self.parent_widget self._widget_layout = QHBoxLayout(self) # widget stuff self._d_widget = QWidget(self) self._widget_layout.addWidget(self._d_widget) self.main_layout = QVBoxLayout(self._d_widget) self.main_layout.setSpacing(0) self.main_layout.setContentsMargins(0,0,0,0) self.arrow_handle = misc.ArrowHandle(self) self.arrow_handle.CLICKED.connect(self.slide) self._widget_layout.addWidget(self.arrow_handle) self.setContentsMargins(0,0,-self.arrow_handle.width(),0) self.show_all_galleries_btn = QPushButton("Show all galleries") self.show_all_galleries_btn.clicked.connect(lambda:parent.manga_list_view.sort_model.set_gallery_list()) self.show_all_galleries_btn.clicked.connect(self.show_all_galleries_btn.hide) self.show_all_galleries_btn.hide() self.main_layout.addWidget(self.show_all_galleries_btn) self.main_buttons_layout = QHBoxLayout() self.main_layout.addLayout(self.main_buttons_layout) # buttons bgroup = QButtonGroup(self) bgroup.setExclusive(True) self.lists_btn = QPushButton("Lists") self.lists_btn.setCheckable(True) bgroup.addButton(self.lists_btn) self.artist_btn = QPushButton("Artists") self.artist_btn.setCheckable(True) bgroup.addButton(self.artist_btn) self.ns_tags_btn = QPushButton("NS && Tags") self.ns_tags_btn.setCheckable(True) bgroup.addButton(self.ns_tags_btn) self.lists_btn.setChecked(True) self.main_buttons_layout.addWidget(self.lists_btn) self.main_buttons_layout.addWidget(self.artist_btn) self.main_buttons_layout.addWidget(self.ns_tags_btn) # buttons contents self.stacked_layout = QStackedLayout() self.main_layout.addLayout(self.stacked_layout) # lists gallery_lists_dummy = QWidget(self) self.lists = GalleryLists(self) create_new_list_btn = QPushButton() create_new_list_btn.setIcon(QIcon(app_constants.PLUS_PATH)) create_new_list_btn.setIconSize(QSize(15, 15)) create_new_list_btn.clicked.connect(lambda: self.lists.create_new_list()) create_new_list_btn.adjustSize() create_new_list_btn.setFixedSize(create_new_list_btn.width(), create_new_list_btn.height()) create_new_list_btn.setToolTip("Create a new list!") lists_l = QVBoxLayout(gallery_lists_dummy) lists_l.setContentsMargins(0,0,0,0) lists_l.setSpacing(0) lists_l.addWidget(self.lists) lists_l.addWidget(create_new_list_btn) lists_index = self.stacked_layout.addWidget(gallery_lists_dummy) self.lists.GALLERY_LIST_CLICKED.connect(parent.manga_list_view.sort_model.set_gallery_list) self.lists.GALLERY_LIST_CLICKED.connect(self.show_all_galleries_btn.show) self.lists.GALLERY_LIST_REMOVED.connect(self.show_all_galleries_btn.click) self.lists_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(lists_index)) self.show_all_galleries_btn.clicked.connect(self.lists.clearSelection) self.show_all_galleries_btn.clicked.connect(self.lists._reset_selected) # artists self.artists_list = GalleryArtistsList(parent.manga_list_view.gallery_model, self) self.artists_list.artist_clicked.connect(lambda a: parent.search('artist:"{}"'.format(a))) artists_list_index = self.stacked_layout.addWidget(self.artists_list) self.artist_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(artists_list_index)) #self.lists.GALLERY_LIST_CLICKED.connect(self.artists_list.set_current_glist) self.show_all_galleries_btn.clicked.connect(self.artists_list.clearSelection) #self.show_all_galleries_btn.clicked.connect(lambda:self.artists_list.set_current_glist()) # ns_tags self.tags_tree = TagsTreeView(self) self.tags_tree.TAG_SEARCH.connect(parent.search) self.tags_tree.NEW_LIST.connect(self.lists.create_new_list) self.tags_tree.setHeaderHidden(True) self.show_all_galleries_btn.clicked.connect(self.tags_tree.clearSelection) self.tags_layout = QVBoxLayout(self.tags_tree) ns_tags_index = self.stacked_layout.addWidget(self.tags_tree) self.ns_tags_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(ns_tags_index)) self.slide_animation = misc.create_animation(self, "maximumSize") self.slide_animation.stateChanged.connect(self._slide_hide) self.slide_animation.setEasingCurve(QEasingCurve.InOutQuad)
class Bar(QWidget): """Bar at the bottom including statusbar and commandline. Attributes: _commandline: Commandline widget in the bar. _completer: Completer to handle interaction between command line and completion. _stack: QStackedLayout containing statusbar and commandline. """ @api.objreg.register def __init__(self, mainwindow): super().__init__(parent=mainwindow) statusbar.init() self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._commandline = commandline.CommandLine() completion_widget = completionwidget.CompletionView(mainwindow) mainwindow.add_overlay(completion_widget, resize=False) self._completer = completer.Completer(self._commandline, completion_widget) self._stack = QStackedLayout(self) self._stack.addWidget(statusbar.statusbar) self._stack.addWidget(self._commandline) self._stack.setCurrentWidget(statusbar.statusbar) self._commandline.editingFinished.connect(self._on_editing_finished) statusbar.statusbar.timer.timeout.connect(self._maybe_hide) api.settings.statusbar.show.changed.connect(self._on_show_changed) api.status.signals.clear.connect(self._maybe_hide) utils.log.statusbar_loghandler.message.connect(self.show) if not api.settings.statusbar.show.value: self.hide() @api.keybindings.register("<colon>", "command", mode=api.modes.MANIPULATE) @api.keybindings.register("<colon>", "command") @api.commands.register(hide=True, store=False, mode=api.modes.MANIPULATE) @api.commands.register(hide=True, store=False) def command(self, text: str = ""): """Enter command mode. **syntax:** ``:command [--text=TEXT]`` optional arguments: * ``--text``: String to append to the ``:`` prefix. """ self._enter_command_mode(":" + text) @api.keybindings.register("?", "search --reverse") @api.keybindings.register("/", "search") @api.commands.register(hide=True, store=False) def search(self, reverse: bool = False): """Start a search. **syntax:** ``:search [--reverse]`` optional arguments: * ``--reverse``: Search in reverse direction. """ if reverse: self._enter_command_mode("?") else: self._enter_command_mode("/") def _enter_command_mode(self, text): """Enter command mode setting the text to text.""" self.show() self._stack.setCurrentWidget(self._commandline) api.modes.COMMAND.enter() self._commandline.setText(text) self._completer.initialize(text) @api.keybindings.register("<escape>", "leave-commandline", mode=api.modes.COMMAND) @api.commands.register(mode=api.modes.COMMAND) def leave_commandline(self): """Leave command mode.""" self._commandline.editingFinished.emit() @utils.slot def _on_editing_finished(self): """Leave command mode on the editingFinished signal.""" self._commandline.setText("") self._stack.setCurrentWidget(statusbar.statusbar) self._maybe_hide() api.modes.COMMAND.leave() def _on_show_changed(self, value: bool): statusbar.statusbar.setVisible(value) self._maybe_hide() def _maybe_hide(self): """Hide bar if statusbar is not visible and not in command mode.""" always_show = api.settings.statusbar.show.value if not always_show and not self._commandline.hasFocus(): self.hide() else: self.show()
class TaskWidget(QWidget): taskModified = pyqtSignal(tasklib.Task) taskDeleted = pyqtSignal(tasklib.Task) taskCreated = pyqtSignal(tasklib.Task) def __init__(self, parent, task, new=False): QWidget.__init__(self, parent) self.task = task self.new = new self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.layout = QStackedLayout(self) self.label = QLabel(self) self.label.setTextFormat(Qt.RichText) self.label.setOpenExternalLinks(True) self._update() self.label.setWordWrap(True) self.layout.addWidget(self.label) self.editor = TaskEditorLineEdit(self, parent.mfile) self.layout.addWidget(self.editor) self.setLayout(self.layout) self.layout.setCurrentIndex(0) self.editor.editingFinished.connect(self.editFinished) self.task.modified.connect(self._update) def sizeHint(self): return self.label.size() def edit(self): self.editor.setText(self.task.text) self.layout.setCurrentIndex(1) self.editor.setFocus() def editFinished(self): # qt bug, this method may be called several times for one edit self.layout.setCurrentIndex(0) text = self.editor.text() if not text: self.taskDeleted.emit(self.task) elif self.new: self.task.text = text self.new = False self.taskCreated.emit(self.task) elif text != self.task.text: self.task.text = text self.taskModified.emit(self) self.parent().setFocus() def _update(self): self.label.setText(self.task.toHtml()) def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.editor.setText(self.task.text) self.layout.setCurrentIndex(0) self.parent().setFocus()
def __init__(self, model, session, viewOnly = False, returnDataSignal = None, parent=None): super(odoeSimSetup, self).__init__(parent) self.setupUi(self) self.viewOnly = viewOnly self.returnDataSignal = returnDataSignal self.sampleFileSet = set() # Contains which inputs are of the distribution "Sample from File" self.fsDataBrowser = dataBrowserFrame(session, self) self.dataViewWidget.setLayout(QStackedLayout(self.dataViewWidget)) self.dataViewWidget.layout().addWidget(self.fsDataBrowser) self.fsDataBrowser.refreshContents() self.fileLoaded = False self.samplesGenerated = False self.currentArchiveData = None self.model = model self.session = session if isinstance(model, Model): data = SampleData(model) dists = [] for i in range(model.getNumInputs()): dists = dists + ['U'] data.setInputDistributions(dists) else: data = model self.currentArchiveData = data self.ignoreDistributionCheck = False if model.getRunType() == Model.EMULATOR: self.flowsheetDataRadio.setHidden(True) if viewOnly: self.loadSamplesRadio.setEnabled(False) self.flowsheetDataRadio.setEnabled(False) self.loadSamplesRadio.clicked.connect(self.setPage) self.flowsheetDataRadio.clicked.connect(self.setPage) self.chooseSchemeRadio.clicked.connect(self.setPage) self.setPage() self.groupBox_2.setHidden(True) self.cancelButton.clicked.connect(self.cancel) self.previewButton.clicked.connect(self.preview) self.previewButton.setEnabled(False) self.doneButton.clicked.connect(self.doneClicked) self.doneButton.setEnabled(False) if viewOnly: self.cancelButton.setText('OK') self.doneButton.setHidden(True) self.samplingTabs.setTabEnabled(1, False) # Make sure appropriate option is visible if not isinstance(model, Model): if model.getInputData() is not None: self.previewButton.setEnabled(True) if not viewOnly: self.doneButton.setEnabled(True) self.runData = model # Make sure distribution tab is showing self.samplingTabs.setCurrentIndex(0) self.samplingTabs.currentChanged[int].connect(self.checkDists) # Set up distributions table self.distTable.init(model, InputPriorTable.SIMSETUP, viewOnly=viewOnly) self.allFixedButton.clicked.connect(self.makeAllFixed) self.allVariableButton.clicked.connect(self.makeAllVariable) if viewOnly or model.getRunType() == Model.EMULATOR: self.allFixedButton.setHidden(True) self.allVariableButton.setHidden(True) # Set up sampling schemes tab self.generateSamplesButton.setEnabled(False) self.generateStatusText.setText('') self.allSchemesRadio.setChecked(True) foundLibs = LocalExecutionModule.getPsuadeInstalledModules(); foundMETIS = foundLibs['METIS'] self.schemesList.clear() self.schemesList.addItems(SamplingMethods.fullNames[0:4]) self.schemesList.addItems(SamplingMethods.fullNames[7:8]) self.schemesList.addItems(SamplingMethods.fullNames[9:]) if not foundMETIS: item = self.schemesList.item(SamplingMethods.METIS) text = item.text() item.setText(text + ' (Not installed)') flags = item.flags() item.setFlags(flags & ~Qt.ItemIsEnabled) if isinstance(model, SampleData): self.schemesList.setCurrentRow(model.getSampleMethod()) self.generateSamplesButton.setEnabled(True) # Change lists of schemes displayed self.allSchemesRadio.toggled.connect(self.showAllSchemes) self.adaptiveRefineRadio.toggled.connect(self.showAdaptiveRefineSchemes) self.otherRadio.toggled.connect(self.showOtherSchemes) self.schemesList.currentItemChanged.connect(self.handleGenerateSamplesButton) self.generateSamplesButton.clicked.connect(self.generateSamples)
class _MainContainer(QWidget): currentEditorChanged = pyqtSignal(str) fileOpened = pyqtSignal(str) beforeFileSaved = pyqtSignal(str) fileSaved = pyqtSignal(str) runFile = pyqtSignal(str) showFileInExplorer = pyqtSignal(str) addToProject = pyqtSignal(str) allFilesClosed = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self.setAcceptDrops(True) self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) self.stack = QStackedLayout() self.stack.setStackingMode(QStackedLayout.StackAll) self._vbox.addLayout(self.stack) self.splitter = dynamic_splitter.DynamicSplitter() self._files_handler = files_handler.FilesHandler(self) # Code Navigation self.__code_back = [] self.__code_forward = [] self.__operations = { 0: self._navigate_code_jumps, 1: self._navigate_bookmarks } # Recent files list self.__last_opened_files = [] # QML UI self._add_file_folder = add_file_folder.AddFileFolderWidget(self) if settings.SHOW_START_PAGE: self.show_start_page() IDE.register_service("main_container", self) # Register signals connections connections = ( # { # "target": "main_container", # "signal_name": "updateLocator", # "slot": self._explore_code # }, { "target": "filesystem", "signal_name": "projectOpened", "slot": self._explore_code }, # { # "target": "projects_explore", # "signal_name": "updateLocator", # "slot": self._explore_code # } { "target": "filesystem", "signal_name": "projectClosed", "slot": self._explore_code } ) IDE.register_signals("main_container", connections) fhandler_short = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Tab), self) fhandler_short.activated.connect(self.show_files_handler) # Added for set language # self._setter_language = set_language.SetLanguageFile() def install(self): ninjaide = IDE.get_service("ide") ninjaide.place_me_on("main_container", self, "central", top=True) self.combo_area = combo_editor.ComboEditor(original=True) self.combo_area.allFilesClosed.connect(self._files_closed) self.combo_area.allFilesClosed.connect( lambda: self.allFilesClosed.emit()) self.combo_area.fileClosed.connect(self._add_to_last_opened) self.splitter.add_widget(self.combo_area) self.add_widget(self.splitter) # self.current_widget = self.combo_area # Code Locator self._code_locator = locator_widget.LocatorWidget(ninjaide) data_settings = IDE.data_settings() recent_files = data_settings.value("lastSession/recentFiles") if recent_files is not None: self.__last_opened_files = recent_files ui_tools.install_shortcuts(self, actions.ACTIONS, ninjaide) # self.fileSaved.connect(self._show_message_about_saved) def run_file(self, filepath): self.runFile.emit(filepath) def _show_file_in_explorer(self, filepath): self.showFileInExplorer.emit(filepath) def _add_to_project(self, filepath): self.addToProject.emit(filepath) def show_files_handler(self): self._files_handler.next_item() def hide_files_handler(self): self._files_handler.hide() def import_from_everywhere(self): """Insert an import line from any place in the editor.""" editorWidget = self.get_current_editor() if editorWidget: dialog = from_import_dialog.FromImportDialog(editorWidget, self) dialog.show() def navigate_code_history(self, operation, forward): self.__operations[operation](forward) def _navigate_code_jumps(self, forward=False): """Navigate between the jump points""" node = None if not forward and self.__code_back: if len(self.__code_back) == 1: return node = self.__code_back.pop() self.__code_forward.append(node) node = self.__code_back[-1] elif forward and self.__code_forward: node = self.__code_forward.pop() self.__code_back.append(node) if node is not None: filename = node[0] line, col = node[1] self.open_file(filename, line, col) def _navigate_bookmarks(self, forward=True): """Navigate between the bookmarks""" current_editor = self.get_current_editor() current_editor.navigate_bookmarks(forward=forward) def _set_focus_to_editor(self): status_bar = IDE.get_service("status_bar") tools_doock = IDE.get_service("tools_dock") editor_widget = self.get_current_editor() if status_bar.isVisible() and tools_doock.isVisible(): status_bar.hide_status_bar() elif tools_doock.isVisible(): tools_doock._hide() elif status_bar.isVisible(): status_bar.hide_status_bar() if editor_widget is not None: editor_widget.extra_selections.remove("find") editor_widget.scrollbar().remove_marker("find") def split_assistance(self): editor_widget = self.get_current_editor() if editor_widget is not None: split_widget = split_orientation.SplitOrientation(self) split_widget.show() def show_dialog(self, widget): self.add_widget(widget) self.stack.setCurrentWidget(widget) def show_split(self, orientation_vertical=False): orientation = Qt.Horizontal if orientation_vertical: orientation = Qt.Vertical self.combo_area.split_editor(orientation) def show_locator(self): """Show the Locator Widget""" if not self._code_locator.isVisible(): self._code_locator.show() def _explore_code(self): """Update locator metadata for the current projects""" self._code_locator.explore_code() def _explore_file_code(self, path): """Update locator metadata for the file in path""" self._code_locator.explore_file_code(path) def current_editor_changed(self, filename): """Notify the new filename of the current editor""" if filename is None: filename = translations.TR_NEW_DOCUMENT self.currentEditorChanged.emit(filename) def get_current_editor(self): current_widget = self.combo_area.current_editor() if isinstance(current_widget, editor.NEditor): return current_widget return None @property def last_opened_files(self): return self.__last_opened_files def _add_to_last_opened(self, nfile): MAX_RECENT_FILES = 10 # FIXME: configuration if nfile.is_new_file: return file_path = nfile.file_path if file_path in self.__last_opened_files: self.__last_opened_files.remove(file_path) self.__last_opened_files.insert(0, file_path) if len(self.__last_opened_files) > MAX_RECENT_FILES: self.__last_opened_files.pop(-1) def clear_last_opened_files(self): self.__last_opened_files.clear() def open_file(self, filename='', line=-1, col=0, ignore_checkers=False): logger.debug("Will try to open %s" % filename) if not filename: logger.debug("Has no filename") if settings.WORKSPACE: directory = settings.WORKSPACE else: directory = os.path.expanduser("~") editor_widget = self.get_current_editor() ninjaide = IDE.get_service("ide") current_project = ninjaide.get_current_project() # TODO: handle current project in NProject if current_project is not None: directory = current_project.full_path elif editor_widget is not None and editor_widget.file_path: directory = file_manager.get_folder( editor_widget.file_path) filenames = QFileDialog.getOpenFileNames( self, translations.TR_OPEN_A_FILE, directory, settings.get_supported_extensions_filter(), initialFilter="Python files (*.py *.pyw)" )[0] else: logger.debug("Has filename") filenames = [filename] if not filenames: return for filename in filenames: image_extensions = ("png", "jpg", "jpeg", "bmp", "gif") if file_manager.get_file_extension(filename) in image_extensions: logger.debug("Will open as image") self.open_image(filename) else: logger.debug("Will try to open: %s" % filename) self.__open_file( filename, line, col, ignore_checkers=ignore_checkers) def __open_file(self, filename, line, col, ignore_checkers=False): try: self.add_editor(filename) if line != -1: self.editor_go_to_line(line, col) self.currentEditorChanged.emit(filename) except file_manager.NinjaIOException as reason: QMessageBox.information( self, translations.TR_OPEN_FILE_ERROR, str(reason)) logger.error("The file %s couldn't be open" % filename) def open_image(self, filename): for index in range(self.combo_area.stacked.count()): widget = self.combo_area.stacked.widget(index) if isinstance(widget, image_viewer.ImageViewer): if widget.image_filename == filename: logger.debug("Image already open") self.combo_area._set_current(neditable=None, index=index) return viewer = image_viewer.ImageViewer(filename) self.combo_area.add_image_viewer(viewer) self.stack.setCurrentWidget(self.splitter) def autosave_file(self): for neditable in self.combo_area.bar.get_editables(): neditable.autosave_file() def save_file(self, editor_widget=None): if editor_widget is None: # This may return None if there is not editor present editor_widget = self.get_current_editor() if editor_widget is None: return False # Ok, we have an editor instance # Save to file only if editor really was modified if editor_widget.is_modified: try: if editor_widget.nfile.is_new_file or \ not editor_widget.nfile.has_write_permission(): return self.save_file_as(editor_widget) file_path = editor_widget.file_path # Emit signal before save self.beforeFileSaved.emit(file_path) if settings.REMOVE_TRAILING_SPACES: editor_widget.remove_trailing_spaces() if settings.ADD_NEW_LINE_AT_EOF: editor_widget.insert_block_at_end() # Save content editor_widget.neditable.save_content() # FIXME: encoding message = translations.TR_FILE_SAVED.format(file_path) self.fileSaved.emit(message) return True except Exception as reason: logger.error("Save file error: %s" % reason) QMessageBox.information( self, translations.TR_SAVE_FILE_ERROR_TITLE, translations.TR_SAVE_FILE_ERROR_BODY ) return False def save_file_as(self, editor_widget=None): force = False if editor_widget is None: # We invoque from menu editor_widget = self.get_current_editor() if editor_widget is None: # We haven't editor in main container return False force = True try: filters = "(*.py);;(*.*)" if editor_widget.file_path is not None: # Existing file extension = file_manager.get_file_extension( editor_widget.file_path) if extension != 'py': filters = "(*.%s);;(*.py);;(*.*)" % extension save_folder = self._get_save_folder(editor_widget.file_path) else: save_folder = settings.WORKSPACE filename = QFileDialog.getSaveFileName( self, translations.TR_SAVE_FILE_DIALOG, save_folder, filters )[0] if not filename: return False # FIXME: remove trailing spaces extension = file_manager.get_file_extension(filename) if not extension: filename = "%s.%s" % (filename, "py") editor_widget.neditable.save_content(path=filename, force=force) # self._setter_language.set_language_from_extension(extension) self.fileSaved.emit(translations.TR_FILE_SAVED.format(filename)) self.currentEditorChanged.emit(filename) return True except file_manager.NinjaFileExistsException as reason: QMessageBox.information( self, translations.TR_FILE_ALREADY_EXISTS_TITLE, translations.TR_FILE_ALREADY_EXISTS_BODY.format( reason.filename) ) except Exception as reason: logger.error("Save file as: %s", reason) QMessageBox.information( self, translations.TR_SAVE_FILE_ERROR_TITLE, translations.TR_SAVE_FILE_ERROR_BODY ) return False def save_project(self, project_path): """Save all files in the project path""" for neditable in self.combo_area.bar.get_editables(): file_path = neditable.file_path if file_path is None: # FIXME: New edited files will not be saved, its ok? continue if file_manager.belongs_to_folder(project_path, file_path): neditable.save_content() def _get_save_folder(self, filename): """Returns the root directory of the 'Main Project' or the home folder""" ninjaide = IDE.get_service("ide") current_project = ninjaide.get_current_project() if current_project is not None: return current_project.path return os.path.expanduser("~") def close_file(self): self.combo_area.close_current_file() def add_editor(self, filename=None): ninjaide = IDE.get_service("ide") editable = ninjaide.get_or_create_editable(filename) if editable.editor: # If already open logger.debug("%s is already open" % filename) self.combo_area.set_current(editable) return self.combo_area.current_editor() else: pass editor_widget = self.create_editor_from_editable(editable) # editor_widget.set_language() # Add the tab keep_index = (self.splitter.count() > 1 and self.combo_area.stacked.count() > 0) self.combo_area.add_editor(editable, keep_index) # Emit a signal about the file open self.fileOpened.emit(filename) if keep_index: self.combo_area.set_current(editable) self.stack.setCurrentWidget(self.splitter) editor_widget.setFocus() return editor_widget def create_editor_from_editable(self, editable): neditor = editor.create_editor(editable) neditor.zoomChanged.connect(self._on_zoom_changed) neditor.addBackItemNavigation.connect(self.add_back_item_navigation) editable.fileSaved.connect( lambda neditable: self._explore_file_code(neditable.file_path)) return neditor def add_back_item_navigation(self): editor_widget = self.get_current_editor() if editor_widget is not None: item = (editor_widget.file_path, editor_widget.cursor_position) if item not in self.__code_back: self.__code_back.append(item) # self.__code_forward.clear() def _on_zoom_changed(self, zoom): text = "Zoom: {}%".format(str(zoom)) ide = IDE.get_service("ide") ide.show_message(text) def add_widget(self, widget): self.stack.addWidget(widget) def show_start_page(self): """Show Start Page widget in main container""" startp = self.stack.widget(0) if isinstance(startp, start_page.StartPage): self.stack.setCurrentIndex(0) else: startp = start_page.StartPage(parent=self) startp.newFile.connect(self.add_editor) self.stack.insertWidget(0, startp) self.stack.setCurrentIndex(0) def _files_closed(self): if settings.SHOW_START_PAGE: self.show_start_page() def add_status_bar(self, status_bar): self._vbox.addWidget(status_bar) def create_file(self, base_path, project_path): self._add_file_folder.create_file(base_path, project_path) def create_folder(self, base_path, project_path): self._add_file_folder.create_folder(base_path, project_path) def restyle_editor(self): neditables = self.combo_area.bar.get_editables() for neditable in neditables: neditable.editor.restyle() def zoom_in_editor(self): """Increase the font size in the current editor""" editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.zoom(1.) def zoom_out_editor(self): """Decrease the font size in the current editor""" editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.zoom(-1.) def reset_zoom_editor(self): """Reset the to original font size in the current editor""" editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.reset_zoom() def editor_move_up(self): editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.move_up_down(up=True) def editor_move_down(self): editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.move_up_down() def editor_duplicate_line(self): editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.duplicate_line() def editor_toggle_comment(self): """Mark the current line or selection as a comment.""" editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.comment_or_uncomment() def editor_go_to_line(self, line, column=0, center=True): editor_widget = self.get_current_editor() if editor_widget is not None: editor_widget.go_to_line(line, column, center) editor_widget.setFocus() def _editor_settings_changed(self, key, value): key = key.split("/")[-1] editor_widget = self.get_current_editor() if editor_widget is not None: callback = getattr(editor.NEditor, key, False) if callback: callback = callback if not hasattr(callback, "__call__"): # Property! callback = callback.fset callback(editor_widget, value) def toggle_tabs_and_spaces(self): """Toggle Show/Hide Tabs and Spaces""" settings.SHOW_TABS_AND_SPACES = not settings.SHOW_TABS_AND_SPACES qsettings = IDE.ninja_settings() qsettings.setValue('preferences/editor/showTabsAndSpaces', settings.SHOW_TABS_AND_SPACES) neditor = self.get_current_editor() if neditor is not None: neditor.show_whitespaces = settings.SHOW_TABS_AND_SPACES def __navigate_with_keyboard(self, forward): """Navigate between the positions in the jump history stack.""" operation = self.combo_area.bar.code_navigator.operation self.navigate_code_history(operation, forward) def navigate_back(self): self.__navigate_with_keyboard(forward=False) def navigate_forward(self): self.__navigate_with_keyboard(forward=True)
def __init__(self, parent: typing.Optional[QWidget], on_connection_request: ConnectionRequestCallback, on_disconnection_request: DisconnectionRequestCallback): super(DeviceManagementWidget, self).__init__(parent) self.setAttribute( Qt.WA_DeleteOnClose) # This is required to stop background timers! self._port_discoverer = PortDiscoverer() self._port_mapping: typing.Dict[str:str] = {} self._port_combo = QComboBox(self) self._port_combo.setEditable(True) self._port_combo.setInsertPolicy(QComboBox.NoInsert) self._port_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) self._port_combo.setFont(get_monospace_font()) self._port_combo.lineEdit().returnPressed.connect( self._on_confirmation) self._connect_button = make_button(self, 'Connect', 'disconnected', on_clicked=self._on_confirmation) self._connect_button.setEnabled( False) # Empty by default, therefore disabled self._port_combo.currentTextChanged.connect( lambda: self._connect_button.setEnabled( bool(self._port_combo.currentText().strip()))) self._status_text = QLabel(self) self._status_text.setText(_STATUS_WHEN_NOT_CONNECTED) self._status_text.setWordWrap(True) self._device_info_widget = LittleBobbyTablesWidget(self) combo_completer = QCompleter() combo_completer.setCaseSensitivity(Qt.CaseInsensitive) combo_completer.setModel(self._port_combo.model()) self._port_combo.setCompleter(combo_completer) self._update_timer = QTimer(self) self._update_timer.timeout.connect(self._update_ports) self._update_timer.start(2000) self._connection_progress_bar = QProgressBar(self) self._connection_progress_bar.setMinimum(0) self._connection_progress_bar.setMaximum(100) self._connection_established = False self._last_task: typing.Optional[asyncio.Task] = None self._connection_request_callback: ConnectionRequestCallback = on_connection_request self._disconnection_request_callback: DisconnectionRequestCallback = on_disconnection_request # Layout self._overlay = QStackedLayout(self) self._init_overlay_widgets() self.setLayout(self._overlay) # Initialization self._update_ports()
def __init__(self, name="Video", path=None, toolbar=None): super().__init__() # self.setFloating(False) # self.setFeatures(QDockWidget.DockWidgetMovable) # self.setAllowedAreas(Qt.AllDockWidgetAreas) # Structure self.setLayout(QVBoxLayout()) self.setObjectName("VideoWidget") # Header buttons self.headerButtonRow = QWidget() self.headerButtonRow.setLayout(QHBoxLayout()) self.layout().addWidget(self.headerButtonRow) # Export button self.exportButton = QPushButton() self.exportButton.setText("Export") self.exportButton.setEnabled(True) self.exportButton.clicked.connect(self.exportFile) self.headerButtonRow.layout().addWidget(self.exportButton) # Close button self.closeButton = QPushButton() self.closeButton.setText("X") self.closeButton.setEnabled(True) self.closeButton.clicked.connect(self.deleteLater) self.headerButtonRow.layout().addWidget(self.closeButton) # Video self.videoContainer = QWidget() self.videoContainer.setLayout(QStackedLayout()) self.video = Video(None, video=path) self.videoContainer.layout().addWidget(self.video) self.layout().addWidget(self.videoContainer) self.video.stateChanged.connect(self.__onPlayerStateChange) # self.video.setFixedWidth(640) # Buttons self.buttonRow = QWidget() self.buttonRowLayout = QHBoxLayout() self.buttonRow.setLayout(self.buttonRowLayout) self.layout().addWidget(self.buttonRow) # Play self.playButton = QPushButton() self.playButton.setText("Play") self.playButton.setEnabled(False) self.playButton.clicked.connect(self.play) self.buttonRowLayout.addWidget(self.playButton) # Progress Bar self.progressSlider = QSlider(Qt.Horizontal) self.progressSlider.setRange(0, int(self.video.number_of_frames - 1)) self.progressSlider.sliderMoved.connect( self.setPosition) # set position when user moves slider self.progressSlider.sliderPressed.connect( self.video.pause) # pause when user presses slider self.video.positionChanged.connect( self.progressSlider.setValue) # update the slider as video plays self.buttonRowLayout.addWidget(self.progressSlider) # Passthrough click events self.video.mouse_down.connect(self.mouse_down.emit) self.video.mouse_move.connect(self.mouse_move.emit) self.video.mouse_up.connect(self.mouse_up.emit) self.video.mouse_over.connect( lambda data: self.mouse_over.emit(data[1])) self.video.mouse_leave.connect( lambda data: self.mouse_leave.emit(data[1])) self.video.scroll_event.connect( lambda val, x, y: self.scroll_event.emit(self.video, val, x, y)) # Register with Toolbar toolbar.register_video(self) VideoWidget.Widgets.append(self) self.destroyed.connect(lambda: VideoWidget.Widgets.remove(self) ) # TODO: check if this works
class ComboEditor(QWidget): # Signals closeSplit = pyqtSignal('PyQt_PyObject') splitEditor = pyqtSignal('PyQt_PyObject', 'PyQt_PyObject', Qt.Orientation) allFilesClosed = pyqtSignal() about_to_close_combo_editor = pyqtSignal() fileClosed = pyqtSignal("PyQt_PyObject") def __init__(self, original=False): super(ComboEditor, self).__init__(None) self.__original = original self.__undocked = [] self._symbols_index = [] vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.bar = ActionBar(main_combo=original) vbox.addWidget(self.bar) # Info bar # self.info_bar = InfoBar(self) # self.info_bar.setVisible(False) # vbox.addWidget(self.info_bar) self.stacked = QStackedLayout() vbox.addLayout(self.stacked) self._main_container = IDE.get_service('main_container') if not self.__original: self._main_container.fileOpened['QString'].connect( self._file_opened_by_main) self.bar.combo_files.showComboSelector.connect( self._main_container.show_files_handler) self.bar.combo_files.hideComboSelector.connect( self._main_container.hide_files_handler) self.bar.needUpdateFocus.connect(self._editor_with_focus) self.bar.change_current['PyQt_PyObject', int].connect(self._set_current) self.bar.splitEditor[bool].connect(self.split_editor) self.bar.runFile['QString'].connect(self._run_file) self.bar.closeSplit.connect(lambda: self.closeSplit.emit(self)) self.bar.addToProject['QString'].connect(self._add_to_project) self.bar.showFileInExplorer['QString'].connect( self._show_file_in_explorer) self.bar.goToSymbol[int].connect(self._go_to_symbol) self.bar.undockEditor.connect(self.undock_editor) self.bar.reopenTab['QString'].connect( lambda path: self._main_container.open_file(path)) self.bar.closeImageViewer.connect(self._close_image) self.bar.code_navigator.previousPressed.connect(self._navigate_code) self.bar.code_navigator.nextPressed.connect(self._navigate_code) # self.connect(self.bar, SIGNAL("recentTabsModified()"), # lambda: self._main_container.recent_files_changed()) # self.connect(self.bar.code_navigator.btnPrevious, # SIGNAL("clicked()"), # lambda: self._navigate_code(False)) # self.connect(self.bar.code_navigator.btnNext, SIGNAL("clicked()"), # lambda: self._navigate_code(True)) def _navigate_code(self, operation, forward=True): self._main_container.navigate_code_history(operation, forward) # op = self.bar.code_navigator.operation # self._main_container.navigate_code_history(val, op) def current_editor(self): return self.stacked.currentWidget() def setFocus(self): super(ComboEditor, self).setFocus() self.current_editor().setFocus() self._editor_with_focus() def _file_opened_by_main(self, path): index = self.stacked.currentIndex() ninjaide = IDE.get_service('ide') editable = ninjaide.get_or_create_editable(path) self.add_editor(editable) self.bar.set_current_by_index(index) if index == -1: self.bar.set_current_by_index(0) def add_image_viewer(self, viewer): """Add Image Viewer widget to the UI area""" self.stacked.addWidget(viewer) viewer.scaleFactorChanged.connect( self.bar.image_viewer_controls.update_scale_label) viewer.imageSizeChanged.connect( self.bar.image_viewer_controls.update_size_label) self.bar.add_item(viewer.display_name(), None) viewer.create_scene() if not self.bar.isVisible(): self.bar.setVisible(True) def add_editor(self, neditable, keep_index=False): """Add Editor Widget to the UI area.""" if neditable.editor: if self.__original: editor = neditable.editor else: # editor = neditable.editor.clone() editor = self._main_container.create_editor_from_editable( neditable) neditable.editor.link(editor) current_index = self.stacked.currentIndex() new_index = self.stacked.addWidget(editor) self.stacked.setCurrentIndex(new_index) self.bar.add_item(neditable.display_name, neditable) # Bar is not visible because all the files have been closed, # so if a new file is opened, show the bar if not self.bar.isVisible(): self.bar.setVisible(True) if keep_index: self.bar.set_current_by_index(current_index) # Connections neditable.fileClosing.connect(self._close_file) editor.editorFocusObtained.connect(self._editor_with_focus) editor.modificationChanged.connect(self._editor_modified) if neditable._swap_file.dirty: self._editor_modified(True, sender=editor) neditable.checkersUpdated.connect(self._show_notification_icon) # Connect file system signals only in the original if self.__original: neditable.askForSaveFileClosing.connect(self._ask_for_save) neditable.fileChanged.connect(self._file_has_been_modified) # Editor Signals editor.cursor_position_changed[int, int].connect( self._update_cursor_position) editor.current_line_changed[int].connect(self._set_current_symbol) """ # self.connect(editor, SIGNAL("editorFocusObtained()"), # self._editor_with_focus) editor.editorFocusObtained.connect(self._editor_with_focus) neditable.fileSaved['PyQt_PyObject'].connect( self._update_combo_info) neditable.fileSaved['PyQt_PyObject'].connect( self._update_symbols) editor.modificationChanged[bool].connect(self._editor_modified) neditable.checkersUpdated.connect(self._show_notification_icon) # Connect file system signals only in the original neditable.fileClosing['PyQt_PyObject'].connect(self._close_file) if self.__original: neditable.askForSaveFileClosing['PyQt_PyObject'].connect( self._ask_for_save) neditable.fileChanged['PyQt_PyObject'].connect( self._file_has_been_modified) self.info_bar.reloadClicked.connect(neditable.reload_file) # Load Symbols self._load_symbols(neditable) """ def show_combo_file(self): self.bar.combo.showPopup() def show_combo_symbol(self): self.bar.symbols_combo.showPopup() def show_combo_set_language(self): self.bar.set_language_combo.showPopup() def unlink_editors(self): for index in range(self.stacked.count()): widget = self.stacked.widget(index) # widget.setDocument(QsciDocument()) def clone(self): combo = ComboEditor() for neditable in self.bar.get_editables(): combo.add_editor(neditable) return combo def split_editor(self, orientation): new_combo = self.clone() self.splitEditor.emit(self, new_combo, orientation) def undock_editor(self): new_combo = ComboEditor() for neditable in self.bar.get_editables(): new_combo.add_editor(neditable) self.__undocked.append(new_combo) new_combo.setWindowTitle("NINJA-IDE") editor = self.current_editor() new_combo.set_current(editor.neditable) new_combo.resize(700, 500) new_combo.about_to_close_combo_editor.connect(self._remove_undock) new_combo.show() def _remove_undock(self): widget = self.sender() self.__undocked.remove(widget) def close_current_file(self): self.bar.about_to_close_file() def _close_image(self, index): layout_item = self.stacked.takeAt(index) layout_item.widget().deleteLater() if self.stacked.isEmpty(): self.bar.hide() self.allFilesClosed.emit() def _close_file(self, neditable): index = self.bar.close_file(neditable) layoutItem = self.stacked.takeAt(index) # neditable.editor.completer.cc.unload_module() # self._add_to_last_opened(neditable.file_path) self.fileClosed.emit(neditable.nfile) layoutItem.widget().deleteLater() if self.stacked.isEmpty(): self.bar.hide() self.allFilesClosed.emit() # def _add_to_last_opened(self, path): # if path not in settings.LAST_OPENED_FILES: # settings.LAST_OPENED_FILES.append(path) # if len(settings.LAST_OPENED_FILES) > settings.MAX_REMEMBER_EDITORS: # self.__lastOpened = self.__lastOpened[1:] # print("RecentTabsModified") # # self.emit(SIGNAL("recentTabsModified()")) def _editor_with_focus(self): # if self._main_container.current_widget is not self: self._main_container.combo_area = self editor = self.current_editor() # FIXME: maybe improve this in ComboFiles.needUpdateFocus # see issue #2027 if editor is not None: self._main_container.current_editor_changed( editor.neditable.file_path) self._load_symbols(editor.neditable) editor.neditable.update_checkers_display() def _ask_for_save(self, neditable): val = QMessageBox.No fileName = neditable.nfile.file_name val = QMessageBox.question( self, (self.tr('The file %s was not saved') % fileName), self.tr("Do you want to save before closing?"), QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if val == QMessageBox.No: neditable.nfile.close(force_close=True) elif val == QMessageBox.Yes: neditable.ignore_checkers = True self._main_container.save_file(neditable.editor) neditable.nfile.close() @pyqtSlot("PyQt_PyObject") def _recovery(self, neditable): print("lalalal") def _file_has_been_modified(self, neditable): index = self.bar.combo_files.findData(neditable) self.stacked.setCurrentIndex(index) self.bar.combo_files.setCurrentIndex(index) msg_box = QMessageBox(self) msg_box.setIcon(QMessageBox.Information) msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msg_box.setDefaultButton(QMessageBox.Yes) msg_box.setWindowTitle(translations.TR_FILE_HAS_BEEN_MODIFIED) msg_box.setText(translations.TR_FILE_MODIFIED_OUTSIDE % neditable.display_name) result = msg_box.exec_() if result == QMessageBox.Yes: neditable.reload_file() return def _run_file(self, path): self._main_container.run_file(path) def _add_to_project(self, path): self._main_container._add_to_project(path) def _show_file_in_explorer(self, path): '''Connected to ActionBar's showFileInExplorer(QString) signal, forwards the file path on to the main container.''' self._main_container._show_file_in_explorer(path) def set_current(self, neditable): if neditable: self.bar.set_current_file(neditable) def _set_current(self, neditable, index): self.stacked.setCurrentIndex(index) if neditable: self.bar.image_viewer_controls.setVisible(False) self.bar.code_navigator.setVisible(True) self.bar.symbols_combo.setVisible(True) self.bar.lbl_position.setVisible(True) editor = self.current_editor() self._update_cursor_position(ignore_sender=True) editor.setFocus() self._main_container.current_editor_changed(neditable.file_path) self._load_symbols(neditable) # self._show_file_in_explorer(neditable.file_path) neditable.update_checkers_display() else: self.bar.combo_files.setCurrentIndex(index) viewer_widget = self.stacked.widget(index) self._main_container.current_editor_changed( viewer_widget.image_filename) self.bar.image_viewer_controls.setVisible(True) self.bar.code_navigator.setVisible(False) self.bar.symbols_combo.setVisible(False) self.bar.lbl_position.setVisible(False) def widget(self, index): return self.stacked.widget(index) def count(self): """Return the number of editors opened.""" return self.stacked.count() def _update_cursor_position(self, line=0, col=0, ignore_sender=False): obj = self.sender() editor = self.current_editor() # Check if it's current to avoid signals from other splits. if ignore_sender or editor == obj: line += 1 self.bar.update_line_col(line, col) def _set_current_symbol(self, line, ignore_sender=False): obj = self.sender() editor = self.current_editor() # Check if it's current to avoid signals from other splits. if ignore_sender or editor == obj: index = bisect.bisect(self._symbols_index, line) if (index >= len(self._symbols_index) or self._symbols_index[index] > (line + 1)): index -= 1 self.bar.set_current_symbol(index) def _editor_modified(self, value, sender=None): if sender is None: sender = self.sender() neditable = sender.neditable if value: text = "\u2022 %s" % neditable.display_name self.bar.update_item_text(neditable, text) else: self.bar.update_item_text(neditable, neditable.display_name) def _go_to_symbol(self, index): line = self._symbols_index[index] editor = self.current_editor() editor.go_to_line(line, center=True) editor.setFocus() def _update_symbols(self, neditable): editor = self.current_editor() # Check if it's current to avoid signals from other splits. if editor == neditable.editor: self._load_symbols(neditable) def _update_combo_info(self, neditable): self.bar.update_item_text(neditable, neditable.display_name) self._main_container.current_editor_changed(neditable.file_path) def _load_symbols(self, neditable): # Get symbols handler by language symbols_handler = handlers.get_symbols_handler(neditable.language()) if symbols_handler is None: return source = neditable.editor.text source = source.encode(neditable.editor.encoding) symbols, symbols_simplified = symbols_handler.obtain_symbols( source, simple=True) self._symbols_index = sorted(symbols_simplified.keys()) symbols_simplified = sorted(list(symbols_simplified.items()), key=lambda x: x[0]) self.bar.add_symbols(symbols_simplified) line, _ = neditable.editor.cursor_position self._set_current_symbol(line, True) tree_symbols = IDE.get_service('symbols_explorer') if tree_symbols is not None: tree_symbols.update_symbols_tree(symbols, neditable.file_path) def _show_notification_icon(self, neditable): checkers = neditable.sorted_checkers icon = QIcon() for items in checkers: checker, color, _ = items if checker.checks: if isinstance(checker.checker_icon, int): icon = self.style().standardIcon(checker.checker_icon) elif isinstance(checker.checker_icon, str): icon = QIcon(checker.checker_icon) # FIXME: sucks else: icon = QIcon(checker.checker_icon) break self.bar.update_item_icon(neditable, icon) def show_menu_navigation(self): self.bar.code_navigator.show_menu_navigation() def closeEvent(self, event): self.about_to_close_combo_editor.emit() # self.emit(SIGNAL("aboutToCloseComboEditor()")) super(ComboEditor, self).closeEvent(event) def reject(self): if not self.__original: super(ComboEditor, self).reject()
class GameTab(QWidget): def __init__(self, core): super(GameTab, self).__init__() self.layout = QStackedLayout() self.default_widget = Games(core) self.default_widget.game_list.show_game_info.connect(self.show_info) self.default_widget.head_bar.import_game.clicked.connect(lambda: self.layout.setCurrentIndex(2)) self.layout.addWidget(self.default_widget) self.game_info = InfoTabs(core) self.game_info.info.update_list.connect(self.update_list) self.layout.addWidget(self.game_info) self.default_widget.head_bar.refresh_list.clicked.connect(self.update_list) self.import_widget = ImportWidget(core) self.layout.addWidget(self.import_widget) self.import_widget.back_button.clicked.connect(lambda: self.layout.setCurrentIndex(0)) self.import_widget.update_list.connect(self.update_list) self.setLayout(self.layout) def update_list(self): self.default_widget.game_list.update_list(not self.default_widget.head_bar.view.isChecked()) self.layout.setCurrentIndex(0) def show_info(self, app_name): self.game_info.update_game(app_name) self.game_info.setCurrentIndex(1) self.layout.setCurrentIndex(1)
def initUI(self): self.centralFrame = QFrame(self) self.centralFrame.setFrameShape(QFrame.NoFrame) self.centralFrame.setFrameShadow(QFrame.Raised) self.centralFrame.setContentsMargins(0, 0, 0, 0) self.centralFrame.setStyleSheet("background-color: rgb(27, 29, 35);" "border: none;") self.contentFrame = QFrame(self.centralFrame) self.contentFrame.setFrameShape(QFrame.NoFrame) self.contentFrame.setFrameShadow(QFrame.Raised) self.contentFrame.setContentsMargins(0, 0, 0, 0) self.contentFrame.setStyleSheet("border: none;") self.csvFrame = QFrame(self.contentFrame) self.csvFrame.setFrameShape(QFrame.NoFrame) self.csvFrame.setFrameShadow(QFrame.Raised) self.csvFrame.setContentsMargins(0, 0, 0, 0) self.measurementsFrame = QFrame(self.csvFrame) self.measurementsFrame.setFrameShape(QFrame.NoFrame) self.measurementsFrame.setFrameShadow(QFrame.Raised) self.measurementsFrame.setContentsMargins(0, 0, 0, 0) self.measurementsFrame.setStyleSheet("border: none;") self.measurementsPanel = MeasurementsPanel(self.measurementsFrame) self.activeMeasurements = self.measurementsPanel.activeMeasurements self.addBtn = self.measurementsPanel.addBtn self.removeBtn = self.measurementsPanel.removeBtn self.measurementsLayout = QVBoxLayout(self.measurementsFrame) self.measurementsLayout.addWidget(self.measurementsPanel) self.measurementsLayout.setContentsMargins(0, 0, 0, 0) self.configurationFrame = QFrame(self.csvFrame) self.configurationFrame.setFrameShape(QFrame.NoFrame) self.configurationFrame.setFrameShadow(QFrame.Raised) self.configurationFrame.setContentsMargins(0, 0, 0, 0) self.configurationFrame.setStyleSheet("background: rgb(15,15,15);" "border: 1px solid gray;" "border-radius: 5px;") self.saveFrame = QFrame(self.configurationFrame) self.saveFrame.setFrameShape(QFrame.NoFrame) self.saveFrame.setFrameShadow(QFrame.Raised) self.saveFrame.setContentsMargins(0, 0, 0, 0) self.saveFrame.setStyleSheet("border: none;") self.saveLabelFrame = QFrame(self.saveFrame) self.saveLabelFrame.setFrameShape(QFrame.NoFrame) self.saveLabelFrame.setFrameShadow(QFrame.Raised) self.saveLabelFrame.setContentsMargins(0, 0, 0, 0) self.saveLabel = Label(self.saveLabelFrame) self.saveLabel.setText("File: ") self.saveLabelLayout = QHBoxLayout(self.saveLabelFrame) self.saveLabelLayout.addWidget(self.saveLabel) self.saveLabelLayout.setContentsMargins(0, 0, 0, 0) self.saveFieldFrame = QFrame(self.saveFrame) self.saveFieldFrame.setFrameShape(QFrame.NoFrame) self.saveFieldFrame.setFrameShadow(QFrame.Raised) self.saveFieldFrame.setContentsMargins(0, 0, 0, 0) self.saveFieldFrame.setStyleSheet("border: none;") self.saveField = LineEdit(self.saveFieldFrame) self.saveFieldLayout = QHBoxLayout(self.saveFieldFrame) self.saveFieldLayout.addWidget(self.saveField) self.saveFieldLayout.setContentsMargins(0, 0, 0, 0) self.saveBtnFrame = QFrame(self.saveFrame) self.saveBtnFrame.setFrameShape(QFrame.NoFrame) self.saveBtnFrame.setFrameShadow(QFrame.Raised) self.saveBtnFrame.setContentsMargins(0, 0, 0, 0) self.saveBtnFrame.setStyleSheet("border: none;") self.saveBtn = PushButton(self.saveBtnFrame) self.saveBtn.setIcon(QIcon(resource_path("icons/ellipsis"))) self.saveBtn.setIconSize(QSize(20, 20)) self.saveBtnLayout = QHBoxLayout(self.saveBtnFrame) self.saveBtnLayout.addWidget(self.saveBtn) self.saveBtnLayout.setContentsMargins(0, 0, 0, 0) self.saveDialog = SaveDialog() self.saveLayout = QHBoxLayout(self.saveFrame) self.saveLayout.addWidget(self.saveLabelFrame) self.saveLayout.addWidget(self.saveFieldFrame) self.saveLayout.addWidget(self.saveBtnFrame) self.saveLayout.setContentsMargins(0, 0, 0, 0) self.controlsFrame = QFrame(self.configurationFrame) self.controlsFrame.setFrameShape(QFrame.NoFrame) self.controlsFrame.setFrameShadow(QFrame.Raised) self.controlsFrame.setContentsMargins(0, 0, 0, 0) self.controlsFrame.setStyleSheet("border: none;") self.runBtnsFrame = QFrame(self.controlsFrame) self.runBtnsFrame.setFrameShape(QFrame.NoFrame) self.runBtnsFrame.setFrameShadow(QFrame.Raised) self.runBtnsFrame.setContentsMargins(0, 0, 0, 0) self.runBtnsFrame.setStyleSheet("border: none;") self.startBtn = PushButton(self.runBtnsFrame) self.startBtn.setIcon(QIcon(resource_path("icons/cil-media-play"))) self.pauseBtn = PushButton(self.runBtnsFrame) self.pauseBtn.setIcon(QIcon(resource_path("icons/cil-media-pause"))) self.runBtnsLayout = QStackedLayout(self.runBtnsFrame) self.runBtnsLayout.addWidget(self.startBtn) self.runBtnsLayout.addWidget(self.pauseBtn) self.runBtnsLayout.setContentsMargins(0, 0, 0, 0) self.runBtnsLayout.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.runBtnsLayout.setCurrentIndex(self.START_BUTTON_INDEX) self.stopBtnFrame = QFrame(self.controlsFrame) self.stopBtnFrame.setFrameShape(QFrame.NoFrame) self.stopBtnFrame.setFrameShadow(QFrame.Raised) self.stopBtnFrame.setContentsMargins(0, 0, 0, 0) self.stopBtnFrame.setStyleSheet("border: none;") self.stopBtn = PushButton(self.stopBtnFrame) self.stopBtn.setIcon(QIcon(resource_path("icons/cil-media-stop"))) self.stopBtnLayout = QStackedLayout(self.stopBtnFrame) self.stopBtnLayout.addWidget(self.stopBtn) self.stopBtnLayout.setContentsMargins(0, 0, 0, 0) self.stopBtnLayout.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.controlsLayout = QHBoxLayout(self.controlsFrame) self.controlsLayout.addWidget(self.runBtnsFrame, alignment=Qt.AlignRight) self.controlsLayout.addWidget(self.stopBtnFrame, alignment=Qt.AlignRight) self.controlsLayout.setContentsMargins(0, 0, 0, 0) self.controlsLayout.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.configurationLayout = QHBoxLayout(self.configurationFrame) self.configurationLayout.addWidget(self.saveFrame, alignment=Qt.AlignLeft) self.configurationLayout.addWidget(self.controlsFrame, alignment=Qt.AlignRight) self.configurationLayout.setContentsMargins(10, 10, 10, 10) self.configurationLayout.setAlignment(Qt.AlignVCenter) self.csvLayout = QVBoxLayout(self.csvFrame) self.csvLayout.addWidget(self.measurementsFrame) self.csvLayout.addWidget(self.configurationFrame) self.csvLayout.setContentsMargins(10, 10, 10, 10) self.csvLayout.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.contentLayout = QVBoxLayout(self.contentFrame) self.contentLayout.addWidget(self.csvFrame, alignment=Qt.AlignTop) self.contentLayout.setContentsMargins(0, 0, 0, 0) self.contentLayout.setAlignment(Qt.AlignTop) self.centralLayout = QHBoxLayout(self.centralFrame) self.centralLayout.addWidget(self.contentFrame) self.centralLayout.setContentsMargins(0, 0, 0, 0) self.uiLayout = QHBoxLayout(self) self.uiLayout.addWidget(self.centralFrame) self.uiLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.uiLayout) self.setContentsMargins(0, 0, 0, 0)
class LoginWindow(QDialog): signal = pyqtSignal(bool) def __init__(self, core: LegendaryCore): super(LoginWindow, self).__init__() self.core = core self.success_code = False self.widget = QWidget() self.setGeometry(0, 0, 200, 300) self.welcome_layout = QVBoxLayout() self.title = QLabel( "<h2>Welcome to Rare the graphical interface for Legendary, an open source Epic Games alternative.</h2>\n<h3>Select one Option to Login</h3>" ) self.browser_btn = QPushButton("Use built in browser to login") self.browser_btn.clicked.connect(self.browser_login) self.browser_btn_normal = QPushButton("Use System browser") self.browser_btn_normal.clicked.connect(self.sys_browser_login) self.import_btn = QPushButton( "Import from existing Epic Games installation") self.import_btn.clicked.connect(self.import_login) self.text = QLabel("") self.exit_btn = QPushButton("Exit App") self.exit_btn.clicked.connect(self.exit_login) self.welcome_layout.addWidget(self.title) self.welcome_layout.addWidget(self.browser_btn) self.welcome_layout.addWidget(self.browser_btn_normal) self.welcome_layout.addWidget(self.import_btn) self.welcome_layout.addWidget(self.text) self.welcome_layout.addWidget(self.exit_btn) self.widget.setLayout(self.welcome_layout) self.browser = LoginBrowser() self.browser.loadFinished.connect(self.check_for_sid_page) self.import_widget = ImportWidget(self.core) self.import_widget.signal.connect(self.login_signal) self.sys_browser_widget = SystemBrowserWidget(core) self.sys_browser_widget.signal.connect(self.login_signal) self.layout = QStackedLayout() self.layout.addWidget(self.widget) self.layout.addWidget(self.browser) self.layout.addWidget(self.import_widget) self.layout.addWidget(self.sys_browser_widget) self.setLayout(self.layout) self.show() def login_signal(self, b: bool): if b: self.success() else: self.layout.setCurrentIndex(0) self.text.setText("<h4 style='color: red'>Login failed</h4>") def login(self): self.exec_() return self.success_code def success(self): self.success_code = True self.close() def retry(self): self.__init__(self.core) def exit_login(self): self.code = 1 self.close() def browser_login(self): self.setGeometry(0, 0, 800, 600) self.browser.load( QUrl( 'https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fredirect' )) self.layout.setCurrentIndex(1) def sys_browser_login(self): self.layout.setCurrentIndex(3) webbrowser.open( "https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fredirect" ) def import_login(self): self.layout.setCurrentIndex(2) def check_for_sid_page(self): if self.browser.url() == QUrl( "https://www.epicgames.com/id/api/redirect"): self.browser.page().toPlainText(self.browser_auth) def browser_auth(self, json): token = self.core.auth_sid(loads(json)["sid"]) if self.core.auth_code(token): logger.info( f"Successfully logged in as {self.core.lgd.userdata['displayName']}" ) self.success() else: self.layout.setCurrentIndex(0) logger.warning("Login failed") self.browser.close() self.text.setText("Login Failed")
class SideBarWidget(QFrame): """ """ def __init__(self, parent): super().__init__(parent) self.setAcceptDrops(True) self.parent_widget = parent self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) self.parent_widget self._widget_layout = QHBoxLayout(self) # widget stuff self._d_widget = QWidget(self) self._widget_layout.addWidget(self._d_widget) self.main_layout = QVBoxLayout(self._d_widget) self.main_layout.setSpacing(0) self.main_layout.setContentsMargins(0,0,0,0) self.arrow_handle = misc.ArrowHandle(self) self.arrow_handle.CLICKED.connect(self.slide) self._widget_layout.addWidget(self.arrow_handle) self.setContentsMargins(0,0,-self.arrow_handle.width(),0) self.show_all_galleries_btn = QPushButton("Show all galleries") self.show_all_galleries_btn.clicked.connect(lambda:parent.manga_list_view.sort_model.set_gallery_list()) self.show_all_galleries_btn.clicked.connect(self.show_all_galleries_btn.hide) self.show_all_galleries_btn.hide() self.main_layout.addWidget(self.show_all_galleries_btn) self.main_buttons_layout = QHBoxLayout() self.main_layout.addLayout(self.main_buttons_layout) # buttons bgroup = QButtonGroup(self) bgroup.setExclusive(True) self.lists_btn = QPushButton("Lists") self.lists_btn.setCheckable(True) bgroup.addButton(self.lists_btn) self.artist_btn = QPushButton("Artists") self.artist_btn.setCheckable(True) bgroup.addButton(self.artist_btn) self.ns_tags_btn = QPushButton("NS && Tags") self.ns_tags_btn.setCheckable(True) bgroup.addButton(self.ns_tags_btn) self.lists_btn.setChecked(True) self.main_buttons_layout.addWidget(self.lists_btn) self.main_buttons_layout.addWidget(self.artist_btn) self.main_buttons_layout.addWidget(self.ns_tags_btn) # buttons contents self.stacked_layout = QStackedLayout() self.main_layout.addLayout(self.stacked_layout) # lists gallery_lists_dummy = QWidget(self) self.lists = GalleryLists(self) create_new_list_btn = QPushButton() create_new_list_btn.setIcon(QIcon(app_constants.PLUS_PATH)) create_new_list_btn.setIconSize(QSize(15, 15)) create_new_list_btn.clicked.connect(lambda: self.lists.create_new_list()) create_new_list_btn.adjustSize() create_new_list_btn.setFixedSize(create_new_list_btn.width(), create_new_list_btn.height()) create_new_list_btn.setToolTip("Create a new list!") lists_l = QVBoxLayout(gallery_lists_dummy) lists_l.setContentsMargins(0,0,0,0) lists_l.setSpacing(0) lists_l.addWidget(self.lists) lists_l.addWidget(create_new_list_btn) lists_index = self.stacked_layout.addWidget(gallery_lists_dummy) self.lists.GALLERY_LIST_CLICKED.connect(parent.manga_list_view.sort_model.set_gallery_list) self.lists.GALLERY_LIST_CLICKED.connect(self.show_all_galleries_btn.show) self.lists.GALLERY_LIST_REMOVED.connect(self.show_all_galleries_btn.click) self.lists_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(lists_index)) self.show_all_galleries_btn.clicked.connect(self.lists.clearSelection) self.show_all_galleries_btn.clicked.connect(self.lists._reset_selected) # artists self.artists_list = GalleryArtistsList(parent.manga_list_view.gallery_model, self) self.artists_list.artist_clicked.connect(lambda a: parent.search('artist:"{}"'.format(a))) artists_list_index = self.stacked_layout.addWidget(self.artists_list) self.artist_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(artists_list_index)) #self.lists.GALLERY_LIST_CLICKED.connect(self.artists_list.set_current_glist) self.show_all_galleries_btn.clicked.connect(self.artists_list.clearSelection) #self.show_all_galleries_btn.clicked.connect(lambda:self.artists_list.set_current_glist()) # ns_tags self.tags_tree = TagsTreeView(self) self.tags_tree.TAG_SEARCH.connect(parent.search) self.tags_tree.NEW_LIST.connect(self.lists.create_new_list) self.tags_tree.setHeaderHidden(True) self.show_all_galleries_btn.clicked.connect(self.tags_tree.clearSelection) self.tags_layout = QVBoxLayout(self.tags_tree) ns_tags_index = self.stacked_layout.addWidget(self.tags_tree) self.ns_tags_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(ns_tags_index)) self.slide_animation = misc.create_animation(self, "maximumSize") self.slide_animation.stateChanged.connect(self._slide_hide) self.slide_animation.setEasingCurve(QEasingCurve.InOutQuad) def _slide_hide(self, state): size = self.sizeHint() if state == self.slide_animation.Stopped: if self.arrow_handle.current_arrow == self.arrow_handle.OUT: self._d_widget.hide() elif self.slide_animation.Running: if self.arrow_handle.current_arrow == self.arrow_handle.IN: if not self.parent_widget.current_manga_view.allow_sidebarwidget: self.arrow_handle.current_arrow = self.arrow_handle.OUT self.arrow_handle.update() else: self._d_widget.show() def slide(self, state): self.slide_animation.setEndValue(QSize(self.arrow_handle.width() * 2, self.height())) if state: self.slide_animation.setDirection(self.slide_animation.Forward) self.slide_animation.start() else: self.slide_animation.setDirection(self.slide_animation.Backward) self.slide_animation.start() def showEvent(self, event): super().showEvent(event) if not app_constants.SHOW_SIDEBAR_WIDGET: self.arrow_handle.click() def _init_size(self, event=None): h = self.parent_widget.height() self._max_width = 200 self.updateGeometry() self.setMaximumWidth(self._max_width) self.slide_animation.setStartValue(QSize(self._max_width, h)) def resizeEvent(self, event): self._init_size(event) return super().resizeEvent(event)
def setupUi(self, Form, username=None, userid=1, host='192.168.2.171', simid=None, reset=False): self.host = host self.username = username self.userid = userid self.simid = simid self.readonly = (simid is not None) self.showsettings = False self.currentindex = 0 self.usedefaultsettings = True self.db = connector.connect(host=self.host, user="******", passwd="Sequal1234", database="simulation", use_pure=True) self.db.autocommit = True self.simrunning = False # self.esrunning = False if not reset: self.thread = None self.thread = QThread() self.cppath = getcwd() + "\\cutplans\\" self.logpath = getcwd() + "\\logs\\" self.shifts = 2 self.simShift = 1 index = [] for i in range(1, self.shifts + 1): index.append(str(i)) index.append("Total") cols = [ "RunTime", "LogsCut", "Production", "LogVolume", "Recovery", "LogRate", "Uptime", "MSLDT", "BSLDT", "TSLDT", "SawdustVol" ] self.results = DataFrame(index=index, columns=cols) # self.OpenExtendSim() Form.setObjectName("Form") Form.resize(900, 750) Form.setMinimumSize(QSize(900, 750)) Form.setStyleSheet("background-color: rgb(255, 255, 255);\n" "color: rgb(0, 115, 119);") if Form.layout() is not None: QWidget().setLayout(Form.layout()) self.verticalLayout = QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") ss = \ """ QToolButton { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 115, 119, 255), stop:1 rgb(4, 147, 131)); color: white; border: None; border-radius: 2px; font: 11pt "Tahoma"; padding: 5px; margin-right: 20px; } """ self.detailsLayout = QHBoxLayout() self.closeButton = QToolButton(Form) self.closeButton.setObjectName("closeButton") self.closeButton.setStyleSheet(ss) self.closeButton.setCursor(QCursor(Qt.PointingHandCursor)) icon1 = QIcon("images/close.png") self.closeButton.setIcon(icon1) self.closeButton.setVisible(self.readonly) self.detailsLayout.addWidget(self.closeButton) self.nameLabel = QLabel(Form) self.nameLabel.setText("Name: ") self.nameLabel.setStyleSheet( "QLabel {" "background: none; font: 15pt \"Tahoma\";font-weight: bold;" "}") self.detailsLayout.addWidget(self.nameLabel) self.nameTextbox = QLineEdit(Form) self.nameTextbox.setText("Simulation") self.nameTextbox.setStyleSheet( "QLineEdit {\n" "background: none; font: 15pt \"Tahoma\";" "border: 1px solid rgb(0,115,119);\n" "}\n" "QLineEdit:disabled {border: none;}") self.detailsLayout.addWidget(self.nameTextbox) h = self.nameTextbox.size().height() self.closeButton.setMinimumSize(QSize(h, h)) self.closeButton.setIconSize(QSize(h - 10, h - 10)) self.PlayButton = QToolButton(Form) self.PlayButton.setObjectName("PlayButton") self.PlayButton.setStyleSheet(ss) self.PlayButton.setMinimumSize(QSize(h, h)) self.PlayButton.setCursor(QCursor(Qt.PointingHandCursor)) icon1 = QIcon("images/play.png") self.PlayButton.setIcon(icon1) self.PlayButton.setIconSize(QSize(h - 10, h - 10)) self.PlayButton.setVisible(False) self.detailsLayout.addWidget(self.PlayButton) hSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.detailsLayout.addItem(hSpacer) self.CreateNewButton = QToolButton(Form) self.CreateNewButton.setObjectName("CreateNewButton") self.CreateNewButton.setStyleSheet(ss) self.CreateNewButton.setMinimumSize(QSize(h, h)) self.CreateNewButton.setText("Create New") self.CreateNewButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) icon1 = QIcon("images/new.png") self.CreateNewButton.setIcon(icon1) self.CreateNewButton.setIconSize(QSize(h - 10, h - 10)) self.CreateNewButton.setCursor(QCursor(Qt.PointingHandCursor)) self.CreateNewButton.setVisible(False) self.detailsLayout.addWidget(self.CreateNewButton) self.SettingsButton = QToolButton(Form) self.SettingsButton.setObjectName("SettingsButton") self.SettingsButton.setStyleSheet(ss) self.SettingsButton.setMinimumSize(QSize(h, h)) self.SettingsButton.setCursor(QCursor(Qt.PointingHandCursor)) icon1 = QIcon("images/settings.png") self.SettingsButton.setIcon(icon1) self.SettingsButton.setIconSize(QSize(h - 10, h - 10)) self.detailsLayout.addWidget(self.SettingsButton) self.detailsLayout.setSpacing(5) self.verticalLayout.addLayout(self.detailsLayout) self.mainhorilayout = QHBoxLayout() self.ResultsArea = QScrollArea(Form) self.ResultsWidget = ResultsWidget() self.ResultsWidget.setupUi(self.ResultsArea) self.ResultsWidget.setObjectName("ResultsWidget") self.ResultsArea.setWidget(self.ResultsWidget) self.ResultsArea.setWidgetResizable(True) self.ResultsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.ResultsArea.setFrameShape(QFrame.NoFrame) self.mainhorilayout.addWidget(self.ResultsArea) self.StackedWidget = QWidget(Form) self.StackedLayout = QStackedLayout(self.StackedWidget) self.CutplanArea = QScrollArea(self.StackedWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.CutplanArea.sizePolicy().hasHeightForWidth()) self.CutplanArea.setSizePolicy(sizePolicy) self.CutplanArea.setMinimumSize(QSize(0, 250)) self.CutplanArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # self.CutplanArea.setSizeAdjustPolicy( # QAbstractScrollArea.AdjustToContents) self.CutplanArea.setWidgetResizable(True) self.CutplanArea.setFrameShape(QFrame.NoFrame) self.CutplanArea.setObjectName("CutplanArea") self.CPWidget = QWidget() self.Cutplans = CutplanWidget() self.Cutplans.setupUi(self.CPWidget) self.Cutplans.setObjectName("Cutplans") self.CutplanArea.setWidget(self.CPWidget) self.StackedLayout.addWidget(self.CutplanArea) self.StackedLayout.setSpacing(0) self.StackedLayout.setContentsMargins(0, 0, 0, 0) self.StackedWidget.setStyleSheet('background-color:rhba(0,0,0,0);') self.StackedWidget.setMaximumWidth(250) self.AddWindow = AddCutplanDialog(self.StackedWidget) self.AddWindow.setupUi(None, "support/cpquery.sql", self.Cutplans.host) self.StackedLayout.addWidget(self.AddWindow) self.SettingsWidget = QWidget(self.StackedWidget) self.SettingsUI = SettingsWindow(self.SettingsWidget) self.SettingsUI.setupUi(self.SettingsWidget) self.GetDefaultSettings() self.StackedLayout.addWidget(self.SettingsWidget) self.StackedLayout.setCurrentIndex(0) self.mainhorilayout.addWidget(self.StackedWidget) self.verticalLayout.addLayout(self.mainhorilayout) self.verticalLayout.setContentsMargins(50, 30, 50, 30) self.verticalLayout.setSpacing(50) self.timer = QTimer(self) self.timer.setInterval(100) self.timer.timeout.connect(self.UpdateGUI) self.PlayButton.clicked.connect(self.OnPlay) self.SettingsButton.clicked.connect(self.OnSettings) self.Cutplans.newcutplans.connect(self.ThreadSetup) self.Cutplans.AddButton.clicked.connect(self.AddClick) self.Cutplans.cploadfinish.connect(self.showPlayButton) self.AddWindow.buttonBox.rejected.connect(self.AddReject) self.AddWindow.buttonBox.accepted.connect(self.AddAccept) self.SettingsUI.buttonbox.accepted.connect(self.GetSettings) self.SettingsUI.buttonbox.rejected.connect(self.SendSettings) self.retranslateUi(Form) QMetaObject.connectSlotsByName(Form)
class AppWindow(QMainWindow): "The application's main window" def __init__(self): super().__init__() self.center = QWidget() self.display = QStackedLayout() self.center.setLayout(self.display) # init the manga view variables self.manga_display() # init the chapter view variables self.chapter_display() # init toolbar self.init_toolbar() # init status bar self.init_stat_bar() self.display.addWidget(self.manga_main) self.display.addWidget(self.chapter_main) self.setCentralWidget(self.center) self.setWindowTitle("Happypanda") self.resize(1029, 650) self.show() def init_stat_bar(self): self.status_bar = self.statusBar() self.status_bar.setMaximumHeight(20) self.status_bar.setSizeGripEnabled(False) self.stat_info = QLabel() self.stat_info.setIndent(5) self.sort_main = QAction("Asc", self) sort_menu = QMenu() self.sort_main.setMenu(sort_menu) s_by_title = QAction("Title", sort_menu) s_by_artist = QAction("Artist", sort_menu) sort_menu.addAction(s_by_title) sort_menu.addAction(s_by_artist) self.status_bar.addPermanentWidget(self.stat_info) #self.status_bar.addAction(self.sort_main) self.temp_msg = QLabel() self.temp_timer = QTimer() self.manga_list_view.series_model.ROWCOUNT_CHANGE.connect(self.stat_row_info) self.manga_list_view.series_model.STATUSBAR_MSG.connect(self.stat_temp_msg) def stat_temp_msg(self, msg): self.temp_timer.stop() self.temp_msg.setText(msg) self.status_bar.addWidget(self.temp_msg) self.temp_timer.timeout.connect(self.temp_msg.clear) self.temp_timer.setSingleShot(True) self.temp_timer.start(5000) def stat_row_info(self): r = self.manga_list_view.series_model.rowCount() t = len(self.manga_list_view.series_model._data) self.stat_info.setText("<b>Showing {} of {} </b>".format(r, t)) def manga_display(self): "initiates the manga view" self.manga_main = QWidget() self.manga_main.setContentsMargins(-10, -12, -10, -10) self.manga_view = QHBoxLayout() self.manga_main.setLayout(self.manga_view) manga_delegate = series.CustomDelegate() manga_delegate.BUTTON_CLICKED.connect(self.setCurrentIndex) self.manga_list_view = series.MangaView() self.manga_list_view.setItemDelegate(manga_delegate) self.manga_view.addWidget(self.manga_list_view) def favourite_display(self): "initiates favourite display" pass def chapter_display(self): "Initiates chapter view" self.chapter_main = QWidget() self.chapter_main.setObjectName("chapter_main") # to allow styling this object self.chapter_layout = QHBoxLayout() self.chapter_main.setLayout(self.chapter_layout) #self.chapter_info.setContentsMargins(-8,-7,-7,-7) #self.chapter_info.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.chapter_info_view = series.ChapterInfo() self.chapter_layout.addWidget(self.chapter_info_view) chapter_list_view = series.ChapterView() self.chapter_layout.addWidget(chapter_list_view) #self.chapter.setCollapsible(0, True) #self.chapter.setCollapsible(1, False) def init_toolbar(self): self.toolbar = QToolBar() self.toolbar.setFixedHeight(30) self.toolbar.setWindowTitle("Show") # text for the contextmenu #self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined? self.toolbar.setMovable(False) self.toolbar.setFloatable(False) #self.toolbar.setIconSize(QSize(20,20)) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) spacer_start = QWidget() # aligns the first actions properly spacer_start.setFixedSize(QSize(10, 1)) self.toolbar.addWidget(spacer_start) favourite_view_icon = QIcon(gui_constants.STAR_BTN_PATH) favourite_view_action = QAction(favourite_view_icon, "Favourite", self) #favourite_view_action.setText("Manga View") favourite_view_action.triggered.connect(lambda: self.setCurrentIndex(1)) #need lambda to pass extra args self.toolbar.addAction(favourite_view_action) catalog_view_icon = QIcon(gui_constants.HOME_BTN_PATH) catalog_view_action = QAction(catalog_view_icon, "Library", self) #catalog_view_action.setText("Catalog") catalog_view_action.triggered.connect(lambda: self.setCurrentIndex(0)) #need lambda to pass extra args self.toolbar.addAction(catalog_view_action) self.toolbar.addSeparator() series_icon = QIcon(gui_constants.PLUS_PATH) series_action = QAction(series_icon, "Add series...", self) series_action.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit) series_menu = QMenu() series_menu.addSeparator() populate_action = QAction("Populate from folder...", self) populate_action.triggered.connect(self.populate) series_menu.addAction(populate_action) series_action.setMenu(series_menu) self.toolbar.addAction(series_action) spacer_middle = QWidget() # aligns buttons to the right spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolbar.addWidget(spacer_middle) self.search_bar = QLineEdit() self.search_bar.setPlaceholderText("Search title, artist, genres") self.search_bar.setMaximumWidth(200) self.toolbar.addWidget(self.search_bar) self.toolbar.addSeparator() settings_icon = QIcon(gui_constants.SETTINGS_PATH) settings_action = QAction(settings_icon, "Set&tings", self) self.toolbar.addAction(settings_action) self.addToolBar(self.toolbar) spacer_end = QWidget() # aligns About action properly spacer_end.setFixedSize(QSize(10, 1)) self.toolbar.addWidget(spacer_end) def setCurrentIndex(self, number, index=None): """Changes the current display view. Params: number <- int (0 for manga view, 1 for chapter view Optional: index <- QModelIndex for chapter view Note: 0-based indexing """ if index is not None: self.chapter_info_view.display_manga(index) self.display.setCurrentIndex(number) else: self.display.setCurrentIndex(number) # TODO: Improve this so that it adds to the series dialog, # so user can edit data before inserting (make it a choice) def populate(self): "Populates the database with series from local drive'" msgbox = QMessageBox() msgbox.setText("<font color='red'><b>Use with care.</b></font> Choose a folder containing all your series'.") msgbox.setInformativeText("Oniichan, are you sure you want to do this?") msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) msgbox.setDefaultButton(QMessageBox.No) if msgbox.exec() == QMessageBox.Yes: path = QFileDialog.getExistingDirectory(None, "Choose a folder containing your series'") if len(path) is not 0: data_thread = QThread() loading_thread = QThread() loading = misc.Loading() if not loading.ON: misc.Loading.ON = True fetch_instance = fetch.Fetch() fetch_instance.series_path = path loading.show() def finished(status): if status: self.manga_list_view.series_model.populate_data() # TODO: make it spawn a dialog instead (from utils.py or misc.py) if loading.progress.maximum() == loading.progress.value(): misc.Loading.ON = False loading.hide() data_thread.quit else: loading.setText("<font color=red>An error occured. Try restarting..</font>") loading.progress.setStyleSheet("background-color:red") data_thread.quit def fetch_deleteLater(): try: fetch_instance.deleteLater except NameError: pass def thread_deleteLater(): #NOTE: Isn't this bad? data_thread.deleteLater def a_progress(prog): loading.progress.setValue(prog) loading.setText("Searching on local disk...\n(Will take a while on first time)") fetch_instance.moveToThread(data_thread) fetch_instance.DATA_COUNT.connect(loading.progress.setMaximum) fetch_instance.PROGRESS.connect(a_progress) data_thread.started.connect(fetch_instance.local) fetch_instance.FINISHED.connect(finished) fetch_instance.FINISHED.connect(fetch_deleteLater) fetch_instance.FINISHED.connect(thread_deleteLater) data_thread.start()
class CodeCompletionWidget(QFrame): def __init__(self, editor): super(CodeCompletionWidget, self).__init__( None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self._revision = 0 self._block = 0 self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = {'a': resources.IMAGES['attribute'], 'f': resources.IMAGES['function'], 'c': resources.IMAGES['class'], 'm': resources.IMAGES['module']} self.cc = code_completion.CodeCompletion() self._completion_results = {} self._prefix = '' self.setVisible(False) self.source = '' self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } self.desktop = QApplication.instance().desktop() self.completion_list.itemClicked['QListWidgetItem*'].connect(self.pre_key_insert_completion) self._editor.document().cursorPositionChanged['const QTextCursor &'].connect(self.update_metadata) def _select_next_row(self, move=1): new_row = self.completion_list.currentRow() + move if new_row < self.completion_list.count(): self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(0) return True def _select_previous_row(self, move=1): new_row = self.completion_list.currentRow() - move if new_row >= 0: self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow( self.completion_list.count() - move) return True def update_metadata(self, cursor): if settings.CODE_COMPLETION: if self._editor.document().revision() != self._revision and \ cursor.block().blockNumber() != self._block: source = self._editor.get_text() source = source.encode(self._editor.encoding) self.cc.analyze_file(self._editor.ID, source, self._editor.indent, self._editor.useTabs) self._revision = self._editor.document().revision() self._block = cursor.block().blockNumber() def insert_completion(self, insert, type_=ord('a')): if insert != self._prefix: closing = '' if type_ in (ord('f'), ord('c')): closing = '()' extra = len(self._prefix) - len(insert) insertion = '%s%s' % (insert[extra:], closing) self._editor.textCursor().insertText(insertion) self.hide_completer() def _get_geometry(self): cr = self._editor.cursorRect() desktop_geometry = self.desktop.availableGeometry(self._editor) point = self._editor.mapToGlobal(cr.topLeft()) cr.moveTopLeft(point) #Check new position according desktop geometry width = (self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10) height = 200 orientation = (point.y() + height) < desktop_geometry.height() if orientation: cr.moveTop(cr.bottom()) cr.setWidth(width) cr.setHeight(height) if not orientation: cr.moveBottom(cr.top()) xpos = desktop_geometry.width() - (point.x() + width) if xpos < 0: cr.moveLeft(cr.left() + xpos) return cr def complete(self, results): self.add_list_items(results) self.completion_list.setCurrentRow(0) cr = self._get_geometry() self.setGeometry(cr) self.completion_list.updateGeometries() self.show() def add_list_items(self, proposals): self.completion_list.clear() for p in proposals: self.completion_list.addItem( QListWidgetItem( QIcon( self._icons.get(p[0], resources.IMAGES['attribute'])), p[1], type=ord(p[0]))) def set_completion_prefix(self, prefix, valid=True): self._prefix = prefix proposals = [] proposals += [('m', item) for item in self._completion_results.get('modules', []) if item.startswith(prefix)] proposals += [('c', item) for item in self._completion_results.get('classes', []) if item.startswith(prefix)] proposals += [('a', item) for item in self._completion_results.get( 'attributes', []) if item.startswith(prefix)] proposals += [('f', item) for item in self._completion_results.get('functions', []) if item.startswith(prefix)] if proposals and valid: self.complete(proposals) else: self.hide_completer() def _invalid_completion_position(self): result = False cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) selection = cursor.selectedText()[:-1].split(' ') if len(selection) == 0 or selection[-1] == '' or \ selection[-1].isdigit(): result = True return result def fill_completer(self, force_completion=False): if not force_completion and (self._editor.cursor_inside_string() or self._editor.cursor_inside_comment() or self._invalid_completion_position()): return source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() results = self.cc.get_completion(source, offset) self._completion_results = results if force_completion: cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.KeepAnchor) prefix = cursor.selectedText() else: prefix = self._editor._text_under_cursor() self.set_completion_prefix(prefix) def hide_completer(self): self._prefix = '' self.hide() def pre_key_insert_completion(self): type_ = ord('a') current = self.completion_list.currentItem() insert = current.text() if not insert.endswith(')'): type_ = current.type() self.insert_completion(insert, type_) self.hide_completer() return True def process_pre_key_event(self, event): if not self.isVisible() or self._editor.lang != "python": return False skip = self._key_operations.get(event.key(), lambda: False)() self._key_operations.get(event.modifiers(), lambda: False)() if skip is None: skip = False return skip def process_post_key_event(self, event): if not settings.CODE_COMPLETION or self._editor.lang != "python": return if self.isVisible(): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() prefix, valid = self.cc.get_prefix(source, offset) self.set_completion_prefix(prefix, valid) self.completion_list.setCurrentRow(0) force_completion = (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier) if event.key() == Qt.Key_Period or force_completion: self.fill_completer(force_completion)
class SimulationPage(QWidget): def setupUi(self, Form, username=None, userid=1, host='192.168.2.171', simid=None, reset=False): self.host = host self.username = username self.userid = userid self.simid = simid self.readonly = (simid is not None) self.showsettings = False self.currentindex = 0 self.usedefaultsettings = True self.db = connector.connect(host=self.host, user="******", passwd="Sequal1234", database="simulation", use_pure=True) self.db.autocommit = True self.simrunning = False # self.esrunning = False if not reset: self.thread = None self.thread = QThread() self.cppath = getcwd() + "\\cutplans\\" self.logpath = getcwd() + "\\logs\\" self.shifts = 2 self.simShift = 1 index = [] for i in range(1, self.shifts + 1): index.append(str(i)) index.append("Total") cols = [ "RunTime", "LogsCut", "Production", "LogVolume", "Recovery", "LogRate", "Uptime", "MSLDT", "BSLDT", "TSLDT", "SawdustVol" ] self.results = DataFrame(index=index, columns=cols) # self.OpenExtendSim() Form.setObjectName("Form") Form.resize(900, 750) Form.setMinimumSize(QSize(900, 750)) Form.setStyleSheet("background-color: rgb(255, 255, 255);\n" "color: rgb(0, 115, 119);") if Form.layout() is not None: QWidget().setLayout(Form.layout()) self.verticalLayout = QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") ss = \ """ QToolButton { background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(0, 115, 119, 255), stop:1 rgb(4, 147, 131)); color: white; border: None; border-radius: 2px; font: 11pt "Tahoma"; padding: 5px; margin-right: 20px; } """ self.detailsLayout = QHBoxLayout() self.closeButton = QToolButton(Form) self.closeButton.setObjectName("closeButton") self.closeButton.setStyleSheet(ss) self.closeButton.setCursor(QCursor(Qt.PointingHandCursor)) icon1 = QIcon("images/close.png") self.closeButton.setIcon(icon1) self.closeButton.setVisible(self.readonly) self.detailsLayout.addWidget(self.closeButton) self.nameLabel = QLabel(Form) self.nameLabel.setText("Name: ") self.nameLabel.setStyleSheet( "QLabel {" "background: none; font: 15pt \"Tahoma\";font-weight: bold;" "}") self.detailsLayout.addWidget(self.nameLabel) self.nameTextbox = QLineEdit(Form) self.nameTextbox.setText("Simulation") self.nameTextbox.setStyleSheet( "QLineEdit {\n" "background: none; font: 15pt \"Tahoma\";" "border: 1px solid rgb(0,115,119);\n" "}\n" "QLineEdit:disabled {border: none;}") self.detailsLayout.addWidget(self.nameTextbox) h = self.nameTextbox.size().height() self.closeButton.setMinimumSize(QSize(h, h)) self.closeButton.setIconSize(QSize(h - 10, h - 10)) self.PlayButton = QToolButton(Form) self.PlayButton.setObjectName("PlayButton") self.PlayButton.setStyleSheet(ss) self.PlayButton.setMinimumSize(QSize(h, h)) self.PlayButton.setCursor(QCursor(Qt.PointingHandCursor)) icon1 = QIcon("images/play.png") self.PlayButton.setIcon(icon1) self.PlayButton.setIconSize(QSize(h - 10, h - 10)) self.PlayButton.setVisible(False) self.detailsLayout.addWidget(self.PlayButton) hSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.detailsLayout.addItem(hSpacer) self.CreateNewButton = QToolButton(Form) self.CreateNewButton.setObjectName("CreateNewButton") self.CreateNewButton.setStyleSheet(ss) self.CreateNewButton.setMinimumSize(QSize(h, h)) self.CreateNewButton.setText("Create New") self.CreateNewButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) icon1 = QIcon("images/new.png") self.CreateNewButton.setIcon(icon1) self.CreateNewButton.setIconSize(QSize(h - 10, h - 10)) self.CreateNewButton.setCursor(QCursor(Qt.PointingHandCursor)) self.CreateNewButton.setVisible(False) self.detailsLayout.addWidget(self.CreateNewButton) self.SettingsButton = QToolButton(Form) self.SettingsButton.setObjectName("SettingsButton") self.SettingsButton.setStyleSheet(ss) self.SettingsButton.setMinimumSize(QSize(h, h)) self.SettingsButton.setCursor(QCursor(Qt.PointingHandCursor)) icon1 = QIcon("images/settings.png") self.SettingsButton.setIcon(icon1) self.SettingsButton.setIconSize(QSize(h - 10, h - 10)) self.detailsLayout.addWidget(self.SettingsButton) self.detailsLayout.setSpacing(5) self.verticalLayout.addLayout(self.detailsLayout) self.mainhorilayout = QHBoxLayout() self.ResultsArea = QScrollArea(Form) self.ResultsWidget = ResultsWidget() self.ResultsWidget.setupUi(self.ResultsArea) self.ResultsWidget.setObjectName("ResultsWidget") self.ResultsArea.setWidget(self.ResultsWidget) self.ResultsArea.setWidgetResizable(True) self.ResultsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.ResultsArea.setFrameShape(QFrame.NoFrame) self.mainhorilayout.addWidget(self.ResultsArea) self.StackedWidget = QWidget(Form) self.StackedLayout = QStackedLayout(self.StackedWidget) self.CutplanArea = QScrollArea(self.StackedWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.CutplanArea.sizePolicy().hasHeightForWidth()) self.CutplanArea.setSizePolicy(sizePolicy) self.CutplanArea.setMinimumSize(QSize(0, 250)) self.CutplanArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # self.CutplanArea.setSizeAdjustPolicy( # QAbstractScrollArea.AdjustToContents) self.CutplanArea.setWidgetResizable(True) self.CutplanArea.setFrameShape(QFrame.NoFrame) self.CutplanArea.setObjectName("CutplanArea") self.CPWidget = QWidget() self.Cutplans = CutplanWidget() self.Cutplans.setupUi(self.CPWidget) self.Cutplans.setObjectName("Cutplans") self.CutplanArea.setWidget(self.CPWidget) self.StackedLayout.addWidget(self.CutplanArea) self.StackedLayout.setSpacing(0) self.StackedLayout.setContentsMargins(0, 0, 0, 0) self.StackedWidget.setStyleSheet('background-color:rhba(0,0,0,0);') self.StackedWidget.setMaximumWidth(250) self.AddWindow = AddCutplanDialog(self.StackedWidget) self.AddWindow.setupUi(None, "support/cpquery.sql", self.Cutplans.host) self.StackedLayout.addWidget(self.AddWindow) self.SettingsWidget = QWidget(self.StackedWidget) self.SettingsUI = SettingsWindow(self.SettingsWidget) self.SettingsUI.setupUi(self.SettingsWidget) self.GetDefaultSettings() self.StackedLayout.addWidget(self.SettingsWidget) self.StackedLayout.setCurrentIndex(0) self.mainhorilayout.addWidget(self.StackedWidget) self.verticalLayout.addLayout(self.mainhorilayout) self.verticalLayout.setContentsMargins(50, 30, 50, 30) self.verticalLayout.setSpacing(50) self.timer = QTimer(self) self.timer.setInterval(100) self.timer.timeout.connect(self.UpdateGUI) self.PlayButton.clicked.connect(self.OnPlay) self.SettingsButton.clicked.connect(self.OnSettings) self.Cutplans.newcutplans.connect(self.ThreadSetup) self.Cutplans.AddButton.clicked.connect(self.AddClick) self.Cutplans.cploadfinish.connect(self.showPlayButton) self.AddWindow.buttonBox.rejected.connect(self.AddReject) self.AddWindow.buttonBox.accepted.connect(self.AddAccept) self.SettingsUI.buttonbox.accepted.connect(self.GetSettings) self.SettingsUI.buttonbox.rejected.connect(self.SendSettings) self.retranslateUi(Form) QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) def ThreadSetup(self, show): self.PlayButton.setVisible(False) self.cpid = 0 self.cpfinish = False for i in range(self.results.shape[0]): for j in range(self.results.shape[1]): self.results.iloc[i, j] = 0 def showPlayButton(self): if not self.readonly: self.PlayButton.setVisible(True) def AddClick(self): self.Cutplans.onClick2() if self.Cutplans.addData is not None: self.AddWindow.addData = self.Cutplans.addData else: self.AddWindow.addData = DataFrame( columns=['ID', 'Log Count', 'Description']) self.AddWindow.onDateChange() self.AddWindow.RTVSetUp() self.StackedLayout.setCurrentIndex(1) self.currentindex = 1 def AddReject(self): self.StackedLayout.setCurrentIndex(0) self.currentindex = 0 def AddAccept(self): self.Cutplans.addData = self.AddWindow.addData self.StackedLayout.setCurrentIndex(0) self.currentindex = 0 self.Cutplans.AddCP() def OnPlay(self): self.PlayButton.setVisible(False) self.Cutplans.AddButton.setVisible(False) self.nameTextbox.setDisabled(True) self.simrunning = True self.cpfinish = False self.SendData() self.timer.start() # if self.esrunning: # # self.esa.RunSim() # self.timer.start() def SendData(self): try: cursor = self.db.cursor() except connector.Error: self.db = connector.connect(host=self.host, user="******", passwd="Sequal1234", database="simulation", use_pure=True) self.db.autocommit = True cursor = self.db.cursor() f = open('support\\initResults.sql', 'r') query = f.read() cursor.execute(query) # Simulations query query = "INSERT INTO simulations (Name, UserID) VALUES " \ "(\'" + self.nameTextbox.text() + "\', " + str(self.userid) + ");" cursor.execute(query) cursor.execute("SELECT LAST_INSERT_ID();") (sid, ) = cursor.fetchone() self.simid = sid # check for downtime setting if sum(self.downtime_setting) == 0: # all downtime off dt = 0 elif sum(self.downtime_setting) == len(self.downtime_setting): # all downtime on dt = 1 else: # custom downtime so insert downtime into downtimesettings dt = 2 temp = self.SettingsUI.downtimeCBtexts.copy() temp.insert(0, 'SimID') tstr = str(temp).replace('\'', '').replace('[', '(').replace(']', ')') query = "INSERT INTO DowntimeSettings " + tstr temp = self.downtime_setting.copy() temp.insert(0, self.simid) tstr = str(temp).replace('[', '(').replace(']', ')') query = query + " VALUES " + tstr + ";" cursor.execute(query) # check for cutback default setting defcb = self.SettingsUI.defaultcutbacks cbtext = self.SettingsUI.cutbackCBtexts cb = True for tstr in defcb: if not self.cutback_setting[cbtext.index(tstr)]: cb = False if cb and sum(self.cutback_setting) == len(defcb): cb = 1 else: cb = 0 temp = cbtext.copy() temp.insert(0, 'SimID') tstr = str(temp).replace('\'', '`').replace('[', '(').replace(']', ')') query = "INSERT INTO CutbackSettings " + tstr temp = self.cutback_setting.copy() temp.insert(0, self.simid) tstr = str(temp).replace('[', '(').replace(']', ')') query = query + " VALUES " + tstr + ";" cursor.execute(query) # SimHistory Query f = open('support\\simHistQuery.sql', 'r') sqltext = f.read() query = sqltext.replace('@SimID', str(self.simid)) query = query.replace('@Name', str(self.nameTextbox.text())) query = query.replace('@UserID', str(self.userid)) query = query.replace('@LogGap', str(self.loggap_setting)) query = query.replace('@Downtime', str(dt)) query = query.replace('@NumBins', str(self.numbins_setting)) query = query.replace('@LineSpeed', str(self.linespeed_setting)) query = query.replace('@Cutbacks', str(cb)) cursor.execute(query) # Cutplans Query f = open('support\\simQuery.sql', 'r') sqltext = f.read() for i in range(self.Cutplans.addData.shape[0]): sqltext_full = sqltext.replace("@SimID", str(sid)) sqltext_full = sqltext_full.replace( "@CutplanID", str(self.Cutplans.addData.ID[i])) sqltext_full = sqltext_full.replace( "@Description", str(self.Cutplans.addData.Description[i])) sqltext_full = sqltext_full.replace( "@NumLogs", str(self.Cutplans.addData['Log Count'][i])) cursor.execute(sqltext_full) def GetDefaultSettings(self): self.loggap_setting = self.SettingsUI.default[0] self.downtime_setting = [] for cb in self.SettingsUI.downtimeCBs: self.downtime_setting.append(cb.isChecked()) self.numbins_setting = self.SettingsUI.default[2] self.linespeed_setting = self.SettingsUI.default[3] self.cutback_setting = [] for cb in self.SettingsUI.cutbackCBs: self.cutback_setting.append(cb.isChecked()) def GetSettings(self): s = self.SettingsUI if s.loggapAuto.isChecked(): self.loggap_setting = -1 else: self.loggap_setting = s.loggapTB.value() self.downtime_setting = [] for cb in s.downtimeCBs: self.downtime_setting.append(cb.isChecked()) self.numbins_setting = s.numbinsTB.value() if s.highspeedRB.isChecked(): self.linespeed_setting = 55.0 elif s.lowspeedRB.isChecked(): self.linespeed_setting = 35.0 elif s.autospeedRB.isChecked(): self.linespeed_setting = -1.0 else: self.linespeed_setting = s.customspeedTB.value() self.cutback_setting = [] for cb in s.cutbackCBs: self.cutback_setting.append(cb.isChecked()) self.usedefaultsettings = not s.resetbutton.isVisible() self.showsettings = False speed = int(self.linespeed_setting) if speed == -1: speed = 55 self.Cutplans.speedsetting = speed self.Cutplans.onClick2() self.Cutplans.AddCP() self.StackedLayout.setCurrentIndex(self.currentindex) def SendSettings(self): s = self.SettingsUI if self.loggap_setting == -1: s.loggapAuto.setChecked(True) else: s.loggapAuto.setChecked(False) s.loggapTB.setValue(self.loggap_setting) for i in range(len(s.downtimeCBs)): s.downtimeCBs[i].setChecked(self.downtime_setting[i]) s.numbinsTB.setValue(self.numbins_setting) if self.linespeed_setting == 55.0: s.highspeedRB.setChecked(True) elif self.linespeed_setting == 35.0: s.lowspeedRB.setChecked(True) elif self.linespeed_setting == -1.0: s.autospeedRB.setChecked(True) else: s.customspeedRB.setChecked(True) s.customspeedTB.setValue(self.linespeed_setting) for i in range(len(s.cutbackCBs)): s.cutbackCBs[i].setChecked(self.cutback_setting[i]) if self.usedefaultsettings: s.resetbutton.setVisible(False) self.showsettings = False self.StackedLayout.setCurrentIndex(self.currentindex) def OnSettings(self): if not self.showsettings: self.SettingsUI.resetbutton.setVisible(not self.usedefaultsettings) self.StackedLayout.setCurrentIndex(2) self.showsettings = True def UpdateGUI(self): if not self.cpfinish: f = open('support\\cpProgress.sql', 'r') sqltext = f.read().replace('@SimID', str(self.simid)) try: cursor = self.db.cursor() except connector.Error: self.db = connector.connect(host=self.host, user="******", passwd="Sequal1234", database="simulation", use_pure=True) self.db.autocommit = True cursor = self.db.cursor() complete = 0 for i in range(self.Cutplans.addData.shape[0]): query = sqltext.replace('@CPID', str(self.Cutplans.addData.ID[i])) cursor.execute(query) (v, ) = cursor.fetchone() self.Cutplans.CPProgress[i].setValue(v) if v >= 100: complete += 1 if complete == self.Cutplans.addData.shape[0]: self.cpfinish = True else: f = open('support\\getResults.sql', 'r') sqltext = f.read() self.results = read_sql(sqltext, self.db) self.ResultsWidget.updateResults(self.results) if self.results['RunTime'][2] >= 17.66: self.timer.stop() self.simrunning = False self.setupPostSimulation() def setupPostSimulation(self): self.Cutplans.AddButton.setVisible(False) self.nameTextbox.setDisabled(True) self.CreateNewButton.setVisible(True) ss = " background-color: ;\n" \ " background-color: qlineargradient(spread:pad, x1:0, y1:0, " \ "x2:1, y2:1, stop:0 rgba(0, 115, 119, 255), stop:1 rgb(4, 147, " \ "131));\n" \ " color: white;\n" \ " height: 25px;\n" \ " border: None;\n" \ " border-radius: 2px;\n" \ " \n" \ " font: 11pt \"Tahoma\";\n" \ " width: 70px;" # SETTINGS READ ONLY self.SettingsUI.buttonbox.setStandardButtons(QDialogButtonBox.Cancel) for w in self.SettingsUI.buttonbox.children(): if w.metaObject().className() == "QPushButton": w.setCursor(QCursor(Qt.PointingHandCursor)) w.setStyleSheet(ss) self.SettingsUI.setupReadOnly() self.CheckCPErrors() def setupReadOnly(self, loadcp=True): self.closeButton.setVisible(True) self.Cutplans.AddButton.setVisible(False) qry = "SELECT * FROM simulation.fullresults Where SimID = " + str( self.simid) data = read_sql(qry, self.db) self.nameTextbox.setText(data["SimName"][0]) self.nameTextbox.setDisabled(True) qry = "SELECT CutplanID as ID, NumLogs as \"Log Count\" From " + \ "cutplans WHERE SimID = " + str(self.simid) self.results = data.iloc[:, 3:15].copy() self.results.columns = [ 'RunTime', 'LogsCut', 'Production', 'LogVolume', 'Recovery', 'LogRate', 'Uptime', 'MSLDT', 'BSLDT', 'TSLDT', 'Sawdust', 'Shift' ] self.results.loc[self.results.index[0], 'Shift'] = self.results.shape[0] self.results = self.results.sort_values(by=['Shift']) self.results['Sawdust'] = self.results['Sawdust'] / \ self.results['LogVolume'] self.ResultsWidget.updateResults(self.results) if loadcp: cpdata = read_sql(qry, self.db) self.Cutplans.AddCP(addData=cpdata, errors=self.CheckCPErrors()) qry = "SELECT * From SimHistory Where SimID = " + str(self.simid) + ";" settings = read_sql(qry, self.db) self.loggap_setting = settings.LogGap[0] dt = settings.Downtime[0] if dt == 0: self.downtime_setting = [] for i in range(len(self.SettingsUI.downtimeCBs)): self.downtime_setting.append(False) elif dt == 1: self.downtime_setting = [] for i in range(len(self.SettingsUI.downtimeCBs)): self.downtime_setting.append(True) else: qry = "SELECT * FROM DowntimeSettings Where SimID = " + str( self.simid) + ";" dt = read_sql(qry, self.db) for i in range(len(self.SettingsUI.downtimeCBs)): x = (dt.iloc[0, i + 1] == 1) self.SettingsUI.downtimeCBs[i].setChecked(x) self.SettingsUI.numbinsTB.setValue(settings.NumBins[0]) if settings.LineSpeed[0] == 55.0: self.SettingsUI.highspeedRB.setChecked(True) elif settings.LineSpeed[0] == 35.0: self.SettingsUI.lowspeedRB.setChecked(True) elif settings.LineSpeed[0] == -1.0: self.SettingsUI.autospeedRB.setChecked(True) else: self.SettingsUI.customspeedRB.setChecked(True) self.SettingsUI.customspeedTB.setValue(settings.LineSpeed[0]) if settings.Downtime[0] == 0: qry = "SELECT * FROM CutbackSettings Where SimID = " + str( self.simid) + ";" cb = read_sql(qry, self.db) for i in range(len(self.SettingsUI.downtimeCBs)): x = (cb.iloc[0, i + 1] == 1) self.SettingsUI.downtimeCBs[i].setChecked(x) self.SettingsUI.buttonbox.setStandardButtons(QDialogButtonBox.Cancel) for w in self.SettingsUI.buttonbox.children(): if w.metaObject().className() == "QPushButton": w.setCursor(QCursor(Qt.PointingHandCursor)) self.SettingsUI.setupReadOnly() def CheckCPErrors(self): with open('support\\cpErrors.sql', 'r') as f: query = f.read().replace('@SimID', str(self.simid)) cperrors = read_sql(query, self.db) return cperrors
class history_search(QWidget): def __init__(self): super().__init__() self.db = None self.init() def init(self): self.menus = QComboBox() self.menus.setView(QListView()) self.menus.setStyleSheet( "QComboBox QAbstractItemView::item {min-height: 25px;}") self.menus.addItem("日期") self.menus.addItem("标题") self.menus.addItem("内容") self.menus.setFixedSize(100, 40) self.select_mode = QButtonGroup() self.select_mode_strict = QRadioButton('严格搜索') self.select_mode_blurry = QRadioButton('模糊搜索') self.select_mode.addButton(self.select_mode_strict) self.select_mode.addButton(self.select_mode_blurry) self.select_mode_strict.setChecked(True) self.input_search = QLineEdit() self.btn_search_keyword = QPushButton("搜索") self.btn_clear_all = QPushButton("Clear") self.btn_clear_all.clicked.connect(self.clear_all) self.btn_search_keyword.clicked.connect(self.load_keyword_info) self.infos = QFrame() self.qsl = QStackedLayout(self.infos) self.search_result = history_search_result() self.qsl.addWidget(self.search_result) menubar = QHBoxLayout() menubar.addWidget(self.menus) menubar.addWidget(self.input_search) menubar.addWidget(self.btn_search_keyword) menubar.addWidget(self.btn_clear_all) menubar.addWidget(self.select_mode_strict) menubar.addWidget(self.select_mode_blurry) layout = QVBoxLayout() layout.addLayout(menubar) layout.addWidget(self.infos) self.setLayout(layout) def set_db(self, db): self.db = db self.search_result.set_db(db) def load_keyword_info(self): index = self.get_index() if index == -1: return keyword = self.input_search.text() if self.select_mode_strict.isChecked(): mode = 1 print('搜索模式: 严格搜索') else: mode = 0 print('搜索模式: 模糊搜索') self.search_result.show_data(index, keyword, mode) def get_index(self): index = self.menus.currentIndex() if (index == 0): print('搜索条件: 日期') elif index == 1: print('搜索条件: 标题') elif index == 2: print('搜索条件: 正文') else: index = -1 print('错误的索引:', index) return index def clear_all(self): self.search_result.clear_data()
def __init__(self): """View initializer.""" super().__init__() self.number_point = 1 self.function_type = 0 self.firstpointvalue = "" self.secondpointvalue = "" self.thirdpointvalue = "" self.fourthpointvalue = "" self.firstendpointvalue = "" self.secondendpointvalue = "" self.thirdendpointvalue = "" self.fourthendpointvalue = "" self.first_link = 1 self.second_link = 2 self.third_link = 3 self.fourth_link = 4 # Set some main window's properties self.setWindowTitle('Function Image') self.setWindowIcon(QtGui.QIcon('Draw.ico')) self.setFixedSize(900, 600) # Set the central widget self._centralWidget = QWidget(self) self.setCentralWidget(self._centralWidget) #Set the Grid Layout self.layout = QGridLayout() #Set the First Part Outer Layout self.sublayout_1 = QVBoxLayout() self.sublayout_1.setContentsMargins(10, 0, 50, 0) self.basic_groupbox = QGroupBox("Basic Configuration") self.basic_groupbox.setContentsMargins(40, 0, 0, 0) self.basic_groupbox.setLayout(self.sublayout_1) #Set the The First Part of Inner Layout self.leftlayout_1 = QHBoxLayout() self.function_type_group_box = QGroupBox("Function Type :") self.function_type_group_box.setFixedHeight(60) self.function_type_group_box.setContentsMargins(100, 0, 0, 0) self.function_type_group_box.setLayout(self.leftlayout_1) self.type_radiobutton_1 = QRadioButton("A/B") self.type_radiobutton_1.setChecked(True) self.type_radiobutton_2 = QRadioButton("x - f(x)") self.type_radiobutton_3 = QRadioButton("None") #Place the Radiobutton self.leftlayout_1.addWidget(self.type_radiobutton_1) self.leftlayout_1.addWidget(self.type_radiobutton_2) self.leftlayout_1.addWidget(self.type_radiobutton_3) #Set the Second part of Inner Layout self.leftlayout_2 = QFormLayout() self.leftlayout_2.setHorizontalSpacing(20) self.function_info_group_box = QGroupBox("Function Info :") self.function_info_group_box.setFixedHeight(60) self.function_info_group_box.setContentsMargins(100, 10, 0, 0) self.function_info_group_box.setLayout(self.leftlayout_2) #Set and Place the Component for the form layout self.function_name = QLineEdit() self.function_name.setFixedWidth(200) self.leftlayout_2.addRow("Function Name:", self.function_name) #Set the Third Part of Inner Layout self.leftlayout_3 = QHBoxLayout() self.point_number = QGroupBox("Point Number :") self.point_number.setFixedHeight(60) self.point_number.setContentsMargins(100, 10, 0, 0) self.point_number.setLayout(self.leftlayout_3) self.number_1 = QRadioButton("1") self.number_2 = QRadioButton("2") self.number_3 = QRadioButton("3") self.number_4 = QRadioButton("4") self.number_1.setChecked(True) #Place the Radiobutton self.leftlayout_3.addWidget(self.number_1) self.leftlayout_3.addWidget(self.number_2) self.leftlayout_3.addWidget(self.number_3) self.leftlayout_3.addWidget(self.number_4) #Place all the Inner Layout for First Part of Outer Layout self.sublayout_1.addWidget(self.function_type_group_box) self.sublayout_1.addWidget(self.function_info_group_box) self.sublayout_1.addWidget(self.point_number) #Set the Second Part Outer Layout self.sublayout_2 = QHBoxLayout() self.advanced_groupbox = QGroupBox("Advanced Configuration") self.advanced_groupbox.setContentsMargins(40, 0, 0, 0) self.advanced_groupbox.setLayout(self.sublayout_2) #Create the stacked Layout self.stackedLayout = QStackedLayout() #Place the Page to Stacked Layout self.stackedLayout.addWidget(self.Page1()) self.stackedLayout.addWidget(self.Page2()) self.stackedLayout.addWidget(self.Page3()) self.stackedLayout.addWidget(self.Page4()) #Place the Stacked Layout self.sublayout_2.addLayout(self.stackedLayout) #Set the Third Part Outer Layout self.sublayout_3 = QVBoxLayout() self.preview_button = QPushButton('Preview') self.sublayout_3.addWidget(self.preview_button) #Place all the Outer Layout self.layout.addWidget(self.basic_groupbox, 0, 0, 3, 2) self.layout.addWidget(self.advanced_groupbox, 0, 2, 2, 1) self.layout.addLayout(self.sublayout_3, 2, 2, 1, 1) #Place the Grid layout to Central Widget self._centralWidget.setLayout(self.layout) #Connect all Function self.number_1.clicked.connect(lambda: self.switchPage(self.number_1)) self.number_2.clicked.connect(lambda: self.switchPage(self.number_2)) self.number_3.clicked.connect(lambda: self.switchPage(self.number_3)) self.number_4.clicked.connect(lambda: self.switchPage(self.number_4)) self.preview_button.clicked.connect(self.CreateImage) self.type_radiobutton_1.clicked.connect(self.setFunctionType) self.type_radiobutton_2.clicked.connect(self.setFunctionType) self.type_radiobutton_3.clicked.connect(self.setFunctionType) #Set the Status Bar status = QStatusBar() status.showMessage("Welcome to the Creating function image tool") self.setStatusBar(status)
def __init__(self, parent): super().__init__(parent) self.setAcceptDrops(True) self.parent_widget = parent self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self._widget_layout = QHBoxLayout(self) # widget stuff self._d_widget = QWidget(self) self._d_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self._widget_layout.addWidget(self._d_widget) self.main_layout = QVBoxLayout(self._d_widget) self.main_layout.setSpacing(0) self.main_layout.setContentsMargins(0,0,0,0) self.arrow_handle = misc.ArrowHandle(self) self.arrow_handle.CLICKED.connect(self.slide) self._widget_layout.addWidget(self.arrow_handle) self.setContentsMargins(0,0,-self.arrow_handle.width(),0) self.show_all_galleries_btn = QPushButton("Show all galleries") self.show_all_galleries_btn.clicked.connect(lambda:parent.manga_list_view.sort_model.set_gallery_list()) self.show_all_galleries_btn.clicked.connect(self.show_all_galleries_btn.hide) self.show_all_galleries_btn.setIcon(app_constants.CROSS_ICON_WH) self.show_all_galleries_btn.hide() self.main_layout.addWidget(self.show_all_galleries_btn) self.main_buttons_layout = QHBoxLayout() self.main_layout.addLayout(self.main_buttons_layout) # buttons bgroup = QButtonGroup(self) bgroup.setExclusive(True) self.lists_btn = QPushButton("") self.lists_btn.setIcon(app_constants.G_LISTS_ICON_WH) self.lists_btn.setCheckable(True) bgroup.addButton(self.lists_btn) self.artist_btn = QPushButton("") self.artist_btn.setIcon(app_constants.ARTISTS_ICON) self.artist_btn.setCheckable(True) bgroup.addButton(self.artist_btn) self.ns_tags_btn = QPushButton("") self.ns_tags_btn.setIcon(app_constants.NSTAGS_ICON) self.ns_tags_btn.setCheckable(True) bgroup.addButton(self.ns_tags_btn) self.lists_btn.setChecked(True) self.main_buttons_layout.addWidget(self.lists_btn) self.main_buttons_layout.addWidget(self.artist_btn) self.main_buttons_layout.addWidget(self.ns_tags_btn) # buttons contents self.stacked_layout = QStackedLayout() self.main_layout.addLayout(self.stacked_layout) # lists gallery_lists_dummy = QWidget(self) self.lists = GalleryLists(self) create_new_list_btn = QPushButton() create_new_list_btn.setIcon(QIcon(app_constants.PLUS_ICON)) create_new_list_btn.setIconSize(QSize(15, 15)) create_new_list_btn.clicked.connect(lambda: self.lists.create_new_list()) create_new_list_btn.adjustSize() create_new_list_btn.setFixedSize(create_new_list_btn.width(), create_new_list_btn.height()) create_new_list_btn.setToolTip("Create a new list!") lists_l = QVBoxLayout(gallery_lists_dummy) lists_l.setContentsMargins(0,0,0,0) lists_l.setSpacing(0) lists_l.addWidget(self.lists) lists_l.addWidget(create_new_list_btn) lists_index = self.stacked_layout.addWidget(gallery_lists_dummy) self.lists.GALLERY_LIST_CLICKED.connect(parent.manga_list_view.sort_model.set_gallery_list) self.lists.GALLERY_LIST_CLICKED.connect(self.show_all_galleries_btn.show) self.lists.GALLERY_LIST_REMOVED.connect(self.show_all_galleries_btn.click) self.lists_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(lists_index)) self.show_all_galleries_btn.clicked.connect(self.lists.clearSelection) self.show_all_galleries_btn.clicked.connect(self.lists._reset_selected) # artists self.artists_list = GalleryArtistsList(parent.manga_list_view.gallery_model, self) self.artists_list.artist_clicked.connect(lambda a: parent.search('artist:"{}"'.format(a))) artists_list_index = self.stacked_layout.addWidget(self.artists_list) self.artist_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(artists_list_index)) #self.lists.GALLERY_LIST_CLICKED.connect(self.artists_list.set_current_glist) self.show_all_galleries_btn.clicked.connect(self.artists_list.clearSelection) #self.show_all_galleries_btn.clicked.connect(lambda:self.artists_list.set_current_glist()) # ns_tags self.tags_tree = TagsTreeView(self) self.tags_tree.TAG_SEARCH.connect(parent.search) self.tags_tree.NEW_LIST.connect(self.lists.create_new_list) self.tags_tree.setHeaderHidden(True) self.show_all_galleries_btn.clicked.connect(self.tags_tree.clearSelection) self.tags_layout = QVBoxLayout(self.tags_tree) ns_tags_index = self.stacked_layout.addWidget(self.tags_tree) self.ns_tags_btn.clicked.connect(lambda:self.stacked_layout.setCurrentIndex(ns_tags_index)) self.slide_animation = misc.create_animation(self, "maximumSize") self.slide_animation.stateChanged.connect(self._slide_hide) self.slide_animation.setEasingCurve(QEasingCurve.InOutQuad)
def CreateApp(self): self.layout = QVBoxLayout() self.layout.setSpacing(0) self.setContentsMargins(0, 0, 0, 0) # Create Tabs self.tabbar = QTabBar(movable=True, tabsClosable=True) self.tabbar.tabCloseRequested.connect(self.CloseTab) self.tabbar.tabBarClicked.connect(self.SwitchTab) self.tabbar.setCurrentIndex(0) self.tabbar.setDrawBase(False) self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self) self.shortcutNewTab.activated.connect(self.AddTab) self.shortcutReload = QShortcut(QKeySequence("Ctrl+R"), self) self.shortcutReload.activated.connect(self.ReloadPage) # self.shortcutCloseTab = QShortcut(QKeySequence("Ctrl+W"), self) # self.shortcutCloseTab.activated.connect(self.CloseTab) # Keep track of tabs self.tabCount = 0 self.tabs = [] # Create AddressBar self.Toolbar = QWidget() self.ToolbarLayout = QHBoxLayout() self.addressbar = AddressBar() self.addressbar.returnPressed.connect(self.BrowseTo) # New tab button self.AddTabButton = QPushButton("+") self.AddTabButton.clicked.connect(self.AddTab) # Set Toolbar Buttons self.BackButton = QPushButton("<") self.BackButton.clicked.connect(self.GoBack) self.ForwardButton = QPushButton(">") self.ForwardButton.clicked.connect(self.GoForward) self.ReloadButton = QPushButton("R") self.ReloadButton.clicked.connect(self.ReloadPage) # build Toolbar self.Toolbar.setLayout(self.ToolbarLayout) self.ToolbarLayout.addWidget(self.BackButton) self.ToolbarLayout.addWidget(self.ForwardButton) self.ToolbarLayout.addWidget(self.ReloadButton) self.ToolbarLayout.addWidget(self.addressbar) self.ToolbarLayout.addWidget(self.AddTabButton) # set main view self.container = QWidget() self.container.layout = QStackedLayout() self.container.setLayout(self.container.layout) self.layout.addWidget(self.tabbar) self.layout.addWidget(self.Toolbar) self.layout.addWidget(self.container) self.setLayout(self.layout) self.AddTab() self.show()
def __init__(self): super().__init__() self.setWindowTitle("My App") layout = QStackedLayout() layout.addWidget(Color("red")) layout.addWidget(Color("green")) layout.addWidget(Color("blue")) layout.addWidget(Color("yellow")) layout.setCurrentIndex(1) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
class Window(QMainWindow): """GUI View""" def __init__(self): """View initializer.""" super().__init__() self.number_point = 1 self.function_type = 0 self.firstpointvalue = "" self.secondpointvalue = "" self.thirdpointvalue = "" self.fourthpointvalue = "" self.firstendpointvalue = "" self.secondendpointvalue = "" self.thirdendpointvalue = "" self.fourthendpointvalue = "" self.first_link = 1 self.second_link = 2 self.third_link = 3 self.fourth_link = 4 # Set some main window's properties self.setWindowTitle('Function Image') self.setWindowIcon(QtGui.QIcon('Draw.ico')) self.setFixedSize(900, 600) # Set the central widget self._centralWidget = QWidget(self) self.setCentralWidget(self._centralWidget) #Set the Grid Layout self.layout = QGridLayout() #Set the First Part Outer Layout self.sublayout_1 = QVBoxLayout() self.sublayout_1.setContentsMargins(10, 0, 50, 0) self.basic_groupbox = QGroupBox("Basic Configuration") self.basic_groupbox.setContentsMargins(40, 0, 0, 0) self.basic_groupbox.setLayout(self.sublayout_1) #Set the The First Part of Inner Layout self.leftlayout_1 = QHBoxLayout() self.function_type_group_box = QGroupBox("Function Type :") self.function_type_group_box.setFixedHeight(60) self.function_type_group_box.setContentsMargins(100, 0, 0, 0) self.function_type_group_box.setLayout(self.leftlayout_1) self.type_radiobutton_1 = QRadioButton("A/B") self.type_radiobutton_1.setChecked(True) self.type_radiobutton_2 = QRadioButton("x - f(x)") self.type_radiobutton_3 = QRadioButton("None") #Place the Radiobutton self.leftlayout_1.addWidget(self.type_radiobutton_1) self.leftlayout_1.addWidget(self.type_radiobutton_2) self.leftlayout_1.addWidget(self.type_radiobutton_3) #Set the Second part of Inner Layout self.leftlayout_2 = QFormLayout() self.leftlayout_2.setHorizontalSpacing(20) self.function_info_group_box = QGroupBox("Function Info :") self.function_info_group_box.setFixedHeight(60) self.function_info_group_box.setContentsMargins(100, 10, 0, 0) self.function_info_group_box.setLayout(self.leftlayout_2) #Set and Place the Component for the form layout self.function_name = QLineEdit() self.function_name.setFixedWidth(200) self.leftlayout_2.addRow("Function Name:", self.function_name) #Set the Third Part of Inner Layout self.leftlayout_3 = QHBoxLayout() self.point_number = QGroupBox("Point Number :") self.point_number.setFixedHeight(60) self.point_number.setContentsMargins(100, 10, 0, 0) self.point_number.setLayout(self.leftlayout_3) self.number_1 = QRadioButton("1") self.number_2 = QRadioButton("2") self.number_3 = QRadioButton("3") self.number_4 = QRadioButton("4") self.number_1.setChecked(True) #Place the Radiobutton self.leftlayout_3.addWidget(self.number_1) self.leftlayout_3.addWidget(self.number_2) self.leftlayout_3.addWidget(self.number_3) self.leftlayout_3.addWidget(self.number_4) #Place all the Inner Layout for First Part of Outer Layout self.sublayout_1.addWidget(self.function_type_group_box) self.sublayout_1.addWidget(self.function_info_group_box) self.sublayout_1.addWidget(self.point_number) #Set the Second Part Outer Layout self.sublayout_2 = QHBoxLayout() self.advanced_groupbox = QGroupBox("Advanced Configuration") self.advanced_groupbox.setContentsMargins(40, 0, 0, 0) self.advanced_groupbox.setLayout(self.sublayout_2) #Create the stacked Layout self.stackedLayout = QStackedLayout() #Place the Page to Stacked Layout self.stackedLayout.addWidget(self.Page1()) self.stackedLayout.addWidget(self.Page2()) self.stackedLayout.addWidget(self.Page3()) self.stackedLayout.addWidget(self.Page4()) #Place the Stacked Layout self.sublayout_2.addLayout(self.stackedLayout) #Set the Third Part Outer Layout self.sublayout_3 = QVBoxLayout() self.preview_button = QPushButton('Preview') self.sublayout_3.addWidget(self.preview_button) #Place all the Outer Layout self.layout.addWidget(self.basic_groupbox, 0, 0, 3, 2) self.layout.addWidget(self.advanced_groupbox, 0, 2, 2, 1) self.layout.addLayout(self.sublayout_3, 2, 2, 1, 1) #Place the Grid layout to Central Widget self._centralWidget.setLayout(self.layout) #Connect all Function self.number_1.clicked.connect(lambda: self.switchPage(self.number_1)) self.number_2.clicked.connect(lambda: self.switchPage(self.number_2)) self.number_3.clicked.connect(lambda: self.switchPage(self.number_3)) self.number_4.clicked.connect(lambda: self.switchPage(self.number_4)) self.preview_button.clicked.connect(self.CreateImage) self.type_radiobutton_1.clicked.connect(self.setFunctionType) self.type_radiobutton_2.clicked.connect(self.setFunctionType) self.type_radiobutton_3.clicked.connect(self.setFunctionType) #Set the Status Bar status = QStatusBar() status.showMessage("Welcome to the Creating function image tool") self.setStatusBar(status) def Page1(self): #Create the First Page page1 = QWidget() page1.setContentsMargins(0, 10, 0, 0) page1Layout = QFormLayout() page1Layout.setVerticalSpacing(10) firstpointvalue = QLineEdit() firstendpointvalue = QLineEdit() page1Layout.addRow("First Point Value :", firstpointvalue) page1Layout.addRow("First End Point Value :", firstendpointvalue) page1.setLayout(page1Layout) firstpointvalue.textChanged.connect(lambda: self.textChange(firstpointvalue.text(), 1)) firstendpointvalue.textChanged.connect(lambda: self.textEndChange(firstendpointvalue.text(), 1)) return page1 def Page2(self): #Create the Second Page page2 = QWidget() page2.setContentsMargins(0, 10, 0, 0) page2Layout = QFormLayout() page2Layout.setVerticalSpacing(40) firstpointvalue = QLineEdit() firstendpointvalue = QLineEdit() secondpointvalue = QLineEdit() secondendpointvalue = QLineEdit() combolink1 = QComboBox() combolink1.addItems(["1st", "2nd"]) combolink1.setCurrentIndex(self.first_link-1) combolink2 = QComboBox() combolink2.addItems(["1st", "2nd"]) combolink2.setCurrentIndex(self.second_link-1) page2Layout.addRow("First Point Value :", firstpointvalue) page2Layout.addRow("First End Point Value :", firstendpointvalue) page2Layout.addRow("Second Point Value :", secondpointvalue) page2Layout.addRow("Second End Point Value :", secondendpointvalue) page2Layout.addRow("1st Point Link :", combolink1) page2Layout.addRow("2nd Point Link :", combolink2) page2.setLayout(page2Layout) firstpointvalue.textChanged.connect(lambda: self.textChange(firstpointvalue.text(), 1)) firstendpointvalue.textChanged.connect(lambda: self.textEndChange(firstendpointvalue.text(), 1)) secondpointvalue.textChanged.connect(lambda: self.textChange(secondpointvalue.text(), 2)) secondendpointvalue.textChanged.connect(lambda: self.textEndChange(secondendpointvalue.text(), 2)) combolink1.currentIndexChanged.connect(lambda: self.selectionChange(combolink1, 1)) combolink2.currentIndexChanged.connect(lambda: self.selectionChange(combolink2, 2)) self.number_2.toggled.connect(lambda: self.checkChange([1,2], combolink1,combolink2)) return page2 def Page3(self): #Create the Third Page page3 = QWidget() page3.setContentsMargins(0, 10, 0, 0) page3Layout = QFormLayout() page3Layout.setVerticalSpacing(20) firstpointvalue = QLineEdit() firstendpointvalue = QLineEdit() secondpointvalue = QLineEdit() secondendpointvalue = QLineEdit() thirdpointvalue = QLineEdit() thirdendpointvalue = QLineEdit() combolink1 = QComboBox() combolink1.addItems(["1st", "2nd", "3rd"]) combolink1.setCurrentIndex(self.first_link-1) combolink2 = QComboBox() combolink2.addItems(["1st", "2nd", "3rd"]) combolink2.setCurrentIndex(self.second_link-1) combolink3 = QComboBox() combolink3.addItems(["1st", "2nd", "3rd"]) combolink3.setCurrentIndex(self.third_link-1) page3Layout.addRow("First Point Value :", firstpointvalue) page3Layout.addRow("First End Point Value :", firstendpointvalue) page3Layout.addRow("Second Point Value :", secondpointvalue) page3Layout.addRow("Second End Point Value :", secondendpointvalue) page3Layout.addRow("Third Point Value :", thirdpointvalue) page3Layout.addRow("Third End Point Value :", thirdendpointvalue) page3Layout.addRow("1st Point Link :", combolink1) page3Layout.addRow("2nd Point Link :", combolink2) page3Layout.addRow("3rd Point Link :", combolink3) page3.setLayout(page3Layout) firstpointvalue.textChanged.connect(lambda: self.textChange(firstpointvalue.text(), 1)) firstendpointvalue.textChanged.connect(lambda: self.textEndChange(firstendpointvalue.text(), 1)) secondpointvalue.textChanged.connect(lambda: self.textChange(secondpointvalue.text(), 2)) secondendpointvalue.textChanged.connect(lambda: self.textEndChange(secondendpointvalue.text(), 2)) thirdpointvalue.textChanged.connect(lambda: self.textChange(thirdpointvalue.text(), 3)) thirdendpointvalue.textChanged.connect(lambda: self.textEndChange(thirdendpointvalue.text(), 3)) combolink1.currentIndexChanged.connect(lambda: self.selectionChange(combolink1, 1)) combolink2.currentIndexChanged.connect(lambda: self.selectionChange(combolink2, 2)) combolink3.currentIndexChanged.connect(lambda: self.selectionChange(combolink3, 3)) self.number_3.toggled.connect(lambda: self.checkChange([1,2,3], combolink1,combolink2,combolink3)) return page3 def Page4(self): #Create the Fourth Page page4 = QWidget() page4.setContentsMargins(0, 10, 0, 0) page4Layout = QFormLayout() page4Layout.setVerticalSpacing(18) firstpointvalue = QLineEdit() firstendpointvalue = QLineEdit() secondpointvalue = QLineEdit() secondendpointvalue = QLineEdit() thirdpointvalue = QLineEdit() thirdendpointvalue = QLineEdit() fourthpointvalue = QLineEdit() fourthendpointvalue = QLineEdit() combolink1 = QComboBox() combolink1.addItems(["1st", "2nd", "3rd", "4th"]) combolink1.setCurrentIndex(self.first_link-1) combolink2 = QComboBox() combolink2.addItems(["1st", "2nd", "3rd", "4th"]) combolink2.setCurrentIndex(self.second_link-1) combolink3 = QComboBox() combolink3.addItems(["1st", "2nd", "3rd", "4th"]) combolink3.setCurrentIndex(self.third_link-1) combolink4 = QComboBox() combolink4.addItems(["1st", "2nd", "3rd", "4th"]) combolink4.setCurrentIndex(self.fourth_link-1) page4Layout.addRow("First Point Value :", firstpointvalue) page4Layout.addRow("First End Point Value :", firstendpointvalue) page4Layout.addRow("Second Point Value :", secondpointvalue) page4Layout.addRow("Second End Point Value :", secondendpointvalue) page4Layout.addRow("Third Point Value :", thirdpointvalue) page4Layout.addRow("Third End Point Value :", thirdendpointvalue) page4Layout.addRow("Fourth Point Value :", fourthpointvalue) page4Layout.addRow("Fourth End Point Value :", fourthendpointvalue) page4Layout.addRow("1st Point Link :", combolink1) page4Layout.addRow("2nd Point Link :", combolink2) page4Layout.addRow("3rd Point Link :", combolink3) page4Layout.addRow("4th Point Link :", combolink4) page4.setLayout(page4Layout) firstpointvalue.textChanged.connect(lambda: self.textChange(firstpointvalue.text(), 1)) firstendpointvalue.textChanged.connect(lambda: self.textEndChange(firstendpointvalue.text(), 1)) secondpointvalue.textChanged.connect(lambda: self.textChange(secondpointvalue.text(), 2)) secondendpointvalue.textChanged.connect(lambda: self.textEndChange(secondendpointvalue.text(), 2)) thirdpointvalue.textChanged.connect(lambda: self.textChange(thirdpointvalue.text(), 3)) thirdendpointvalue.textChanged.connect(lambda: self.textEndChange(thirdendpointvalue.text(), 3)) fourthpointvalue.textChanged.connect(lambda: self.textChange(fourthpointvalue.text(), 4)) fourthendpointvalue.textChanged.connect(lambda: self.textEndChange(fourthendpointvalue.text(), 4)) combolink1.currentIndexChanged.connect(lambda: self.selectionChange(combolink1, 1)) combolink2.currentIndexChanged.connect(lambda: self.selectionChange(combolink2, 2)) combolink3.currentIndexChanged.connect(lambda: self.selectionChange(combolink3, 3)) combolink4.currentIndexChanged.connect(lambda: self.selectionChange(combolink4, 4)) self.number_4.toggled.connect(lambda: self.checkChange([1,2,3,4], combolink1,combolink2,combolink3,combolink4)) return page4 def switchPage(self, b): b = int(b.text()) # Set the point number self.number_point = b self.stackedLayout.setCurrentIndex(b-1) def selectionChange(self, combobox: QComboBox, num: int): if num == 1 : self.first_link = combobox.currentIndex()+1 if num == 2 : self.second_link = combobox.currentIndex()+1 if num == 3 : self.third_link = combobox.currentIndex()+1 if num == 4 : self.fourth_link = combobox.currentIndex()+1 def checkChange(self, num: list, *combobox: QComboBox): for i in num : if i == 1: combobox[i-1].setCurrentIndex(self.first_link-1) if i == 2: combobox[i-1].setCurrentIndex(self.second_link-1) if i == 3: combobox[i-1].setCurrentIndex(self.third_link-1) if i == 4: combobox[i-1].setCurrentIndex(self.fourth_link-1) def textChange(self, text: str, num: int): if num == 1: self.firstpointvalue = text if num == 2: self.secondpointvalue = text if num == 3: self.thirdpointvalue = text if num == 4: self.fourthpointvalue = text def textEndChange(self, text: str, num: int): if num == 1 : self.firstendpointvalue = text if num == 2 : self.secondendpointvalue = text if num == 3 : self.thirdendpointvalue = text if num == 4 : self.fourthendpointvalue = text def setFunctionType(self): if self.type_radiobutton_1.isChecked() : self.function_type = 0 elif self.type_radiobutton_2.isChecked() : self.function_type = 1 elif self.type_radiobutton_3.isChecked() : self.function_type = 2 pass def CreateImage(self): # Initialize the value if self.number_point == 1: self.point_domain = [self.firstpointvalue] self.point_range = [self.firstendpointvalue] self.link_order = [1] elif self.number_point == 2 : self.point_domain = [self.firstpointvalue, self.secondpointvalue] self.point_range = [self.firstendpointvalue, self.secondendpointvalue] self.link_order = [self.first_link, self.second_link] elif self.number_point == 3: self.point_domain = [self.firstpointvalue, self.secondpointvalue, self.thirdpointvalue] self.point_range = [self.firstendpointvalue, self.secondendpointvalue, self.thirdendpointvalue] self.link_order = [self.first_link, self.second_link, self.third_link] elif self.number_point == 4 : self.point_domain = [self.firstpointvalue, self.secondpointvalue, self.thirdpointvalue, self.fourthpointvalue] self.point_range = [self.firstendpointvalue, self.secondendpointvalue, self.thirdendpointvalue, self.fourthendpointvalue] self.link_order = [self.first_link, self.second_link, self.third_link, self.fourth_link] #Create the Image img = Picture() img.DrawFunction(self.function_type, self.function_name.text(), self.number_point, self.point_domain, self.point_range, self.link_order) # Create the Preview Frame Frame = Preview_Window(img.img) Frame.show()
class ProjectTreeColumn(QDialog): # Signals dockWidget = pyqtSignal('PyQt_PyObject') undockWidget = pyqtSignal() changeTitle = pyqtSignal('PyQt_PyObject', 'QString') updateLocator = pyqtSignal() def __init__(self, parent=None): super(ProjectTreeColumn, self).__init__(parent) vbox = QVBoxLayout(self) # vbox.setSizeConstraint(QVBoxLayout.SetDefaultConstraint) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self._buttons = [] self._combo_project = QComboBox() self._combo_project.setProperty("border_bottom", True) self._combo_project.setProperty("gradient", True) # self._combo_project.setProperty("border", True) # self._combo_project.setFrame(False) # self._combo_project.setMinimumHeight(30) self._combo_project.setContextMenuPolicy(Qt.CustomContextMenu) vbox.addWidget(self._combo_project) self._projects_area = QStackedLayout() logger.debug("This is the projects area") vbox.addLayout(self._projects_area) self.projects = [] self._combo_project.currentIndexChanged[int].connect( self._change_current_project) self._combo_project.customContextMenuRequested[ 'const QPoint&'].connect(self.context_menu_for_root) connections = ( { 'target': 'main_container', 'signal_name': 'addToProject(QString)', 'slot': self._add_file_to_project }, { 'target': 'main_container', 'signal_name': 'showFileInExplorer(QString)', 'slot': self._show_file_in_explorer }, ) IDE.register_service('projects_explorer', self) IDE.register_signals('projects_explorer', connections) ExplorerContainer.register_tab(translations.TR_TAB_PROJECTS, self) # FIXME: Should have a ninja settings object that stores tree state # FIXME: Or bettter, application data object # TODO: check this: # self.connect(ide, SIGNAL("goingDown()"), # self.tree_projects.shutdown) # def close_project_signal(): # self.emit(SIGNAL("updateLocator()")) def install_tab(self): ide = IDE.get_service('ide') ui_tools.install_shortcuts(self, actions.PROJECTS_TREE_ACTIONS, ide) ide.goingDown.connect(self.close) def load_session_projects(self, projects): for project in projects: if os.path.exists(project): self._open_project_folder(project) def open_project_folder(self, folderName=None): if settings.WORKSPACE: directory = settings.WORKSPACE else: directory = os.path.expanduser("~") if folderName is None: folderName = QFileDialog.getExistingDirectory( self, translations.TR_OPEN_PROJECT_DIRECTORY, directory) logger.debug("Choosing Foldername") if folderName: if not file_manager.folder_exists(folderName): QMessageBox.information( self, translations.TR_PROJECT_NONEXIST_TITLE, translations.TR_PROJECT_NONEXIST % folderName) return logger.debug("Opening %s" % folderName) self._open_project_folder(folderName) def _open_project_folder(self, folderName): ninjaide = IDE.get_service("ide") project = NProject(folderName) qfsm = ninjaide.filesystem.open_project(project) if qfsm: self.add_project(project) self.save_recent_projects(folderName) # FIXME: show editor area? # main_container = IDE.get_service('main_container') # if main_container: # main_container.show_editor_area() if len(self.projects) > 1: title = "%s (%s)" % (translations.TR_TAB_PROJECTS, len(self.projects)) else: title = translations.TR_TAB_PROJECTS self.changeTitle.emit(self, title) def _add_file_to_project(self, path): """Add the file for 'path' in the project the user choose here.""" if self._projects_area.count() > 0: pathProject = [self.current_project] addToProject = add_to_project.AddToProject(pathProject, self) addToProject.exec_() if not addToProject.pathSelected: return main_container = IDE.get_service('main_container') if not main_container: return editorWidget = main_container.get_current_editor() if not editorWidget.file_path: name = QInputDialog.getText( None, translations.TR_ADD_FILE_TO_PROJECT, translations.TR_FILENAME + ": ")[0] if not name: QMessageBox.information( self, translations.TR_INVALID_FILENAME, translations.TR_INVALID_FILENAME_ENTER_A_FILENAME) return else: name = file_manager.get_basename(editorWidget.file_path) new_path = file_manager.create_path(addToProject.pathSelected, name) ide_srv = IDE.get_service("ide") old_file = ide_srv.get_or_create_nfile(path) new_file = old_file.save(editorWidget.text(), new_path) #FIXME: Make this file replace the original in the open tab else: pass # Message about no project def _show_file_in_explorer(self, path): '''Iterate through the list of available projects and show the current file in the explorer view for the first project that contains it (i.e. if the same file is included in multiple open projects, the path will be expanded for the first project only). Note: This slot is connected to the main container's "showFileInExplorer(QString)" signal.''' central = IDE.get_service('central_container') if central and not central.is_lateral_panel_visible(): return for project in self.projects: index = project.model().index(path) if index.isValid(): # This highlights the index in the tree for us project.scrollTo(index, QAbstractItemView.EnsureVisible) project.setCurrentIndex(index) break def add_project(self, project): if project not in self.projects: self._combo_project.addItem(project.name) ptree = TreeProjectsWidget(project) self._projects_area.addWidget(ptree) ptree.closeProject['PyQt_PyObject'].connect(self._close_project) pmodel = project.model ptree.setModel(pmodel) pindex = pmodel.index(pmodel.rootPath()) ptree.setRootIndex(pindex) self.projects.append(ptree) current_index = self._projects_area.count() self._projects_area.setCurrentIndex(current_index - 1) self._combo_project.setCurrentIndex(current_index - 1) def _close_project(self, widget): """Close the project related to the tree widget.""" index = self._projects_area.currentIndex() self.projects.remove(widget) self._projects_area.takeAt(index) self._combo_project.removeItem(index) index = self._combo_project.currentIndex() self._projects_area.setCurrentIndex(index) ninjaide = IDE.get_service('ide') ninjaide.filesystem.close_project(widget.project.path) widget.deleteLater() if len(self.projects) > 1: title = "%s (%s)" % (translations.TR_TAB_PROJECTS, len(self.projects)) else: title = translations.TR_TAB_PROJECTS self.changeTitle.emit(self, title) self.updateLocator.emit() def _change_current_project(self, index): self._projects_area.setCurrentIndex(index) def close_opened_projects(self): for project in reversed(self.projects): self._close_project(project) def save_project(self): """Save all the opened files that belongs to the actual project.""" if self._projects_area.count() > 0: path = self.current_project.path main_container = IDE.get_service('main_container') if path and main_container: main_container.save_project(path) def create_new_project(self): wizard = new_project_manager.NewProjectManager(self) wizard.show() @property def current_project(self): if self._projects_area.count() > 0: return self._projects_area.currentWidget().project @property def current_tree(self): return self._projects_area.currentWidget() def set_current_item(self, path): if self.current_project is not None: self.current_tree.set_current_item(path) def save_recent_projects(self, folder): settings = IDE.data_settings() recent_project_list = settings.value('recentProjects', {}) #if already exist on the list update the date time projectProperties = json_manager.read_ninja_project(folder) name = projectProperties.get('name', '') description = projectProperties.get('description', '') if name == '': name = file_manager.get_basename(folder) if description == '': description = translations.TR_NO_DESCRIPTION if folder in recent_project_list: properties = recent_project_list[folder] properties["lastopen"] = QDateTime.currentDateTime() properties["name"] = name properties["description"] = description recent_project_list[folder] = properties else: recent_project_list[folder] = { "name": name, "description": description, "isFavorite": False, "lastopen": QDateTime.currentDateTime() } #if the length of the project list it's high that 10 then delete #the most old #TODO: add the length of available projects to setting if len(recent_project_list) > 10: del recent_project_list[self.find_most_old_open( recent_project_list)] settings.setValue('recentProjects', recent_project_list) def find_most_old_open(self, recent_project_list): listFounder = [] for recent_project_path, content in list(recent_project_list.items()): listFounder.append( (recent_project_path, int(content["lastopen"].toString("yyyyMMddHHmmzzz")))) listFounder = sorted(listFounder, key=lambda date: listFounder[1], reverse=True) # sort by date last used return listFounder[0][0] def reject(self): if self.parent() is None: self.dockWidget.emit(self) def closeEvent(self, event): self.dockWidget.emit(self) event.ignore() def context_menu_for_root(self): menu = QMenu(self) path = self.current_tree.project.path action_add_file = menu.addAction(QIcon(":img/new"), translations.TR_ADD_NEW_FILE) action_add_folder = menu.addAction(QIcon(":img/openProj"), translations.TR_ADD_NEW_FOLDER) action_create_init = menu.addAction(translations.TR_CREATE_INIT) # self.connect(action_add_file, SIGNAL("triggered()"), # lambda: self.current_tree._add_new_file(path)) # self.connect(action_add_folder, SIGNAL("triggered()"), # lambda: self.current_tree._add_new_folder(path)) # self.connect(action_create_init, SIGNAL("triggered()"), # lambda: self.current_tree._create_init(path)) # menu.addSeparator() # actionRunProject = menu.addAction(QIcon( # ":img/play"), translations.TR_RUN_PROJECT) # self.connect(actionRunProject, SIGNAL("triggered()"), # self.current_tree._execute_project) # if self.current_tree._added_to_console: # actionRemoveFromConsole = menu.addAction( # translations.TR_REMOVE_PROJECT_FROM_PYTHON_CONSOLE) # self.connect(actionRemoveFromConsole, SIGNAL("triggered()"), # self.current_tree._remove_project_from_console) # else: # actionAdd2Console = menu.addAction( # translations.TR_ADD_PROJECT_TO_PYTHON_CONSOLE) # self.connect(actionAdd2Console, SIGNAL("triggered()"), # self.current_tree._add_project_to_console) # actionShowFileSizeInfo = menu.addAction(translations.TR_SHOW_FILESIZE) # self.connect(actionShowFileSizeInfo, SIGNAL("triggered()"), # self.current_tree.show_filesize_info) # actionProperties = menu.addAction(QIcon(":img/pref"), # translations.TR_PROJECT_PROPERTIES) # self.connect(actionProperties, SIGNAL("triggered()"), # self.current_tree.open_project_properties) # menu.addSeparator() action_close = menu.addAction(translations.TR_CLOSE_PROJECT) action_add_file.triggered.connect( lambda: self.current_tree._add_new_file(path)) action_add_folder.triggered.connect( lambda: self.current_tree._add_new_folder(path)) action_close.triggered.connect(self.current_tree._close_project) # self.connect(action_close, SIGNAL("triggered()"), # self.current_tree._close_project) # menu for the project for m in self.current_tree.extra_menus_by_scope['project']: if isinstance(m, QMenu): menu.addSeparator() menu.addMenu(m) # show the menu! menu.exec_(QCursor.pos())
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) scriptDir = os.path.dirname(os.path.realpath(__file__)) self.setWindowIcon( QtGui.QIcon(scriptDir + os.path.sep + 'Resources/Logo2.ico')) self.setMinimumSize(QSize(700, 200)) self.setWindowTitle('TRG-Duplicate Tracker') bar = self.menuBar() Functions_menu = bar.addMenu('Functions') scan_action = QAction('Scan', self) scan_action.setIcon( QtGui.QIcon(scriptDir + os.path.sep + 'Resources/Scan.ico')) scan_action.triggered.connect(self.scanScreen) search_action = QAction('Search', self) search_action.setIcon( QtGui.QIcon(scriptDir + os.path.sep + 'Resources/Search.ico')) search_action.triggered.connect(self.searchScreen) CheckLoc_action = QAction('Check Locations', self) CheckLoc_action.setIcon( QtGui.QIcon(scriptDir + os.path.sep + 'Resources/Racks.ico')) CheckLoc_action.triggered.connect(self.rackScreen) Functions_menu.addAction(scan_action) Functions_menu.addAction(search_action) Functions_menu.addAction(CheckLoc_action) blankWidget = QWidget() self.dupWidget = DuplicateTracker() self.searchWidget = Searcher() self.rackwidget = Racker() self.layout = QStackedLayout() self.layout.addWidget(self.dupWidget) self.layout.addWidget(self.searchWidget) self.layout.addWidget(self.rackwidget) blankWidget.setLayout(self.layout) self.setCentralWidget(blankWidget) def searchScreen(self): self.layout.setCurrentIndex(1) def scanScreen(self): self.layout.setCurrentIndex(0) def rackScreen(self): self.layout.setCurrentIndex(2)
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _win_id: The window ID the statusbar is associated with. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move to the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _severity = None _color_flags = [] STYLESHEET = _generate_stylesheet() def __init__(self, *, win_id, private, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) config.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._color_flags = ColorFlags() self._color_flags.private = private self._hbox = QHBoxLayout(self) self._set_hbox_padding() self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(private=private, win_id=win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) self.backforward = backforward.Backforward() self._hbox.addWidget(self.backforward) self.tabindex = tabindex.TabIndex() self._hbox.addWidget(self.tabindex) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) config.instance.changed.connect(self._on_config_changed) QTimer.singleShot(0, self.maybe_hide) def __repr__(self): return utils.get_repr(self) @pyqtSlot(str) def _on_config_changed(self, option): if option == 'statusbar.hide': self.maybe_hide() elif option == 'statusbar.padding': self._set_hbox_padding() @pyqtSlot() def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" tab = self._current_tab() hide = config.val.statusbar.hide if hide or (tab is not None and tab.data.fullscreen): self.hide() else: self.show() def _set_hbox_padding(self): padding = config.val.statusbar.padding self._hbox.setContentsMargins(padding.left, 0, padding.right, 0) @pyqtProperty('QStringList') def color_flags(self): """Getter for self.color_flags, so it can be used as Qt property.""" return self._color_flags.to_stringlist() def _current_tab(self): """Get the currently displayed tab.""" window = objreg.get('tabbed-browser', scope='window', window=self._win_id) return window.currentWidget() def set_mode_active(self, mode, val): """Setter for self.{insert,command,caret}_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if mode == usertypes.KeyMode.insert: log.statusbar.debug("Setting insert flag to {}".format(val)) self._color_flags.insert = val if mode == usertypes.KeyMode.passthrough: log.statusbar.debug("Setting passthrough flag to {}".format(val)) self._color_flags.passthrough = val if mode == usertypes.KeyMode.command: log.statusbar.debug("Setting command flag to {}".format(val)) self._color_flags.command = val elif mode in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]: log.statusbar.debug("Setting prompt flag to {}".format(val)) self._color_flags.prompt = val elif mode == usertypes.KeyMode.caret: tab = self._current_tab() log.statusbar.debug("Setting caret flag - val {}, selection " "{}".format(val, tab.caret.selection_enabled)) if val: if tab.caret.selection_enabled: self._set_mode_text("{} selection".format(mode.name)) self._color_flags.caret = ColorFlags.CaretMode.selection else: self._set_mode_text(mode.name) self._color_flags.caret = ColorFlags.CaretMode.on else: self._color_flags.caret = ColorFlags.CaretMode.off config.set_register_stylesheet(self, update=False) def _set_mode_text(self, mode): """Set the mode text.""" if mode == 'passthrough': key_instance = config.key_instance all_bindings = key_instance.get_reverse_bindings_for('passthrough') bindings = all_bindings.get('leave-mode') if bindings: suffix = ' ({} to leave)'.format(bindings[0]) else: suffix = '' else: suffix = '' text = "-- {} MODE --{}".format(mode.upper(), suffix) self.txt.set_text(self.txt.Text.normal, text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._stack.setCurrentWidget(self.cmd) self.show() def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget") self._stack.setCurrentWidget(self.txt) self.maybe_hide() @pyqtSlot(str) def set_text(self, val): """Set a normal (persistent) text in the status bar.""" self.txt.set_text(self.txt.Text.normal, val) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[mode].passthrough: self._set_mode_text(mode.name) if mode in [usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough]: self.set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): """Clear marked mode.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[old_mode].passthrough: if keyparsers[new_mode].passthrough: self._set_mode_text(new_mode.name) else: self.txt.set_text(self.txt.Text.normal, '') if old_mode in [usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret, usertypes.KeyMode.prompt, usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough]: self.set_mode_active(old_mode, False) @pyqtSlot(browsertab.AbstractTab) def on_tab_changed(self, tab): """Notify sub-widgets when the tab has been changed.""" self.url.on_tab_changed(tab) self.prog.on_tab_changed(tab) self.percentage.on_tab_changed(tab) self.backforward.on_tab_changed(tab) self.maybe_hide() assert tab.private == self._color_flags.private def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos()) def minimumSizeHint(self): """Set the minimum height to the text height plus some padding.""" padding = config.val.statusbar.padding width = super().minimumSizeHint().width() height = self.fontMetrics().height() + padding.top + padding.bottom return QSize(width, height)
class ImageViewer(QWidget): def __init__(self, Win): super(ImageViewer, self).__init__() self.Win = Win self.signal = resizeSignal() self.signal.resize.connect(self.resizeEvent_wrapper) self.twoDimage = twoDimage(self) self.threeDblock = threeDblock(self) self.fourDmap = fourDmap(self) self.box = QStackedLayout() self.box.addWidget(QFrame()) self.box.addWidget(QLabel("1D data")) self.box.addWidget(self.twoDimage) self.box.addWidget(self.threeDblock) self.box.addWidget(self.fourDmap) self.box.setCurrentIndex(0) self.keyflag = [False, False] self.setFocusPolicy(Qt.ClickFocus) self.setLayout(self.box) self.setMinimumSize(1, 500) def setData(self, data): if data == None: self.box.setCurrentIndex(0) self.setMinimumWidth(1) else: if data.dims == 1: self.box.setCurrentIndex(1) minWidth = 1 elif data.dims == 2: self.box.setCurrentIndex(2) self.twoDimage.loaddata(data) minWidth = 480 elif data.dims == 3: self.box.setCurrentIndex(3) self.threeDblock.loaddata(data) minWidth = 580 elif data.dims == 4: self.box.setCurrentIndex(4) self.fourDmap.loaddata(data) minWidth = 640 if self.width() < minWidth: self.Win.resize(self.Win.width()+minWidth-self.width(), self.Win.height()) self.setMinimumWidth(minWidth) def resizeEvent_wrapper(self): if self.box.currentIndex() == 2: self.twoDimage.resizeEvent_wrapper() elif self.box.currentIndex() == 3: self.threeDblock.resizeEvent_wrapper() elif self.box.currentIndex() == 4: self.fourDmap.resizeEvent_wrapper() def keyPressEvent(self, event): if event.key() == Qt.Key_Control: self.keyflag[0] = True if event.key() == Qt.Key_A: self.keyflag[1] = True if self.keyflag == [True, True]: if self.box.currentIndex() == 2: if self.twoDimage.toolPanel.isChecked(): self.twoDimage.toolPanel.setChecked(False) else: self.twoDimage.toolPanel.setChecked(True) if self.box.currentIndex() == 3: if self.threeDblock.toolPanel.isChecked(): self.threeDblock.toolPanel.setChecked(False) else: self.threeDblock.toolPanel.setChecked(True) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: self.keyflag[0] = False if event.key() == Qt.Key_A: self.keyflag[1] = False