class MdiWindowListWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.list = QListWidget() #self.list.doubleClicked.connect(self.onDblClick) self.list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.list.customContextMenuRequested.connect( self.onCustomContextMenuRequested) self.list.itemClicked.connect(self.gotoItem) windowLayout = QVBoxLayout() windowLayout.addWidget(self.list) windowLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(windowLayout) def gotoItem(self, item): windowId = item.data(QtCore.Qt.UserRole) navigate("WINDOW-ID", "Id=" + windowId) def updateWindowList(self, wndList): print("MdiWindowListWidget.updateWindowList", len(wndList)) self.list.clear() for wnd in wndList: wid = wnd.widget() text = wnd.windowTitle() + "|" + type( wid).__name__ + "|" + wid.objectName() listitem = QListWidgetItem(text) listitem.setData(QtCore.Qt.UserRole, wid.objectName()) self.list.addItem(listitem) def onCustomContextMenuRequested(self, point): item = self.list.itemAt(point) ctx = QMenu("Context menu", self) if item is not None: ctx.addAction("Close window", lambda: self.closeWindow(item)) ctx.addAction("New window", lambda: self.newWindow()) ctx.exec(self.list.viewport().mapToGlobal(point))
class Listspace(QSplitter, ViewManager): """ Class implementing the listspace viewmanager class. @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @signal lastEditorClosed() emitted after the last editor window was closed @signal editorOpened(str) emitted after an editor window was opened @signal editorOpenedEd(Editor) emitted after an editor window was opened @signal editorClosed(str) emitted just before an editor window gets closed @signal editorClosedEd(Editor) emitted just before an editor window gets closed @signal editorRenamed(str) emitted after an editor was renamed @signal editorRenamedEd(Editor) emitted after an editor was renamed @signal editorSaved(str) emitted after an editor window was saved @signal editorSavedEd(Editor) emitted after an editor window was saved @signal checkActions(Editor) emitted when some actions should be checked for their status @signal cursorChanged(Editor) emitted after the cursor position of the active window has changed @signal breakpointToggled(Editor) emitted when a breakpoint is toggled. @signal bookmarkToggled(Editor) emitted when a bookmark is toggled. @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled. @signal previewStateChanged(bool) emitted to signal a change in the preview state @signal editorLanguageChanged(Editor) emitted to signal a change of an editors language @signal editorTextChanged(Editor) emitted to signal a change of an editor's text @signal editorLineChanged(str,int) emitted to signal a change of an editor's current line (line is given one based) """ changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) lastEditorClosed = pyqtSignal() editorOpened = pyqtSignal(str) editorOpenedEd = pyqtSignal(Editor) editorClosed = pyqtSignal(str) editorClosedEd = pyqtSignal(Editor) editorRenamed = pyqtSignal(str) editorRenamedEd = pyqtSignal(Editor) editorSaved = pyqtSignal(str) editorSavedEd = pyqtSignal(Editor) checkActions = pyqtSignal(Editor) cursorChanged = pyqtSignal(Editor) breakpointToggled = pyqtSignal(Editor) bookmarkToggled = pyqtSignal(Editor) syntaxerrorToggled = pyqtSignal(Editor) previewStateChanged = pyqtSignal(bool) editorLanguageChanged = pyqtSignal(Editor) editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) def __init__(self, parent): """ Constructor @param parent parent widget (QWidget) """ self.stacks = [] QSplitter.__init__(self, parent) ViewManager.__init__(self) self.setChildrenCollapsible(False) self.viewlist = QListWidget(self) policy = self.viewlist.sizePolicy() policy.setHorizontalPolicy(QSizePolicy.Ignored) self.viewlist.setSizePolicy(policy) self.addWidget(self.viewlist) self.viewlist.setContextMenuPolicy(Qt.CustomContextMenu) self.viewlist.currentRowChanged.connect(self.__showSelectedView) self.viewlist.customContextMenuRequested.connect(self.__showMenu) self.stackArea = QSplitter(self) self.stackArea.setChildrenCollapsible(False) self.addWidget(self.stackArea) self.stackArea.setOrientation(Qt.Vertical) stack = StackedWidget(self.stackArea) self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) self.setSizes([int(self.width() * 0.2), int(self.width() * 0.8)]) # 20% for viewlist, 80% for the editors self.__inRemoveView = False self.__initMenu() self.contextMenuEditor = None self.contextMenuIndex = -1 def __initMenu(self): """ Private method to initialize the viewlist context menu. """ self.__menu = QMenu(self) self.__menu.addAction(UI.PixmapCache.getIcon("tabClose.png"), self.tr('Close'), self.__contextMenuClose) self.closeOthersMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("tabCloseOther.png"), self.tr("Close Others"), self.__contextMenuCloseOthers) self.__menu.addAction(self.tr('Close All'), self.__contextMenuCloseAll) self.__menu.addSeparator() self.saveMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("fileSave.png"), self.tr('Save'), self.__contextMenuSave) self.__menu.addAction(UI.PixmapCache.getIcon("fileSaveAs.png"), self.tr('Save As...'), self.__contextMenuSaveAs) self.__menu.addAction(UI.PixmapCache.getIcon("fileSaveAll.png"), self.tr('Save All'), self.__contextMenuSaveAll) self.__menu.addSeparator() self.openRejectionsMenuAct = self.__menu.addAction( self.tr("Open 'rejection' file"), self.__contextMenuOpenRejections) self.__menu.addSeparator() self.__menu.addAction(UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__contextMenuPrintFile) self.__menu.addSeparator() self.copyPathAct = self.__menu.addAction( self.tr("Copy Path to Clipboard"), self.__contextMenuCopyPathToClipboard) def __showMenu(self, point): """ Private slot to handle the customContextMenuRequested signal of the viewlist. @param point position to open the menu at (QPoint) """ if self.editors: itm = self.viewlist.itemAt(point) if itm is not None: row = self.viewlist.row(itm) self.contextMenuEditor = self.editors[row] self.contextMenuIndex = row if self.contextMenuEditor: self.saveMenuAct.setEnabled( self.contextMenuEditor.isModified()) fileName = self.contextMenuEditor.getFileName() self.copyPathAct.setEnabled(bool(fileName)) if fileName: rej = "{0}.rej".format(fileName) self.openRejectionsMenuAct.setEnabled( os.path.exists(rej)) else: self.openRejectionsMenuAct.setEnabled(False) self.closeOthersMenuAct.setEnabled( self.viewlist.count() > 1) self.__menu.popup(self.viewlist.mapToGlobal(point)) def canCascade(self): """ Public method to signal if cascading of managed windows is available. @return flag indicating cascading of windows is available """ return False def canTile(self): """ Public method to signal if tiling of managed windows is available. @return flag indicating tiling of windows is available """ return False def canSplit(self): """ public method to signal if splitting of the view is available. @return flag indicating splitting of the view is available. """ return True def tile(self): """ Public method to tile the managed windows. """ pass def cascade(self): """ Public method to cascade the managed windows. """ pass def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). """ self.viewlist.clear() for win in self.editors: for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() def _removeView(self, win): """ Protected method to remove a view (i.e. window). @param win editor window to be removed """ self.__inRemoveView = True ind = self.editors.index(win) itm = self.viewlist.takeItem(ind) if itm: del itm for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() self.__inRemoveView = False if ind > 0: ind -= 1 else: if len(self.editors) > 1: ind = 1 else: return stack.setCurrentWidget(stack.firstEditor()) self._showView(self.editors[ind].parent()) aw = self.activeWindow() fn = aw and aw.getFileName() or None if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) def _addView(self, win, fn=None, noName="", next=False): """ Protected method to add a view (i.e. window). @param win editor assembly to be added @param fn filename of this editor (string) @param noName name to be used for an unnamed editor (string) @param next flag indicating to add the view next to the current view (bool) """ editor = win.getEditor() if fn is None: if not noName: self.untitledCount += 1 noName = self.tr("Untitled {0}").format(self.untitledCount) self.viewlist.addItem(noName) editor.setNoName(noName) else: txt = os.path.basename(fn) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = QListWidgetItem(txt) itm.setToolTip(fn) self.viewlist.addItem(itm) self.currentStack.addWidget(win) self.currentStack.setCurrentWidget(win) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect(self.__cursorLineChanged) index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __captionChange(self, cap, editor): """ Private method to handle caption change signals from the editor. Updates the listwidget text to reflect the new caption information. @param cap Caption for the editor (string) @param editor Editor to update the caption for """ fn = editor.getFileName() if fn: self.setEditorName(editor, fn) def __cursorLineChanged(self, lineno): """ Private slot to handle a change of the current editor's cursor line. @param lineno line number of the current editor's cursor (zero based) """ editor = self.sender() if editor: fn = editor.getFileName() if fn: self.editorLineChanged.emit(fn, lineno + 1) def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). @param win editor assembly to be shown @param fn filename of this editor (string) """ editor = win.getEditor() for stack in self.stacks: if stack.hasEditor(editor): stack.setCurrentWidget(win) self.currentStack = stack break index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __showSelectedView(self, row): """ Private slot called to show a view selected in the list. @param row row number of the item clicked on (integer) """ if row != -1: self._showView(self.editors[row].parent()) self._checkActions(self.editors[row]) def activeWindow(self): """ Public method to return the active (i.e. current) window. @return reference to the active editor """ return self.currentStack.currentWidget() def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. @param windowMenu reference to the window menu """ pass def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. """ pass def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. @param editor editor window to be changed @param newName new name to be shown (string) """ if newName: currentRow = self.viewlist.currentRow() index = self.editors.index(editor) txt = os.path.basename(newName) if not QFileInfo(newName).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = self.viewlist.item(index) itm.setText(txt) itm.setToolTip(newName) self.viewlist.setCurrentRow(currentRow) self.changeCaption.emit(newName) def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. @param m flag indicating the modification status (boolean) @param editor editor window changed """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if m: keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon(UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) self._checkActions(editor) def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. @param editor editor that sent the signal """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if editor.isModified(): keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon(UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) ViewManager._syntaxErrorToggled(self, editor) def addSplit(self): """ Public method used to split the current view. """ stack = StackedWidget(self.stackArea) stack.show() self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) if self.stackArea.orientation() == Qt.Horizontal: size = self.stackArea.width() else: size = self.stackArea.height() self.stackArea.setSizes([int(size / len(self.stacks))] * len(self.stacks)) self.splitRemoveAct.setEnabled(True) self.nextSplitAct.setEnabled(True) self.prevSplitAct.setEnabled(True) def removeSplit(self): """ Public method used to remove the current split view. @return flag indicating successfull removal """ if len(self.stacks) > 1: stack = self.currentStack res = True savedEditors = stack.editors[:] for editor in savedEditors: res &= self.closeEditor(editor) if res: try: i = self.stacks.index(stack) except ValueError: return True if i == len(self.stacks) - 1: i -= 1 self.stacks.remove(stack) stack.close() self.currentStack = self.stacks[i] if len(self.stacks) == 1: self.splitRemoveAct.setEnabled(False) self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) return True return False def getSplitOrientation(self): """ Public method to get the orientation of the split view. @return orientation of the split (Qt.Horizontal or Qt.Vertical) """ return self.stackArea.orientation() def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. @param orientation orientation of the split (Qt.Horizontal or Qt.Vertical) """ self.stackArea.setOrientation(orientation) def nextSplit(self): """ Public slot used to move to the next split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) + 1 if ind == len(self.stacks): ind = 0 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def prevSplit(self): """ Public slot used to move to the previous split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) - 1 if ind == -1: ind = len(self.stacks) - 1 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def __contextMenuClose(self): """ Private method to close the selected editor. """ if self.contextMenuEditor: self.closeEditorWindow(self.contextMenuEditor) def __contextMenuCloseOthers(self): """ Private method to close the other editors. """ index = self.contextMenuIndex for i in list(range(self.viewlist.count() - 1, index, -1)) + \ list(range(index - 1, -1, -1)): editor = self.editors[i] self.closeEditorWindow(editor) def __contextMenuCloseAll(self): """ Private method to close all editors. """ savedEditors = self.editors[:] for editor in savedEditors: self.closeEditorWindow(editor) def __contextMenuSave(self): """ Private method to save the selected editor. """ if self.contextMenuEditor: self.saveEditorEd(self.contextMenuEditor) def __contextMenuSaveAs(self): """ Private method to save the selected editor to a new file. """ if self.contextMenuEditor: self.saveAsEditorEd(self.contextMenuEditor) def __contextMenuSaveAll(self): """ Private method to save all editors. """ self.saveEditorsList(self.editors) def __contextMenuOpenRejections(self): """ Private slot to open a rejections file associated with the selected editor. """ if self.contextMenuEditor: fileName = self.contextMenuEditor.getFileName() if fileName: rej = "{0}.rej".format(fileName) if os.path.exists(rej): self.openSourceFile(rej) def __contextMenuPrintFile(self): """ Private method to print the selected editor. """ if self.contextMenuEditor: self.printEditor(self.contextMenuEditor) def __contextMenuCopyPathToClipboard(self): """ Private method to copy the file name of the selected editor to the clipboard. """ if self.contextMenuEditor: fn = self.contextMenuEditor.getFileName() if fn: cb = QApplication.clipboard() cb.setText(fn) def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. @param index index of the current editor """ if index == -1 or not self.editors: return editor = self.activeWindow() if editor is None: return self._checkActions(editor) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) if not self.__inRemoveView: self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) cindex = self.editors.index(editor) self.viewlist.setCurrentRow(cindex) def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched @param event the event that occurred @return flag indicating, if we handled the event """ if event.type() == QEvent.MouseButtonPress and \ not event.button() == Qt.RightButton: switched = True if isinstance(watched, QStackedWidget): switched = watched is not self.currentStack self.currentStack = watched elif isinstance(watched, QScintilla.Editor.Editor): for stack in self.stacks: if stack.hasEditor(watched): switched = stack is not self.currentStack self.currentStack = stack break currentWidget = self.currentStack.currentWidget() if currentWidget: index = self.editors.index(currentWidget) self.viewlist.setCurrentRow(index) aw = self.activeWindow() if aw is not None: self._checkActions(aw) aw.setFocus() fn = aw.getFileName() if fn: self.changeCaption.emit(fn) if switched: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) return False
class ApplicationWindow(QMainWindow): def __init__(self, gui): QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("application main window") self.main_widget = QWidget(self) scroll_box_width = 800 # the height of the feature/label boxes (too small makes the horizontal scroll bar # cover the text) label_box_height = 35 # set the GUI widgets # the user side on the right userside = QVBoxLayout() # sample field to display lbox = QHBoxLayout() self.w_sfield = QComboBox() self.w_sfield_val = QLabel(text='NA') self.w_sfield_val.setTextInteractionFlags(Qt.TextSelectableByMouse) scroll = QScrollArea() scroll.setFixedHeight(label_box_height) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.w_sfield_val.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_sfield_val) lbox.addWidget(self.w_sfield) lbox.addWidget(scroll) userside.addLayout(lbox) # add the sample field combobox values for i in gui.exp.sample_metadata.columns: self.w_sfield.addItem(str(i)) # feature field to display lbox = QHBoxLayout() self.w_ffield = QComboBox() self.w_ffield_val = QLabel(text='NA') self.w_ffield_val.setTextInteractionFlags(Qt.TextSelectableByMouse) scroll = QScrollArea() scroll.setFixedHeight(label_box_height) self.w_ffield_val.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_ffield_val) lbox.addWidget(self.w_ffield) lbox.addWidget(scroll) userside.addLayout(lbox) for i in gui.exp.feature_metadata.columns: self.w_ffield.addItem(str(i)) # sample id lbox = QHBoxLayout() label = QLabel(text='Sample ID:') scroll = QScrollArea() scroll.setFixedHeight(label_box_height) self.w_sid = QLabel(text='?') self.w_sid.setTextInteractionFlags(Qt.TextSelectableByMouse) self.w_sid.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_sid) lbox.addWidget(label) lbox.addWidget(scroll) userside.addLayout(lbox) # feature id lbox = QHBoxLayout() label = QLabel(text='Feature ID:') scroll = QScrollArea() scroll.setFixedHeight(label_box_height) self.w_fid = QLabel(text='?') self.w_fid.setTextInteractionFlags(Qt.TextSelectableByMouse) self.w_fid.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_fid) lbox.addWidget(label) lbox.addWidget(scroll) userside.addLayout(lbox) # abundance value lbox = QHBoxLayout() label = QLabel(text='Abundance:') self.w_abund = QLabel(text='?') lbox.addWidget(label) lbox.addWidget(self.w_abund) userside.addLayout(lbox) # buttons lbox_buttons = QHBoxLayout() self.w_sequence = QPushButton(text='Copy Seq') lbox_buttons.addWidget(self.w_sequence) self.w_info = QPushButton(text='Info') lbox_buttons.addWidget(self.w_info) self.w_annotate = QPushButton(text='Annotate') lbox_buttons.addWidget(self.w_annotate) userside.addLayout(lbox_buttons) # db annotations list self.w_dblist = QListWidget() self.w_dblist.itemDoubleClicked.connect(self.double_click_annotation) userside.addWidget(self.w_dblist) # the annotation list right mouse menu self.w_dblist.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.w_dblist.customContextMenuRequested.connect( self.annotation_list_right_clicked) # buttons at bottom lbox_buttons_bottom = QHBoxLayout() self.w_save_fasta = QPushButton(text='Save Seqs') lbox_buttons_bottom.addWidget(self.w_save_fasta) self.w_enrichment = QPushButton(text='Enrichment') lbox_buttons_bottom.addWidget(self.w_enrichment) self.w_save_fig = QPushButton(text='Save Fig') lbox_buttons_bottom.addWidget(self.w_save_fig) userside.addLayout(lbox_buttons_bottom) # the heatmap on the left side heatmap = MplCanvas(self.main_widget, width=5, height=4, dpi=100) heatmap.setFocusPolicy(QtCore.Qt.ClickFocus) heatmap.setFocus() layout = QHBoxLayout(self.main_widget) frame = QFrame() splitter = QSplitter(QtCore.Qt.Horizontal, self.main_widget) splitter.addWidget(heatmap) frame.setLayout(userside) splitter.addWidget(frame) layout.addWidget(splitter) self.plotfigure = heatmap.figure self.gui = gui # link events to gui self.w_annotate.clicked.connect(self.annotate) self.w_sequence.clicked.connect(self.copy_sequence) self.w_save_fasta.clicked.connect(self.save_fasta) self.w_enrichment.clicked.connect(self.enrichment) self.w_save_fig.clicked.connect(self.save_fig) self.w_sfield.currentIndexChanged.connect(self.info_field_changed) self.w_ffield.currentIndexChanged.connect(self.info_field_changed) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) def fileQuit(self): # remove the window from the app list - memory can be cleared. app = QtCore.QCoreApplication.instance() if app is not None: if self in app.references: logger.debug('removing window from app window list') app.references.remove(self) else: logger.warning('window not in app window list. Not removed') else: logger.warning('App not found - not removing window from list') self.close() def closeEvent(self, ce): # called when the window is closed. # in that case, we need to remove the reference to the window from the app # window list, so it will be garbage collected now. # happens in fileQuit() method. self.fileQuit() def annotation_list_right_clicked(self, QPos): self.listMenu = QtWidgets.QMenu() parent_position = self.w_dblist.mapToGlobal(QtCore.QPoint(0, 0)) item = self.w_dblist.itemAt(QPos) data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) if db is None: logger.debug('No database for selected item') return menu_details = self.listMenu.addAction("Details") menu_details.triggered.connect(lambda: self.right_menu_details(item)) if db.annotatable: menu_details = self.listMenu.addAction("Update annotation") menu_details.triggered.connect( lambda: self.right_menu_update(item)) menu_delete = self.listMenu.addAction("Delete annotation") menu_delete.triggered.connect(lambda: self.right_menu_delete(item)) menu_remove = self.listMenu.addAction( "Remove seq. from annotation") menu_remove.triggered.connect( lambda: self.right_menu_remove_feature(item)) self.listMenu.move(parent_position + QPos) self.listMenu.show() def right_menu_details(self, item): self.double_click_annotation(item) def right_menu_delete(self, item): if QtWidgets.QMessageBox.warning( self, "Delete annotation?", "Are you sure you want to delete the annotation:\n%s\n" "and all associated features?" % item.text(), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: return data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) logger.debug('Deleting annotation %s' % item.text()) err = db.delete_annotation(data) if err: logger.error('Annotation not deleted. Error: %s' % err) self.gui.show_info() def right_menu_update(self, item): logger.debug('update annotation %s' % item.text) data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) db.upadte_annotation(data, self.gui.exp) def right_menu_remove_feature(self, item): features = self.gui.get_selected_seqs() if QtWidgets.QMessageBox.warning( self, "Remove feature from annotation?", "Are you sure you want to remove the %d selected features\n" "from the annotation:\n%s?" % (len(features), item.text()), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: return data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) logger.debug('Removing %d features from annotation %s' % (features, item.text())) err = db.remove_features_from_annotation(features, data) if err: logger.error('Features not removed from annotation. Error: %s' % err) def info_field_changed(self): sid, fid, abd = self.gui.get_selection_info() self.gui._update_info_labels(sid, fid, abd) def copy_sequence(self): '''Copy the sequence to the clipboard ''' cseq = self.gui.exp.feature_metadata.index[self.gui.current_select[1]] clipboard = QApplication.clipboard() clipboard.setText(cseq) def save_fasta(self): seqs = self.gui.get_selected_seqs() filename, _ = QtWidgets.QFileDialog.getSaveFileName( self, caption='Save selected seqs to fasta') self.gui.exp.save_fasta(str(filename), seqs) def save_fig(self): '''Save the figure to a pdf/svg/png. Called from the Save Fig button in the gui. ''' cfig = self.plotfigure filename, _ = QtWidgets.QFileDialog.getSaveFileName( self, caption='Save figure', filter='PDF (*.pdf);;SVG (*.svg);; PNG (*.png)', initialFilter='PDF (*.pdf)') cfig.savefig(str(filename)) def enrichment(self): '''Get and display the list of enriched database terms for the selected features. Iterate over all databases that support enrichment analysis. For each such database, get the list of enriched terms in the selected set of features (compared to the other features in the experiment). Then display the list of these terms in a new qt5 window with blue terms for ones enriched in the selected group, red terms for ones enriched in the unselected set of features ''' exp = self.gui.exp group1_seqs = self.gui.get_selected_seqs() allseqs = exp.feature_metadata.index.values group2_seqs = set(allseqs) - set(group1_seqs) for cdb in self.gui.databases: if not cdb.can_do_enrichment: continue logger.debug('Database: %s' % cdb.database_name) enriched, term_feature_scores, efeatures = cdb.enrichment( exp, group1_seqs, term_type='term') # enriched = cdb.enrichment(exp, group1_seqs, term_type='annotation') logger.debug('Got %d enriched terms' % len(enriched)) if len(enriched) == 0: QtWidgets.QMessageBox.information( self, "No enriched terms found", "No enriched annotations found when comparing\n%d selected sequences to %d " "other sequences" % (len(group1_seqs), len(group2_seqs))) return enriched = enriched.sort_values('odif') listwin = SListWindow(listname='enriched ontology terms') for idx, cres in enriched.iterrows(): if cres['odif'] > 0: ccolor = 'blue' else: ccolor = 'red' cname = cres['term'] # For each enriched term, double clicking will display a heatmap # where all annotations containing the term are the features, # and bacteria (from the two compared groups) are the samples. # This enables seeing where does the enrichment for this term come from. # i.e. which bacteria are present in each annotation containing this term. dblclick_data = {} dblclick_data['database'] = cdb dblclick_data['term'] = cname dblclick_data['exp'] = exp g1_seqs = set(group1_seqs) ordered_g1_seqs = [ s for s in exp.feature_metadata.index.values if s in g1_seqs ] ordered_g2_seqs = [ s for s in exp.feature_metadata.index.values if s in group2_seqs ] dblclick_data['features1'] = ordered_g1_seqs dblclick_data['features2'] = ordered_g2_seqs listwin.add_item('%s - effect %f, pval %f ' % (cname, cres['odif'], cres['pvals']), color=ccolor, dblclick_data=dblclick_data) listwin.exec_() def double_click_annotation(self, item): '''Show database information about the double clicked item in the list. Call the appropriate database for displaying the info ''' data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) if db is None: return db.show_annotation_info(data) def annotate(self): '''Add database annotation to selected features ''' # get the database used to add annotation if self.gui._annotation_db is None: logger.warning( 'No database with add annotation capability selected (use plot(...,databases=[dbname])' ) return # get the sequences of the selection seqs = self.gui.get_selected_seqs() # annotate err = self.gui._annotation_db.add_annotation(seqs, self.gui.exp) if err: logger.error('Error encountered when adding annotaion: %s' % err) return logger.info('Annotation added')
class Music(QWidget): def __init__(self): super().__init__() self.currentSonger = '' self.setWindowIcon(QIcon("image/tray.png")) self.setWindowTitle("SYL - 音乐盛宴") self.setObjectName("box") # 窗口无边框 self.setWindowFlags(Qt.FramelessWindowHint) # 窗口居于所有窗口的顶端 # self.setWindowFlags(Qt.WindowOverridesSystemGestures) # 窗口居于所有窗口的顶端 针对部分X11 # self.setWindowFlags(Qt.X11BypassWindowManagerHint) # 初始化基本UI界面 self.initUI() # 初始化播放核心 self.initplayer() # 显示主界面 self.show() self.widget1 = index() self.widget1.setParent(self) def initUI(self): # 获取电脑屏幕宽高 让主界面初始化后处于屏幕中间 wh = QApplication.desktop().screenGeometry() self.screen_w , self.screen_h = wh.width() ,wh.height() self.setGeometry(int((self.screen_w-300)/2),int((self.screen_h-600)/2),300,600) # self.setWindowOpacity(0.97); #当前播放歌曲的封面 songer_img = DragLabel(self) # songer_img.setwinflag.connect(self.setwinflag) songer_img.setParent(self) songer_img.resize(300,200) self.picture = QLabel(songer_img) self.picture.resize(300,200) self.picture.setStyleSheet("QLabel{ border-image:url("+conf['pifu']+")}") # syl = QLabel(songer_img) # syl.setGeometry(15,5,34,15) # syl.setStyleSheet("QLabel{ border-image:url(image/newimg/logo.png);}") # ================================ songinfo = QLabel(songer_img) songinfo.setGeometry(0,30,300,80) songinfo.setStyleSheet("QLabel{ background:transparent;}") songpic = QLabel(songinfo) songpic.setGeometry(10,0,80,80) songpic.setStyleSheet("QLabel{ border-image:url(image/newimg/user.jpg);border-radius:2px;}") self.songname = QLabel("老鼠爱大米 - 香香",songinfo) self.songname.setGeometry(105,0,210,25) self.songname.setStyleSheet("QLabel{ color:#EEE;font-size:15px;}") uploaduser = QLabel("By 张三的歌",songinfo) uploaduser.move(105,25) # uploaduser.setCursor(QCursor(Qt.PointingHandCursor)) uploaduser.setStyleSheet("QLabel{ color:yellow;font-size:15px;} QLabel:hover{color:red}") fenshu = QLabel("评分 - 7.6",songinfo) fenshu.setGeometry(105,50,210,25) # self.picture.setGraphicsEffect(QGraphicsBlurEffect()) fenshu.setStyleSheet("QLabel{ color:#EEE;font-size:15px;}") songtool = QLabel(songer_img) songtool.setGeometry(0,110,300,35) songtool.setStyleSheet("QLabel{ background:transparent;}") # 喜欢歌曲 lovesong = QLabel(songtool) lovesong.setGeometry(20,10,25,25) lovesong.setStyleSheet("QLabel{ border-image:url(image/newimg/kg_ic_player_liked.png);}") # 评论 pinglun = QLabel(songtool) pinglun.setGeometry(50,5,33,33) pinglun.setStyleSheet("QLabel{ border-image:url(image/newimg/pinglun.png);}") # 歌曲更多信息 songmore = QLabel("查看这首歌的更多资料",songtool) songmore.move(100,10) # songmore.setCursor(QCursor(Qt.PointingHandCursor)) songmore.setStyleSheet("QLabel{ color:#BBB} QLabel:hover{color:pink}") # ====================================== # 顶部工具栏 # 隐藏 btn = QPushButton("",self) btn.setGeometry(270,0,15,32) # btn.setCursor(QCursor(Qt.PointingHandCursor)) btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/mini.png) } QPushButton:hover{ border-image:url(image/newimg/mini_2.png) } ") btn.clicked.connect(self.close) # 换皮肤 btn = QPushButton("",self) btn.setGeometry(230,10,20,20) # btn.setCursor(QCursor(Qt.PointingHandCursor)) btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/fx_slide_menu_change_bg_2.png) } QPushButton:hover{ border-image:url(image/newimg/fx_slide_menu_change_bg.png) } ") btn.clicked.connect(self.huanfu) # 设置封面 # btn = QPushButton("",self) # btn.setGeometry(230,-10,41,48) # btn.setCursor(QCursor(Qt.PointingHandCursor)) # btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/fengmian.png) } ") # btn.clicked.connect(self.setHeaderImg) # 开启/关闭歌词 # btn = QPushButton("",self) # btn.setGeometry(200,0,30,30) # btn.setCursor(QCursor(Qt.PointingHandCursor)) # btn.setStyleSheet("QPushButton{ border:none;color:white;background:transparent;border-image:url(image/newimg/geci.png) } ") # btn.clicked.connect(self.lrc) # 播放组件 ( 播放 前进 后退 播放时间 进度条 歌曲名 音量 ) # 播放/暂停 self.playBtn = QPushButton("",songer_img) self.playBtn.setGeometry(130,155,32,25) self.playBtn.setStyleSheet("QPushButton{ border-image:url(image/newimg/statusbar_btn_play.png);border:none } QPushButton:hover{ border-image:url(image/newimg/statusbar_btn_play_2.png)} ") # 下一首 self.nextBtn = QPushButton("",songer_img) self.nextBtn.setGeometry(186,159,20,20) self.nextBtn.setStyleSheet("QPushButton{ border-image:url(image/newimg/statusbar_btn_next.png);border:none } QPushButton:hover{ border-image:url(image/newimg/statusbar_btn_next_2.png)}") # 音量调节 self.songvolume = QPushButton("",songer_img) self.songvolume.setGeometry(236,159,20,20) self.songvolume.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_menu_volume.png);border:none } QPushButton:hover{ border-image:url(image/newimg/ic_player_menu_volume_2.png)}") self.songvolume.clicked.connect(self.setvolume) # 音量 self.volslider = QSlider(Qt.Horizontal,self) self.volslider.setCursor(QCursor(Qt.UpArrowCursor)) self.volslider.setGeometry(250,165,45,6) self.volslider.setValue(70) self.volslider.setRange(0,100) self.volslider.setStyleSheet(qss_vol) self.volslider.setVisible(False) # 上一首 self.prevBtn = QPushButton("",songer_img) self.prevBtn.setGeometry(85,159,20,20) self.prevBtn.setStyleSheet("QPushButton{ border-image:url(image/newimg/statusbar_btn_prev.png);border:none } QPushButton:hover{ border-image:url(image/newimg/statusbar_btn_prev_2.png)}") # 播放模式 self.playmodel = QPushButton("",songer_img) self.playmodel.setGeometry(35,156,25,25) self.playmodel.setStyleSheet("QPushButton{ border-image:url(image/newimg/allmodel.png);border:none } QPushButton:hover{ border-image:url(image/newimg/allmodel_2.png)}") self.playmodel.clicked.connect(self.moshi) # 当前播放时间 self.songTime = QLabel("",self) self.songTime.setGeometry(240,180,80,20) self.songTime.setStyleSheet("QLabel{ color:#AAA;font-size:12px;}") self.songTime.setAlignment(Qt.AlignHCenter) # 当前歌曲名 self.currentMusicName = QLabel("",songer_img) self.currentMusicName.setGeometry(0,180,200,20) self.currentMusicName.setStyleSheet("QLabel{ color:white ;font-weight:100;font-size:12px;margin-left:5px;}") # 歌曲进度条 self.processSlider = QSlider(Qt.Horizontal,self) self.processSlider.setGeometry(0,193,300,7) # self.processSlider.setRange(1,100) self.processSlider.setValue(0) self.processSlider.setStyleSheet(qss_process_slider) self.processSlider.setCursor(QCursor(Qt.UpArrowCursor)) # 歌曲列表 --------------------------- listWgt = QWidget(self) listWgt.setGeometry(0, 200, 300,380) listWgt.setStyleSheet(qss_scrollbar) #列表 self.songList = QListWidget(listWgt) self.songList.setGeometry(5,0,235,380) self.songList.setStyleSheet(qss_songlist) # 列表添加右键菜单 # self.songList.setContextMenuPolicy(Qt.CustomContextMenu) # self.songList.customContextMenuRequested.connect(self.rightMenuShow) #歌曲列表右边的功能列表 funcList = QListWidget(listWgt) funcList.setGeometry(240,0,55,380) funcList.setStyleSheet(qss_menu) btn = QPushButton("",funcList) btn.clicked.connect(self.newwindow) btn.setGeometry(15,10,30,30) btn.setStyleSheet("QPushButton{ border-image:url(image/home.png)} \ QPushButton:hover{ border-image:url(image/homehover.png) }") # btn.setCursor(QCursor(Qt.PointingHandCursor)) btn = QPushButton("",funcList) btn.setGeometry(15,60,30,30) btn.setStyleSheet("QPushButton{ border-image:url(image/tuijian.png) } \ QPushButton:hover{ border-image:url(image/tuijianhover.png) }") # btn.setCursor(QCursor(Qt.PointingHandCursor)) btn = QPushButton("",funcList) btn.setGeometry(15,100,30,30) btn.setStyleSheet("QPushButton{ border-image:url(image/shoucang.png) }\QPushButton:hover{ border-image:url(image/shoucanghover.png) }") # btn.setCursor(QCursor(Qt.PointingHandCursor)) btn = QPushButton("",funcList) btn.setGeometry(15,140,30,30) btn.setStyleSheet("QPushButton{ border-image:url(image/rizhi.png) }\ QPushButton:hover{ border-image:url(image/rizhihover.png) }") # btn.setCursor(QCursor(Qt.PointingHandCursor)) btn = QPushButton("",funcList) btn.setGeometry(17,180,30,30) btn.setStyleSheet("QPushButton{ border-image:url(image/mv.png) }\ QPushButton:hover{ border-image:url(image/mvhover.png) }") # btn.setCursor(QCursor(Qt.PointingHandCursor)) setbtn = QPushButton("",funcList) setbtn.setGeometry(15,225,33,33) setbtn.setStyleSheet("QPushButton{ border-image:url(image/settinghover.png) }\ QPushButton:hover{ border-image:url(image/setting.png) }") setbtn.clicked.connect(self.openseting) #底部状态栏 wg = QWidget(self) wg.setGeometry(0, 580, 300,20) wg.setStyleSheet("QWidget{ background:#2D2D2D; } ") # ql = QLabel(" <a style='color:#444;text-decoration:none;font-size:12px;' href ='https://github.com/codeAB/music-player' >S Y L </a>",wg) # ql.resize(300,20) # ql.setAlignment(Qt.AlignRight) # ql.linkActivated.connect(self.openurl) #设置托盘图标 tray = QSystemTrayIcon(self) tray.setIcon(QIcon('image/tray.png')) self.trayIconMenu = QMenu(self) self.trayIconMenu.setStyleSheet(qss_tray) showAction = QAction(QIcon('image/tray.png'),u"显示主面板", self,triggered=self.show) self.trayIconMenu.addAction(showAction) # self.trayIconMenu.addAction(preAction) # self.trayIconMenu.addAction(pauseAction) # self.trayIconMenu.addAction(nextAction) # self.trayIconMenu.addAction(quitAction) tray.setContextMenu(self.trayIconMenu) tray.show() tray.activated.connect(self.dbclick_tray) # 重写两个方法实现拖动播放器到屏幕顶端自动隐藏 def enterEvent(self,QMouseEvent): if self.y() < 1 and self.size().width() == 300: self.setGeometry(self.x(),0,300,600) # 窗口居于所有窗口的顶端 # self.setWindowFlags(Qt.WindowOverridesSystemGestures) #针对X11 # self.setWindowFlags(Qt.X11BypassWindowManagerHint) def leaveEvent(self,QMouseEvent): if self.y() < 1 and self.size().width() == 300: self.setGeometry(self.x(),0,300,1) # 窗口居于所有窗口的顶端 # self.setWindowFlags(Qt.WindowOverridesSystemGestures) #针对X11 # self.setWindowFlags(Qt.X11BypassWindowManagerHint) # else: # self.setWindowFlags(Qt.FramelessWindowHint) #加载播放核心 def initplayer(self): #play_song_list用来方便的维护列表,主要用来记录当前播放列表 # self.play_song_list = {} self.p = Player(self) # self.songList.itemDoubleClicked.connect(self.playit) self.playBtn.clicked.connect(self.play_or_pause) self.nextBtn.clicked.connect(self.nextone) self.prevBtn.clicked.connect(self.prevone) # self.lrc() # self.vol.valueChanged.connect(self.) #双击托盘图标 def dbclick_tray(self,event): if event==QSystemTrayIcon.DoubleClick: # self.show() if self.isVisible(): self.hide() else: self.show() #打开音乐窗 def newwindow(self): if not hasattr(self,'widget1'): self.widget1 = index() self.widget1.setParent(self) # 获取屏幕宽高 wh = QApplication.desktop().screenGeometry() self.screen_w , self.screen_h = wh.width() ,wh.height() self.move(int((self.screen_w-900)/2),int((self.screen_h-600)/2)) self.widget1.show() else: if self.size().width() == 900: self.resize(300,600) self.widget1.hide() return True # wh = QApplication.desktop().screenGeometry() # self.screen_w , self.screen_h = wh.width() ,wh.height() # self.move(int((self.screen_w-900)/2),int((self.screen_h-600)/2)) self.widget1.show() self.resize(900,600) #创建右键菜单 def rightMenuShow(self,point): self.current_context_item = self.songList.itemAt(point) if self.current_context_item is None: return False rightMenu = QMenu(self.songList) # print(dir(rightMenu)) rightMenu.setStyleSheet("QMenu{ width:100px;border:none;padding:5px; } QMenu::item{ background-color: transparent;width:70px;text-align:center;height:25px; margin:0px 0px;border-bottom:1px solid #EEE;padding-left:20px;color:#333 } QMenu::item:selected{ color:red;border-bottom:1px solid pink;background:none; }") loveAction = QAction(u"添加收藏", self, triggered=self.deleteSongItem) delAction = QAction(u"删除", self, triggered=self.deleteSongItem) rateAction = QAction(u"我要打分", self, triggered=self.deleteSongItem) cmAction = QAction(u"评论", self, triggered=self.deleteSongItem) moreAction = QAction(u"歌曲详情", self, triggered=self.deleteSongItem) moneyAction = QAction(u"打赏", self, triggered=self.deleteSongItem) rightMenu.addAction(loveAction) rightMenu.addAction(delAction) rightMenu.addAction(rateAction) rightMenu.addAction(cmAction) rightMenu.addAction(moreAction) rightMenu.addAction(moneyAction) rightMenu.exec_(QCursor.pos()) def deleteSongItem(self): item = self.current_context_item # print(dir(item)) item.setBackground(QBrush(QColor("red"))) return False # index = item.text() x = self.songList.row(self.current_context_item) self.newSort(int(x)) # 获取当前鼠标右键点击的歌曲名 songname = self.current_context_item.text() p = re.compile(r'\d+') r = p.findall(songname) item = int(r[0]) - 1; mp3path = conf['mp3dir'] i = 0 for filename in os.listdir(mp3path): if i == item: # 删除列表item self.songList.takeItem(self.songList.row(self.current_context_item)) # 删除播放队列item self.playlist.removeMedia(item) # 删除文件 os.remove(os.path.join(mp3path, filename)) break i = i+1 # 当删除或者新增歌曲时更新列表 def newSort(self,index,flag = 'del'): # 删除歌曲 if flag == 'del': v = self.songList.findChildren(QPushButton,'',Qt.FindChildrenRecursively) self.songList.removeItemWidget(self.current_context_item) # print(len(v)) # v[index].parent().remove() # print(v[index].parent().hide()) self.songList.update() print(self.songList.count()) def openurl(self): QDesktopServices.openUrl(QUrl("http://sylsong.com")) def myclose(self): if hasattr(self,'widget1'): self.widget1.close() and self.close() else: self.close() def setHeaderImg(self): cs = self.currentSonger if len(cs) > 1: self.s = Singer(cs,self) self.show() # def lrc(self): # if hasattr(self,'lrctext'): # if self.lrctext.isVisible(): # self.lrctext.setVisible(False) # self.p.showgeci(1) # else: # self.lrctext.setVisible(True) # self.p.showgeci() # else: # self.lrctext = DLabel(self) # self.p.showgeci() def moshi(self): ct = self.playmodel; currentModel = self.playlist.playbackMode() if currentModel == 1: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.playmodel.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_mode_all_default.png); } QPushButton:hover{ border-image:url(image/newimg/ic_player_mode_all_default_2.png)}") elif currentModel == 2: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) self.playmodel.setStyleSheet("QPushButton{ border-image:url(image/newimg/allmodel.png); } QPushButton:hover{ border-image:url(image/newimg/allmodel_2.png)}") elif currentModel == 3: self.playlist.setPlaybackMode(QMediaPlaylist.Random) self.playmodel.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_mode_random_default.png); } QPushButton:hover{ border-image:url(image/newimg/ic_player_mode_random_default_2.png)}") elif currentModel == 4: self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) self.playmodel.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_mode_single_default.png); } QPushButton:hover{ border-image:url(image/newimg/ic_player_mode_single_default_2.png)}") def setvolume(self): if self.volslider.isVisible(): self.volslider.setVisible(False) self.songvolume.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_menu_volume.png); } QPushButton:hover{ border-image:url(image/newimg/ic_player_menu_volume_2.png)}") else: self.volslider.setVisible(True) self.songvolume.setStyleSheet("QPushButton{ border-image:url(image/newimg/ic_player_menu_volume_click.png); } QPushButton:hover{ border-image:url(image/newimg/ic_player_menu_volume_click.png)}") # def setwinflag(self,index): # if index == 2: # self.setWindowFlags(Qt.X11BypassWindowManagerHint) # self.update() # self.show() # else: # self.setWindowFlags(Qt.FramelessWindowHint) # self.update() # self.show() def openseting(self): if not hasattr(self,'popwindow'): self.popwindow = popWindow(1) else: self.popwindow.show() def huanfu(self): # self.picture.setStyleSheet("QLabel{ border-image:url(image/newimg/back.jpg)}") fileinput = QFileDialog.getOpenFileName(self,"选择一张图片作为皮肤","/opt/music-player/","Images (*.jpg)") if not fileinput[0]: return False else: f=open("conf/conf.py","w+") conf['pifu'] = fileinput[0] f.write("conf = "+str(conf)) f.close() self.picture.setStyleSheet("QLabel{ border-image:url("+fileinput[0]+")}")
class ApplicationWindow(QMainWindow): def __init__(self, gui): QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("application main window") self.main_widget = QWidget(self) scroll_box_width = 800 # set the GUI widgets # the user side on the right userside = QVBoxLayout() # sample field to display lbox = QHBoxLayout() self.w_sfield = QComboBox() self.w_sfield_val = QLabel(text='NA') self.w_sfield_val.setTextInteractionFlags(Qt.TextSelectableByMouse) scroll = QScrollArea() scroll.setFixedHeight(18) self.w_sfield_val.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_sfield_val) lbox.addWidget(self.w_sfield) lbox.addWidget(scroll) userside.addLayout(lbox) # add the sample field combobox values for i in gui.exp.sample_metadata.columns: self.w_sfield.addItem(str(i)) # feature field to display lbox = QHBoxLayout() self.w_ffield = QComboBox() self.w_ffield_val = QLabel(text='NA') self.w_ffield_val.setTextInteractionFlags(Qt.TextSelectableByMouse) scroll = QScrollArea() scroll.setFixedHeight(18) self.w_ffield_val.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_ffield_val) lbox.addWidget(self.w_ffield) lbox.addWidget(scroll) userside.addLayout(lbox) for i in gui.exp.feature_metadata.columns: self.w_ffield.addItem(str(i)) # sample id lbox = QHBoxLayout() label = QLabel(text='Sample ID:') scroll = QScrollArea() scroll.setFixedHeight(18) self.w_sid = QLabel(text='?') self.w_sid.setTextInteractionFlags(Qt.TextSelectableByMouse) self.w_sid.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_sid) lbox.addWidget(label) lbox.addWidget(scroll) userside.addLayout(lbox) # feature id lbox = QHBoxLayout() label = QLabel(text='Feature ID:') scroll = QScrollArea() scroll.setFixedHeight(18) self.w_fid = QLabel(text='?') self.w_fid.setTextInteractionFlags(Qt.TextSelectableByMouse) self.w_fid.setMinimumWidth(scroll_box_width) scroll.setWidget(self.w_fid) lbox.addWidget(label) lbox.addWidget(scroll) userside.addLayout(lbox) # abundance value lbox = QHBoxLayout() label = QLabel(text='Abundance:') self.w_abund = QLabel(text='?') lbox.addWidget(label) lbox.addWidget(self.w_abund) userside.addLayout(lbox) # buttons lbox_buttons = QHBoxLayout() self.w_sequence = QPushButton(text='Copy Seq') lbox_buttons.addWidget(self.w_sequence) self.w_info = QPushButton(text='Info') lbox_buttons.addWidget(self.w_info) self.w_annotate = QPushButton(text='Annotate') lbox_buttons.addWidget(self.w_annotate) userside.addLayout(lbox_buttons) # db annotations list self.w_dblist = QListWidget() self.w_dblist.itemDoubleClicked.connect(self.double_click_annotation) userside.addWidget(self.w_dblist) # the annotation list right mouse menu self.w_dblist.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.w_dblist.customContextMenuRequested.connect( self.annotation_list_right_clicked) # buttons at bottom lbox_buttons_bottom = QHBoxLayout() self.w_save_fasta = QPushButton(text='Save Seqs') lbox_buttons_bottom.addWidget(self.w_save_fasta) self.w_enrichment = QPushButton(text='Enrichment') lbox_buttons_bottom.addWidget(self.w_enrichment) userside.addLayout(lbox_buttons_bottom) # the heatmap on the left side heatmap = MplCanvas(self.main_widget, width=5, height=4, dpi=100) heatmap.setFocusPolicy(QtCore.Qt.ClickFocus) heatmap.setFocus() layout = QHBoxLayout(self.main_widget) frame = QFrame() splitter = QSplitter(QtCore.Qt.Horizontal, self.main_widget) splitter.addWidget(heatmap) frame.setLayout(userside) splitter.addWidget(frame) layout.addWidget(splitter) self.plotfigure = heatmap.figure self.gui = gui # link events to gui self.w_annotate.clicked.connect(self.annotate) self.w_sequence.clicked.connect(self.copy_sequence) self.w_save_fasta.clicked.connect(self.save_fasta) self.w_enrichment.clicked.connect(self.enrichment) self.w_sfield.currentIndexChanged.connect(self.info_field_changed) self.w_ffield.currentIndexChanged.connect(self.info_field_changed) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) def fileQuit(self): self.close() def closeEvent(self, ce): self.fileQuit() def annotation_list_right_clicked(self, QPos): self.listMenu = QtWidgets.QMenu() parent_position = self.w_dblist.mapToGlobal(QtCore.QPoint(0, 0)) item = self.w_dblist.itemAt(QPos) data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) if db is None: logger.debug('No database for selected item') return menu_details = self.listMenu.addAction("Details") menu_details.triggered.connect(lambda: self.right_menu_details(item)) if db.annotatable: menu_details = self.listMenu.addAction("Update annotation") menu_details.triggered.connect( lambda: self.right_menu_update(item)) menu_delete = self.listMenu.addAction("Delete annotation") menu_delete.triggered.connect(lambda: self.right_menu_delete(item)) menu_remove = self.listMenu.addAction( "Remove seq. from annotation") menu_remove.triggered.connect( lambda: self.right_menu_remove_feature(item)) self.listMenu.move(parent_position + QPos) self.listMenu.show() def right_menu_details(self, item): self.double_click_annotation(item) def right_menu_delete(self, item): if QtWidgets.QMessageBox.warning( self, "Delete annotation?", "Are you sure you want to delete the annotation:\n%s\n" "and all associated features?" % item.text(), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: return data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) logger.debug('Deleting annotation %s' % item.text()) err = db.delete_annotation(data) if err: logger.error('Annotation not deleted. Error: %s' % err) self.gui.show_info() def right_menu_update(self, item): logger.debug('update annotation %s' % item.text) data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) db.upadte_annotation(data, self.gui.exp) def right_menu_remove_feature(self, item): features = self.gui.get_selected_seqs() if QtWidgets.QMessageBox.warning( self, "Remove feature from annotation?", "Are you sure you want to remove the %d selected features\n" "from the annotation:\n%s?" % (len(features), item.text()), QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No: return data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) logger.debug('Removing %d features from annotation %s' % (features, item.text())) err = db.remove_features_from_annotation(features, data) if err: logger.error('Features not removed from annotation. Error: %s' % err) def info_field_changed(self): sid, fid, abd = self.gui.get_selection_info() self.gui._update_info_labels(sid, fid, abd) def copy_sequence(self): '''Copy the sequence to the clipboard ''' cseq = self.gui.exp.feature_metadata.index[self.gui.current_select[1]] clipboard = QApplication.clipboard() clipboard.setText(cseq) def save_fasta(self): seqs = self.gui.get_selected_seqs() filename, _ = QtWidgets.QFileDialog.getSaveFileName( self, caption='Save selected seqs to fasta') self.gui.exp.save_fasta(str(filename), seqs) def enrichment(self): group1_seqs = self.gui.get_selected_seqs() allseqs = self.gui.exp.feature_metadata.index.values group2_seqs = list(set(allseqs).difference(set(group1_seqs))) logger.debug('Getting experiment annotations for %d features' % len(allseqs)) for cdb in self.gui.databases: if not cdb.can_get_feature_terms: continue logger.debug('Database: %s' % cdb.database_name) feature_terms = cdb.get_feature_terms(allseqs, self.gui.exp) logger.debug('got %d terms' % len(feature_terms)) res = analysis.relative_enrichment(self.gui.exp, group1_seqs, feature_terms) logger.debug('Got %d enriched terms' % len(res)) if len(res) == 0: QtWidgets.QMessageBox.information( self, "No enriched terms found", "No enriched annotations found when comparing\n%d selected sequences to %d " "other sequences" % (len(group1_seqs), len(group2_seqs))) return listwin = SListWindow(listname='enriched ontology terms') for cres in res: if cres['group1'] > cres['group2']: ccolor = 'blue' else: ccolor = 'red' cname = cres['description'] listwin.add_item( '%s - %f (selected %f, other %f) ' % (cname, cres['pval'], cres['group1'], cres['group2']), color=ccolor) listwin.exec_() def double_click_annotation(self, item): '''Show database information about the double clicked item in the list. Call the appropriate database for displaying the info ''' data = item.data(QtCore.Qt.UserRole) db = data.get('_db_interface', None) if db is None: return db.show_annotation_info(data) def annotate(self): '''Add database annotation to selected features ''' # get the database used to add annotation if self.gui._annotation_db is None: logger.warn( 'No database with add annotation capability selected (use plot(...,databases=[dbname])' ) return # get the sequences of the selection seqs = self.gui.get_selected_seqs() # annotate err = self.gui._annotation_db.add_annotation(seqs, self.gui.exp) if err: logger.error('Error encountered when adding annotaion: %s' % err) return logger.info('Annotation added')
class VectorDatabaseFrame(GenericFrame): def __init__(self, parent): super().__init__(QHBoxLayout(), 'Vector Database', parent) self.vectors = None self.vector_info = VectorInformationFrame() self.list = QListWidget() self.dialog = None self.buttons = QToolBar('Buttons') self.init_list() self.init_frame() self.list.itemClicked.connect(self.unsaved_dialog) self.vector_info.save_changes.clicked.connect( lambda: self.list.currentItem().setText( self.vector_info.currentVector.data.get("Name"))) def init_frame(self): self.setFrameShape(QFrame.StyledPanel) self.init_buttons() self.layout.addWidget(self.list) self.layout.addWidget(self.vector_info) self.layout.addWidget(self.buttons) self.setMinimumSize(600, 400) def init_buttons(self): self.buttons.setOrientation(Qt.Vertical) self.buttons.setMovable(False) self.buttons.setStyleSheet(""" QToolBar { spacing: 6px; padding: 3px; } """) # Buttons after this are set to the right side spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.buttons.addWidget(spacer) b1 = QPushButton('Add Vector') self.buttons.addWidget(b1) b1.clicked.connect(self.add_vector) b2 = QPushButton('Delete Vector') self.buttons.addWidget(b2) b2.clicked.connect(self.delete_vector_dialog) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.buttons.addWidget(spacer) b3 = QPushButton('Close') self.buttons.addWidget(b3) b3.clicked.connect(self.check_status) def init_list(self): self.vectors = get_vector_list() if self.vectors: for vector in self.vectors: self.list.addItem(vector.get("Name")) self.list.setCurrentItem(self.list.itemAt(0, 0)) self.vector_info.update_frame(self.list.currentItem()) def add_vector(self): v = Vector() self.vectors.append(v.data) self.list.addItem(self.vectors[-1].get("Name")) self.list.setCurrentItem(self.list.item(self.list.count() - 1)) self.vector_info.update_frame(self.list.currentItem()) def delete_vector_dialog(self): self.dialog = GenericWindow(QGridLayout()) dialog_delete = QPushButton("Delete") dialog_cancel = QPushButton("Cancel") self.dialog.layout.addWidget(QLabel("Delete current vector?"), 0, 1) self.dialog.layout.addWidget(dialog_delete, 1, 0) self.dialog.layout.addWidget(dialog_cancel, 1, 2) dialog_delete.clicked.connect(self.dialog_confirm_delete) dialog_cancel.clicked.connect(self.dialog_cancel) self.dialog.show() def unsaved_dialog(self, vector, closeParent=None): if self.vector_info.save_changes.isEnabled(): self.dialog = GenericWindow(QGridLayout(), self) dialog_confirm = QPushButton("Continue") dialog_cancel = QPushButton("Cancel") self.dialog.layout.addWidget( QLabel( "Changes to current vector are pending.\nContinue without saving?" ), 0, 1) self.dialog.layout.addWidget(dialog_confirm, 1, 0) self.dialog.layout.addWidget(dialog_cancel, 1, 2) if closeParent is not None: dialog_confirm.clicked.connect(self.dialog_confirm_exit) else: dialog_confirm.clicked.connect(self.dialog_confirm_change) dialog_cancel.clicked.connect(self.dialog_cancel) self.dialog.show() else: self.vector_info.update_frame(vector) def dialog_confirm_exit(self): self.dialog.close() self.parentWidget().close() def dialog_confirm_change(self): self.vector_info.update_frame(self.list.currentItem()) self.dialog.close() def dialog_confirm_delete(self): del_object("Name", self.list.takeItem(self.list.currentRow()).text(), "Vector") if self.list.count() > 0: self.list.setCurrentItem(self.list.itemAt(0, 0)) self.vector_info.update_frame(self.list.currentItem()) else: self.vector_info.reset_frame() self.dialog.close() def dialog_cancel(self): self.list.setCurrentItem( self.list.findItems( self.vector_info.currentVector.data.get("Name"), Qt.MatchExactly)[0]) self.dialog.close() def check_status(self): if not self.vector_info.save_changes.isEnabled(): self.parentWidget().close() else: self.unsaved_dialog(self.vector_info.currentVector, True)
class SongList(QWidget): def __init__(self, parent=None): super(SongList, self).__init__(parent) os.chdir(os.path.dirname(os.path.abspath(__file__))) resourcesPath = os.getcwd() resourcesPath = os.path.join(resourcesPath, "resources") self.PLAY_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "play.png"))) self.PAUSE_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "pause.png"))) self.STOP_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "stop.png"))) self.DELETE_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "delete.png"))) self.setupMediaPlayer() self.setupUi() def setupMediaPlayer(self): self.mediaPlayer = QMediaPlayer() self.mediaPlayer.setNotifyInterval(1) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) def setupUi(self): self.setWindowTitle("List of songs") mainLayout = QHBoxLayout(self) verticalListLayout = QVBoxLayout() self.songsListWidget = QListWidget() self.songsListWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.songsListWidget.customContextMenuRequested.connect(self.listWidgetRightClick) verticalListLayout.addWidget(self.songsListWidget) miniHorizontalLayout = QHBoxLayout() locatorLine = QLineEdit() locatorLine.setPlaceholderText("Locator") locatorBox = QComboBox() items = ["Title", "Status", "Description", "Style", "All"] locatorBox.addItems(items) locatorBox.setCurrentIndex(len(items)-1) miniHorizontalLayout.addWidget(locatorLine) miniHorizontalLayout.addWidget(locatorBox) locatorLine.textChanged.connect(lambda:self.populateList(locatorLine.text(), locatorBox.currentText())) verticalListLayout.addLayout(miniHorizontalLayout) self.mainForm = QGroupBox() self.mainForm.setTitle("Details") mainLayout.addLayout(verticalListLayout) mainLayout.addWidget(self.mainForm) self.populateList() self.mainFormSetupUi() #self.show() self.songsListWidget.currentRowChanged.connect(self.changePage) def mainFormSetupUi(self): """title, status style, duration, descriptin, location, project, variation_another_song, timestamp""" mainLayout = QVBoxLayout(self.mainForm) #Horizontal Layout 1 horizontalLayout1 = QHBoxLayout() titleLabel = QLabel("Song name:") self.titleEdit = QLineEdit() self.titleEdit.editingFinished.connect(self.checkSong) self.titleEdit.textChanged.connect(self.validateSong) horizontalLayout1.addWidget(titleLabel) horizontalLayout1.addWidget(self.titleEdit) #Horizontal Layout 2 horizontalLayout2 = QHBoxLayout() statusLabel = QLabel("Status:") self.statusBox = QComboBox() dateLabel = QLabel("Date:") self.dateEdit = QDateTimeEdit() self.dateEdit.setCalendarPopup(True) horizontalLayout2.addWidget(statusLabel) horizontalLayout2.addWidget(self.statusBox) horizontalLayout2.addStretch(1) horizontalLayout2.addWidget(dateLabel) horizontalLayout2.addWidget(self.dateEdit) #Style Groupbox, widgets added automatically self.styleGroupBox = QGroupBox() self.styleGroupBox.setTitle("Style:") self.styleLayout = QGridLayout(self.styleGroupBox) horizontalLayout3 = QHBoxLayout() durationLabel = QLabel("Duration:") self.durationLine = QTimeEdit() self.durationLine.setDisplayFormat("mm:ss") projectLabel = QLabel("Project") self.projectComboBox = QComboBox() self.projectComboBox.setEditable(True) horizontalLayout3.addWidget(durationLabel) horizontalLayout3.addWidget(self.durationLine) horizontalLayout3.addWidget(projectLabel) horizontalLayout3.addWidget(self.projectComboBox) horizontalLayout4 = QHBoxLayout() descriptionLabel = QLabel("Description:") variationLabel = QLabel("Variation from another song: ") self.variationLine = QLineEdit() horizontalLayout4.addWidget(descriptionLabel) horizontalLayout4.addStretch(1) horizontalLayout4.addWidget(variationLabel) horizontalLayout4.addWidget(self.variationLine) self.descriptionTextEdit = QTextEdit() horizontalLayout5 = QHBoxLayout() locationLabel = QLabel("Location:") self.locationLine = QLineEdit() self.locationButton = QPushButton("...") self.locationButton.clicked.connect(self.locateFile) horizontalLayout5.addWidget(locationLabel) horizontalLayout5.addWidget(self.locationLine) horizontalLayout5.addWidget(self.locationButton) horizontalLayout6 = QHBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.sliderReleased.connect(self.playSlider) self.slider.setStyleSheet("QSlider::handle:horizontal { border: 1px solid #777; background:#b55858;}") horizontalLayout6.addWidget(self.slider) horizontalLayout7 = QHBoxLayout() self.playButton = QPushButton() self.stopButton = QPushButton() self.playButton.setIcon(self.PLAY_ICON) self.stopButton.setIcon(self.STOP_ICON) self.playButton.clicked.connect(self.playSong) self.stopButton.clicked.connect(self.stopSong) horizontalLayout7.addStretch(1) horizontalLayout7.addWidget(self.playButton) horizontalLayout7.addWidget(self.stopButton) horizontalLayout7.addStretch(1) horizontalLayout8 = QHBoxLayout() self.saveButton = QPushButton() self.saveButton.setText("Save") self.saveButton.clicked.connect(self.saveSong) horizontalLayout8.addStretch(1) horizontalLayout8.addWidget(self.saveButton) mainLayout.addLayout(horizontalLayout1) mainLayout.addLayout(horizontalLayout2) mainLayout.addWidget(self.styleGroupBox) mainLayout.addLayout(horizontalLayout3) mainLayout.addLayout(horizontalLayout4) mainLayout.addWidget(self.descriptionTextEdit) mainLayout.addLayout(horizontalLayout5) mainLayout.addLayout(horizontalLayout6) mainLayout.addLayout(horizontalLayout7) mainLayout.addLayout(horizontalLayout8) def clearForm(self): self.titleEdit.clear() self.statusBox.clear() for widget in self.styleGroupBox.children(): if not isinstance(widget, QGridLayout): widget.deleteLater() self.durationLine.clear() self.projectComboBox.clear() self.variationLine.clear() self.descriptionTextEdit.clear() self.locationLine.clear() def changePage(self, index): title = self.songsListWidget.item(index).data(Qt.UserRole) self.clearForm() self.populateForm(title) self.slider.setValue(0) def populateForm(self, title): #title is the primary key listArray = queries("""SELECT title, status, style, duration, description, location, project, variation_another_song, timestamp from songs WHERE title = ?""", (title,)) print(listArray) if len(listArray) != 0: title = listArray[0][0] status = listArray[0][1] styles = [] styleArray = listArray[0][2] if styleArray != None: if "," in styleArray: styles = styleArray.split(",") else: styles.append(styleArray) duration = listArray[0][3] description = listArray[0][4] location = listArray[0][5] project = listArray[0][6] variation_another_song = listArray[0][7] timestamp = listArray[0][8] else: title = None status = None styles = None duration = None description = None location = None project = None variation_another_song = None timestamp = None if title != None: self.titleEdit.setText(title) self.statusBox.addItems(["Select...", "Demo", "WIP", "Idea", "Unfinished song", "EQ", "Master", "Finished"]) if status != None: self.statusBox.setCurrentText(status) if timestamp != None: self.dateEdit.setDateTime(datetime.strptime(timestamp, '%d/%m/%Y %H:%M')) else: self.dateEdit.setDateTime(datetime.now())#default styleArray = queries("select style from songs where style is not null") """ print(styleArray) if styleArray != None: styleArray = styleArray[0][0] if "," in styleArray: styles = styleArray.split(",") else: styles.append(styleArray)""" stylesArray = [] query = queries("select style from songs where style is not null") if len(query) != 0: for style in query: stylesMiniArray = style[0].split(",") stylesMiniArray = list(filter(None, stylesMiniArray)) for item in stylesMiniArray: if item not in stylesArray: if item != '': stylesArray.append(item) self.x = 0 self.y = 0 if len(stylesArray) != 0: for style in stylesArray: print("style", style) checkBox = QCheckBox(style) self.styleLayout.addWidget(checkBox, self.x, self.y) self.checkBoxPositionAsignment() self.addStyle() if styles!= None: if len(styles) != 0: for style in styles: for checkbox in self.styleGroupBox.children(): if isinstance(checkbox, QCheckBox): if checkbox.text() == style: checkbox.setChecked(True) if duration != None: time = QTime(0,0,0) self.durationLine.setTime(time.addSecs(duration)) projectsArray = ["Select..."] projectsArrayQuery = queries("SELECT project from songs") if len(projectsArrayQuery) != 0: for project in projectsArrayQuery[0]: if project not in projectsArray: projectsArray.append(project) if project != None: self.projectComboBox.setCurrentText(project) if variation_another_song != None: self.variationLine.setText(variation_another_song) if description != None: self.descriptionTextEdit.setText(description) available = False if location != None: self.locationLine.setText(location) if len(self.locationLine.text()) != 0: try: self.playlist = QMediaPlaylist() self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(location))) self.mediaPlayer.setPlaylist(self.playlist) except: pass available = True#I know this is stupid but just in case self.slider.setVisible(available) self.playButton.setVisible(available) self.stopButton.setVisible(available) def populateList(self, locatorItem=None, locatorColumn=None): print(locatorItem, locatorColumn) self.songsListWidget.blockSignals(True) self.songsListWidget.clear() if locatorItem == None or locatorItem == "": listArray = queries("""SELECT title, status, timestamp from songs """) print(listArray) else: if locatorColumn != "All": #No strings concatenation, no security holes if locatorColumn == "Title": sql = """SELECT title, status, timestamp from songs where title LIKE ?""" elif locatorColumn == "Status": sql = """SELECT title, status, timestamp from songs where status LIKE ?""" elif locatorColumn == "Description": sql = """SELECT title, status, timestamp from songs where description LIKE ?""" elif locatorColumn == "Style": sql = """SELECT title, status, timestamp from songs where style LIKE ?""" locatorItem = "%" + locatorItem + "%" listArray = queries(sql, (locatorItem,)) else: locatorItem = "%" + locatorItem + "%" variables = [locatorItem, locatorItem, locatorItem, locatorItem, locatorItem] listArray = queries("""SELECT title, status, timestamp from songs where title LIKE ? OR type LIKE ? OR original_song LIKE ? OR link LIKE ? OR description LIKE ?""", variables) for item in listArray: title = item[0] status = item[1] timestamp = item[2] try: timestamp = datetime.strptime(timestamp, "%d/%m/%Y %H:%M") timestamp = timestamp.strftime("%d/%m/%Y") except: timestamp = "" text = "%s %s %s" % (title, status, timestamp) qItem = QListWidgetItem(text) qItem.setData(Qt.UserRole, title) self.songsListWidget.addItem(qItem) #new idea qItem = QListWidgetItem("New song...") qItem.setData(Qt.UserRole, "New song...") #otherwise that would be an error self.songsListWidget.addItem(qItem) self.songsListWidget.blockSignals(False) def listWidgetRightClick(self, position): widgetItem = self.songsListWidget.itemAt(position) if widgetItem != None: #quick lazy text fix if widgetItem.text() != "New song...": print(widgetItem.text()) menu = QMenu() deleteAction = QAction(self.DELETE_ICON, "Delete song") menu.addAction(deleteAction) action = menu.exec(self.mapToGlobal(position)) if action == deleteAction: msg = QMessageBox.question(None, "Delete?", "Are you sure you want to delete this entry?") if msg == QMessageBox.Yes: title = widgetItem.data(Qt.UserRole) queries("DELETE from songs where title = ?", (title,)) self.populateList() self.songsListWidget.setCurrentRow(0) def songVariations(self): sql = "SELECT title from songs" songArray = [] for song in queries(sql)[0]: songArray.append(song) return songArray def checkBoxPositionAsignment(self): self.y += 1 if self.y == 4: self.y = 0 self.x += 1 def addStyle(self, text=""): "text = "" if comes from outside" self.styleEdit = QLineEdit() self.styleEdit.setPlaceholderText("Style") self.styleEdit.textChanged.connect(self.validateStyle) self.styleEdit.returnPressed.connect(lambda: self.addStyle(self.styleEdit.text())) if text != "": self.styleLayout.takeAt(self.styleLayout.count()-1).widget().deleteLater() styleCheckBox = QCheckBox() styleCheckBox.setText(text) print(text) self.styleLayout.addWidget(styleCheckBox, self.x, self.y) self.checkBoxPositionAsignment() print(self.durationLine.text()) self.styleLayout.addWidget(self.styleEdit) def checkSong(self): text = self.titleEdit.text() sql = "SELECT title from songs where title = ?" if len(queries(sql, (text,))) != 0: self.titleEdit.setText("") def validateSong(self): pass #VALIDATE REG EXP def validateStyle(self, text): if "," in text: self.styleEdit.undo() def playSong(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.PAUSE_ICON) else: self.playButton.setIcon(self.PLAY_ICON) def positionChanged(self, position): if position != self.mediaPlayer.duration(): self.slider.setValue(position) def durationChanged(self, duration): if duration != self.mediaPlayer.position(): print("duration chagned") self.slider.setRange(0, duration) def playSlider(self): self.mediaPlayer.setPosition(self.slider.value()) def stopSong(self): self.mediaPlayer.stop() def locateFile(self): self.fileSystem = QFileDialog(filter="Sound files (*.wav *.mp3 *.flac)") self.fileSystem.show() self.fileSystem.fileSelected.connect(self.fileLoaded) def fileLoaded(self, path): self.locationLine.setText(path) try: self.playlist = QMediaPlaylist() self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(path))) self.mediaPlayer.setPlaylist(self.playlist) except: print("fail") self.slider.setVisible(True) self.playButton.setVisible(True) self.stopButton.setVisible(True) def saveSong(self): title = self.titleEdit.text() status = self.statusBox.currentText() date = self.dateEdit.text() style = "" print(status, style) x = 0 for checkBox in self.styleGroupBox.children(): if isinstance(checkBox, QCheckBox): if checkBox.isChecked(): style += (checkBox.text()) + "," x+=1 if x != 0: style = style.rstrip(",") else: style = None duration = self.durationLine.time() duration = QTime(0, 0).secsTo(duration) project = self.projectComboBox.currentText() variation = self.variationLine.text() description = self.descriptionTextEdit.toPlainText() location = self.locationLine.text() variables = [title, status, description, location, project,\ variation, date, style, duration] print("---------", variables) sql = """INSERT OR REPLACE into songs (title, status, description, location, project, variation_another_song, timestamp, style, duration) values (?, ?, ?, ?, ?, ?, ?, ?, ?)""" queries(sql, variables) self.populateList()
class Thumbnail(DockWidget): item_double_clicked = pyqtSignal(int) current_index_changed = pyqtSignal(int) remove_project_signal = pyqtSignal(int) selected_project_changed = pyqtSignal(ProjectDocument) analysis_compare = pyqtSignal(int) synchronize_changed_signal = pyqtSignal(bool) def __init__(self, history_project_manager: HistoryProjectManager, origin_project, parent=None): DockWidget.__init__(self, widget_title="历史项目", parent=parent) self.content_widget = QWidget() self.setWidget(self.content_widget) # 初始化窗口内组件 self.tb = QToolBar(self) self.list_widget = QListWidget() self.layout = QVBoxLayout() self._origin_project = origin_project self._list_item_to_project = {} self._history_project_manger = history_project_manager self.__create_layout() self.__create_tool_bar(self.tb) self.__create_list_widget() projects = self._history_project_manger.get_projects_document() for project in projects: self.add_project(project) def __del__(self): del self.list_widget del self.tb del self._history_project_manger # 创建布局 def __create_layout(self): self.layout.addWidget(self.tb) self.layout.addWidget(self.list_widget) self.content_widget.setLayout(self.layout) def current_project(self) -> ProjectDocument: return self._list_item_to_project[self.list_widget.currentItem()] # 创建工具栏 def __create_tool_bar(self, toolbar): self.new_action = QAction(QIcon(":/add.png"), "添加", self) self.new_action.triggered.connect(self.open_new_project) toolbar.addAction(self.new_action) self.delete_action = QAction(QIcon(':/remove.png'), "关闭", self) self.delete_action.triggered.connect(self.remove_project) toolbar.addAction(self.delete_action) self.analysis = QAction(QIcon(":/fenxi.png"), "历史数据分析", parent=self) self.analysis.triggered.connect(self.analysis_all_project) toolbar.addAction(self.analysis) self.analysis_compare = QAction(QIcon("://duibifenxi.png"), "数据对比", parent=self) toolbar.addAction(self.analysis_compare) self.analysis_compare.triggered.connect(self.analysis_project_with) self._is_synchronize_checked = QCheckBox("同步", self) self._is_synchronize_checked.setChecked(True) self._is_synchronize_checked.toggled.connect( self.synchronize_changed_signal) toolbar.addSeparator() toolbar.addWidget(self._is_synchronize_checked) def analysis_all_project(self): projects = self._history_project_manger.get_projects() projects.insert(0, self._origin_project.project()) years = [] for year in range(len(projects)): years.append(2014 + year) data = get_projects_area_data(projects, years) if not data: return chart = PolygonalChart("历史数据对比", data, self) chart.show() def analysis_project_with(self): """""" def __create_list_widget(self): # 设置列表窗口 self.list_widget.setGeometry(QtCore.QRect(90, 330, 621, 171)) self.list_widget.setIconSize(QtCore.QSize(100, 100)) self.list_widget.setMovement(QtWidgets.QListView.Static) self.list_widget.setResizeMode(QtWidgets.QListView.Adjust) self.list_widget.setGridSize(QtCore.QSize(150, 150)) self.list_widget.setViewMode(QtWidgets.QListView.IconMode) self.list_widget.setObjectName("listWidget") # item样式设置 self.list_widget.setStyleSheet( "QListWidget::item{border:1px solid gray; color:black; margin-top:20px;}" ) # 列表窗口右键点击菜单 self.list_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.list_widget.customContextMenuRequested.connect( self.my_listwidget_context) # 关闭自动排序 self.list_widget.setSortingEnabled(False) # 去除垂直滚动条 self.list_widget.setWrapping(0) self.list_widget.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAsNeeded) # 设置双击缩略图的信号与槽连接 self.list_widget.itemClicked.connect(self.__item_clicked) self.list_widget.itemDoubleClicked.connect(self.__item_double_clicked) def add_project(self, project): fit_pixmap = project.get_pixmap() fit_pixmap = fit_pixmap.scaled(80, 80, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation) new_item = ListWidgetItem(QIcon(fit_pixmap), project.project_brief_info()) new_item.setToolTip(project.project_brief_info()) new_item.setSizeHint(QtCore.QSize(90, 130)) self.list_widget.addItem(new_item) self.list_widget.setCurrentItem(new_item) self._list_item_to_project[new_item] = project # 右键菜单 def my_listwidget_context(self, point): pop_menu = QtWidgets.QMenu() if self.list_widget.itemAt(point): pop_menu.addAction(self.new_action) pop_menu.addAction(self.delete_action) else: pop_menu.addAction(self.new_action) pop_menu.exec_(QtGui.QCursor.pos()) # 鼠标单击 def __item_clicked(self, clicked_item): """""" def __item_double_clicked(self, item): if item in self._list_item_to_project: self.selected_project_changed.emit( self._list_item_to_project[item]) def open_new_project(self): file_format = "Project files (*.mfb)" dir_ = "." file_names = QFileDialog.getOpenFileNames(self, "选择遥感图片", dir_, file_format)[0] if file_names: project_format = ProjectFormat() had_files = self._history_project_manger.get_all_files() for file in file_names: if file == self._origin_project.get_file_name( ) or file in had_files: continue project = ProjectDocument(project_format.read_project(file)) if not project: continue self._history_project_manger.add_history_project(project) self.add_project(project) else: return None # 工具栏删除 def remove_project(self): current_project_item = self.list_widget.currentItem() if current_project_item and current_project_item in self._list_item_to_project: project = self._list_item_to_project[current_project_item] self._history_project_manger.remove_history_project(project) self.list_widget.removeItemWidget(current_project_item) self.list_widget.takeItem( self.list_widget.row(current_project_item)) del self._list_item_to_project[current_project_item] del current_project_item self.list_widget.update()
class Listspace(QSplitter, ViewManager): """ Class implementing the listspace viewmanager class. @signal changeCaption(str) emitted if a change of the caption is necessary @signal editorChanged(str) emitted when the current editor has changed @signal editorChangedEd(Editor) emitted when the current editor has changed @signal lastEditorClosed() emitted after the last editor window was closed @signal editorOpened(str) emitted after an editor window was opened @signal editorOpenedEd(Editor) emitted after an editor window was opened @signal editorClosed(str) emitted just before an editor window gets closed @signal editorClosedEd(Editor) emitted just before an editor window gets closed @signal editorRenamed(str) emitted after an editor was renamed @signal editorRenamedEd(Editor) emitted after an editor was renamed @signal editorSaved(str) emitted after an editor window was saved @signal editorSavedEd(Editor) emitted after an editor window was saved @signal checkActions(Editor) emitted when some actions should be checked for their status @signal cursorChanged(Editor) emitted after the cursor position of the active window has changed @signal breakpointToggled(Editor) emitted when a breakpoint is toggled. @signal bookmarkToggled(Editor) emitted when a bookmark is toggled. @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled. @signal previewStateChanged(bool) emitted to signal a change in the preview state @signal editorLanguageChanged(Editor) emitted to signal a change of an editors language @signal editorTextChanged(Editor) emitted to signal a change of an editor's text @signal editorLineChanged(str,int) emitted to signal a change of an editor's current line (line is given one based) """ changeCaption = pyqtSignal(str) editorChanged = pyqtSignal(str) editorChangedEd = pyqtSignal(Editor) lastEditorClosed = pyqtSignal() editorOpened = pyqtSignal(str) editorOpenedEd = pyqtSignal(Editor) editorClosed = pyqtSignal(str) editorClosedEd = pyqtSignal(Editor) editorRenamed = pyqtSignal(str) editorRenamedEd = pyqtSignal(Editor) editorSaved = pyqtSignal(str) editorSavedEd = pyqtSignal(Editor) checkActions = pyqtSignal(Editor) cursorChanged = pyqtSignal(Editor) breakpointToggled = pyqtSignal(Editor) bookmarkToggled = pyqtSignal(Editor) syntaxerrorToggled = pyqtSignal(Editor) previewStateChanged = pyqtSignal(bool) editorLanguageChanged = pyqtSignal(Editor) editorTextChanged = pyqtSignal(Editor) editorLineChanged = pyqtSignal(str, int) def __init__(self, parent): """ Constructor @param parent parent widget (QWidget) """ self.stacks = [] QSplitter.__init__(self, parent) ViewManager.__init__(self) self.setChildrenCollapsible(False) self.viewlist = QListWidget(self) policy = self.viewlist.sizePolicy() policy.setHorizontalPolicy(QSizePolicy.Ignored) self.viewlist.setSizePolicy(policy) self.addWidget(self.viewlist) self.viewlist.setContextMenuPolicy(Qt.CustomContextMenu) self.viewlist.currentRowChanged.connect(self.__showSelectedView) self.viewlist.customContextMenuRequested.connect(self.__showMenu) self.stackArea = QSplitter(self) self.stackArea.setChildrenCollapsible(False) self.addWidget(self.stackArea) self.stackArea.setOrientation(Qt.Vertical) stack = StackedWidget(self.stackArea) self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) self.setSizes([int(self.width() * 0.2), int(self.width() * 0.8)]) # 20% for viewlist, 80% for the editors self.__inRemoveView = False self.__initMenu() self.contextMenuEditor = None self.contextMenuIndex = -1 def __initMenu(self): """ Private method to initialize the viewlist context menu. """ self.__menu = QMenu(self) self.__menu.addAction( UI.PixmapCache.getIcon("tabClose.png"), self.tr('Close'), self.__contextMenuClose) self.closeOthersMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("tabCloseOther.png"), self.tr("Close Others"), self.__contextMenuCloseOthers) self.__menu.addAction( self.tr('Close All'), self.__contextMenuCloseAll) self.__menu.addSeparator() self.saveMenuAct = self.__menu.addAction( UI.PixmapCache.getIcon("fileSave.png"), self.tr('Save'), self.__contextMenuSave) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAs.png"), self.tr('Save As...'), self.__contextMenuSaveAs) self.__menu.addAction( UI.PixmapCache.getIcon("fileSaveAll.png"), self.tr('Save All'), self.__contextMenuSaveAll) self.__menu.addSeparator() self.openRejectionsMenuAct = self.__menu.addAction( self.tr("Open 'rejection' file"), self.__contextMenuOpenRejections) self.__menu.addSeparator() self.__menu.addAction( UI.PixmapCache.getIcon("print.png"), self.tr('Print'), self.__contextMenuPrintFile) self.__menu.addSeparator() self.copyPathAct = self.__menu.addAction( self.tr("Copy Path to Clipboard"), self.__contextMenuCopyPathToClipboard) def __showMenu(self, point): """ Private slot to handle the customContextMenuRequested signal of the viewlist. @param point position to open the menu at (QPoint) """ if self.editors: itm = self.viewlist.itemAt(point) if itm is not None: row = self.viewlist.row(itm) self.contextMenuEditor = self.editors[row] self.contextMenuIndex = row if self.contextMenuEditor: self.saveMenuAct.setEnabled( self.contextMenuEditor.isModified()) fileName = self.contextMenuEditor.getFileName() self.copyPathAct.setEnabled(bool(fileName)) if fileName: rej = "{0}.rej".format(fileName) self.openRejectionsMenuAct.setEnabled( os.path.exists(rej)) else: self.openRejectionsMenuAct.setEnabled(False) self.closeOthersMenuAct.setEnabled( self.viewlist.count() > 1) self.__menu.popup(self.viewlist.mapToGlobal(point)) def canCascade(self): """ Public method to signal if cascading of managed windows is available. @return flag indicating cascading of windows is available """ return False def canTile(self): """ Public method to signal if tiling of managed windows is available. @return flag indicating tiling of windows is available """ return False def canSplit(self): """ public method to signal if splitting of the view is available. @return flag indicating splitting of the view is available. """ return True def tile(self): """ Public method to tile the managed windows. """ pass def cascade(self): """ Public method to cascade the managed windows. """ pass def _removeAllViews(self): """ Protected method to remove all views (i.e. windows). """ self.viewlist.clear() for win in self.editors: for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() def _removeView(self, win): """ Protected method to remove a view (i.e. window). @param win editor window to be removed """ self.__inRemoveView = True ind = self.editors.index(win) itm = self.viewlist.takeItem(ind) if itm: del itm for stack in self.stacks: if stack.hasEditor(win): stack.removeWidget(win) break win.closeIt() self.__inRemoveView = False if ind > 0: ind -= 1 else: if len(self.editors) > 1: ind = 1 else: return stack.setCurrentWidget(stack.firstEditor()) self._showView(self.editors[ind].parent()) aw = self.activeWindow() fn = aw and aw.getFileName() or None if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) def _addView(self, win, fn=None, noName="", next=False): """ Protected method to add a view (i.e. window). @param win editor assembly to be added @param fn filename of this editor (string) @param noName name to be used for an unnamed editor (string) @param next flag indicating to add the view next to the current view (bool) """ editor = win.getEditor() if fn is None: if not noName: self.untitledCount += 1 noName = self.tr("Untitled {0}").format(self.untitledCount) self.viewlist.addItem(noName) editor.setNoName(noName) else: txt = os.path.basename(fn) if not QFileInfo(fn).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = QListWidgetItem(txt) itm.setToolTip(fn) self.viewlist.addItem(itm) self.currentStack.addWidget(win) self.currentStack.setCurrentWidget(win) editor.captionChanged.connect(self.__captionChange) editor.cursorLineChanged.connect(self.__cursorLineChanged) index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __captionChange(self, cap, editor): """ Private method to handle caption change signals from the editor. Updates the listwidget text to reflect the new caption information. @param cap Caption for the editor (string) @param editor Editor to update the caption for """ fn = editor.getFileName() if fn: self.setEditorName(editor, fn) def __cursorLineChanged(self, lineno): """ Private slot to handle a change of the current editor's cursor line. @param lineno line number of the current editor's cursor (zero based) """ editor = self.sender() if editor: fn = editor.getFileName() if fn: self.editorLineChanged.emit(fn, lineno + 1) def _showView(self, win, fn=None): """ Protected method to show a view (i.e. window). @param win editor assembly to be shown @param fn filename of this editor (string) """ editor = win.getEditor() for stack in self.stacks: if stack.hasEditor(editor): stack.setCurrentWidget(win) self.currentStack = stack break index = self.editors.index(editor) self.viewlist.setCurrentRow(index) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) self.editorChanged.emit(fn) self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) def __showSelectedView(self, row): """ Private slot called to show a view selected in the list. @param row row number of the item clicked on (integer) """ if row != -1: self._showView(self.editors[row].parent()) self._checkActions(self.editors[row]) def activeWindow(self): """ Public method to return the active (i.e. current) window. @return reference to the active editor """ return self.currentStack.currentWidget() def showWindowMenu(self, windowMenu): """ Public method to set up the viewmanager part of the Window menu. @param windowMenu reference to the window menu """ pass def _initWindowActions(self): """ Protected method to define the user interface actions for window handling. """ pass def setEditorName(self, editor, newName): """ Public method to change the displayed name of the editor. @param editor editor window to be changed @param newName new name to be shown (string) """ if newName: currentRow = self.viewlist.currentRow() index = self.editors.index(editor) txt = os.path.basename(newName) if not QFileInfo(newName).isWritable(): txt = self.tr("{0} (ro)").format(txt) itm = self.viewlist.item(index) itm.setText(txt) itm.setToolTip(newName) self.viewlist.setCurrentRow(currentRow) self.changeCaption.emit(newName) def _modificationStatusChanged(self, m, editor): """ Protected slot to handle the modificationStatusChanged signal. @param m flag indicating the modification status (boolean) @param editor editor window changed """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if m: keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon( UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) self._checkActions(editor) def _syntaxErrorToggled(self, editor): """ Protected slot to handle the syntaxerrorToggled signal. @param editor editor that sent the signal """ currentRow = self.viewlist.currentRow() index = self.editors.index(editor) keys = [] if editor.isModified(): keys.append("fileModified.png") if editor.hasSyntaxErrors(): keys.append("syntaxError22.png") elif editor.hasWarnings(): keys.append("warning22.png") if not keys: keys.append("empty.png") self.viewlist.item(index).setIcon( UI.PixmapCache.getCombinedIcon(keys)) self.viewlist.setCurrentRow(currentRow) ViewManager._syntaxErrorToggled(self, editor) def addSplit(self): """ Public method used to split the current view. """ stack = StackedWidget(self.stackArea) stack.show() self.stackArea.addWidget(stack) self.stacks.append(stack) self.currentStack = stack stack.currentChanged.connect(self.__currentChanged) stack.installEventFilter(self) if self.stackArea.orientation() == Qt.Horizontal: size = self.stackArea.width() else: size = self.stackArea.height() self.stackArea.setSizes( [int(size / len(self.stacks))] * len(self.stacks)) self.splitRemoveAct.setEnabled(True) self.nextSplitAct.setEnabled(True) self.prevSplitAct.setEnabled(True) def removeSplit(self): """ Public method used to remove the current split view. @return flag indicating successfull removal """ if len(self.stacks) > 1: stack = self.currentStack res = True savedEditors = stack.editors[:] for editor in savedEditors: res &= self.closeEditor(editor) if res: try: i = self.stacks.index(stack) except ValueError: return True if i == len(self.stacks) - 1: i -= 1 self.stacks.remove(stack) stack.close() self.currentStack = self.stacks[i] if len(self.stacks) == 1: self.splitRemoveAct.setEnabled(False) self.nextSplitAct.setEnabled(False) self.prevSplitAct.setEnabled(False) return True return False def getSplitOrientation(self): """ Public method to get the orientation of the split view. @return orientation of the split (Qt.Horizontal or Qt.Vertical) """ return self.stackArea.orientation() def setSplitOrientation(self, orientation): """ Public method used to set the orientation of the split view. @param orientation orientation of the split (Qt.Horizontal or Qt.Vertical) """ self.stackArea.setOrientation(orientation) def nextSplit(self): """ Public slot used to move to the next split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) + 1 if ind == len(self.stacks): ind = 0 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def prevSplit(self): """ Public slot used to move to the previous split. """ aw = self.activeWindow() _hasFocus = aw and aw.hasFocus() ind = self.stacks.index(self.currentStack) - 1 if ind == -1: ind = len(self.stacks) - 1 self.currentStack = self.stacks[ind] if _hasFocus: aw = self.activeWindow() if aw: aw.setFocus() index = self.editors.index(self.currentStack.currentWidget()) self.viewlist.setCurrentRow(index) def __contextMenuClose(self): """ Private method to close the selected editor. """ if self.contextMenuEditor: self.closeEditorWindow(self.contextMenuEditor) def __contextMenuCloseOthers(self): """ Private method to close the other editors. """ index = self.contextMenuIndex for i in list(range(self.viewlist.count() - 1, index, -1)) + \ list(range(index - 1, -1, -1)): editor = self.editors[i] self.closeEditorWindow(editor) def __contextMenuCloseAll(self): """ Private method to close all editors. """ savedEditors = self.editors[:] for editor in savedEditors: self.closeEditorWindow(editor) def __contextMenuSave(self): """ Private method to save the selected editor. """ if self.contextMenuEditor: self.saveEditorEd(self.contextMenuEditor) def __contextMenuSaveAs(self): """ Private method to save the selected editor to a new file. """ if self.contextMenuEditor: self.saveAsEditorEd(self.contextMenuEditor) def __contextMenuSaveAll(self): """ Private method to save all editors. """ self.saveEditorsList(self.editors) def __contextMenuOpenRejections(self): """ Private slot to open a rejections file associated with the selected editor. """ if self.contextMenuEditor: fileName = self.contextMenuEditor.getFileName() if fileName: rej = "{0}.rej".format(fileName) if os.path.exists(rej): self.openSourceFile(rej) def __contextMenuPrintFile(self): """ Private method to print the selected editor. """ if self.contextMenuEditor: self.printEditor(self.contextMenuEditor) def __contextMenuCopyPathToClipboard(self): """ Private method to copy the file name of the selected editor to the clipboard. """ if self.contextMenuEditor: fn = self.contextMenuEditor.getFileName() if fn: cb = QApplication.clipboard() cb.setText(fn) def __currentChanged(self, index): """ Private slot to handle the currentChanged signal. @param index index of the current editor """ if index == -1 or not self.editors: return editor = self.activeWindow() if editor is None: return self._checkActions(editor) editor.setFocus() fn = editor.getFileName() if fn: self.changeCaption.emit(fn) if not self.__inRemoveView: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, editor.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(editor) cindex = self.editors.index(editor) self.viewlist.setCurrentRow(cindex) def eventFilter(self, watched, event): """ Public method called to filter the event queue. @param watched the QObject being watched @param event the event that occurred @return flag indicating, if we handled the event """ if event.type() == QEvent.MouseButtonPress and \ not event.button() == Qt.RightButton: switched = True if isinstance(watched, QStackedWidget): switched = watched is not self.currentStack self.currentStack = watched elif isinstance(watched, QScintilla.Editor.Editor): for stack in self.stacks: if stack.hasEditor(watched): switched = stack is not self.currentStack self.currentStack = stack break currentWidget = self.currentStack.currentWidget() if currentWidget: index = self.editors.index(currentWidget) self.viewlist.setCurrentRow(index) aw = self.activeWindow() if aw is not None: self._checkActions(aw) aw.setFocus() fn = aw.getFileName() if fn: self.changeCaption.emit(fn) if switched: self.editorChanged.emit(fn) self.editorLineChanged.emit( fn, aw.getCursorPosition()[0] + 1) else: self.changeCaption.emit("") self.editorChangedEd.emit(aw) return False
class Controles(QMainWindow): def __init__(self, parent=None): super(Controles, self).__init__(parent) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setWindowTitle("Controles") self.Reproduciendo = False self.strButtonShow = " Ver Reproductor" self.strButtonHide = "Ocultar Reproductor" self.videoVentana = VideoWindow() self.videoVentana.setControles(self) self.videoVentana.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint) self.videoVentana.resize(640, 480) self.listwidget = QListWidget() self.listwidget.clicked.connect(self.listclicked) self.playButton = QPushButton() self.playButton.setEnabled(True) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.stopButton = QPushButton() self.stopButton.setEnabled(True) self.stopButton.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.stopButton.clicked.connect(self.stop) self.anadirButton = QPushButton() self.anadirButton.setEnabled(True) self.anadirButton.setText("+") self.anadirButton.setIcon(self.style().standardIcon( QStyle.SP_FileIcon)) self.anadirButton.clicked.connect(self.addFile) self.removeButton = QPushButton() self.removeButton.setEnabled(True) self.removeButton.setText("-") self.removeButton.setIcon(self.style().standardIcon( QStyle.SP_FileIcon)) self.removeButton.clicked.connect(self.removeFile) self.abrirListaButton = QPushButton() self.abrirListaButton.setEnabled(True) self.abrirListaButton.setText(" ") self.abrirListaButton.setIcon(self.style().standardIcon( QStyle.SP_FileDialogNewFolder)) self.abrirListaButton.clicked.connect(self.openList) self.guardarListaButton = QPushButton() self.guardarListaButton.setEnabled(True) self.guardarListaButton.setText(" ") self.guardarListaButton.setIcon(self.style().standardIcon( QStyle.SP_DialogSaveButton)) self.guardarListaButton.clicked.connect(self.saveList) self.quitarButton = QPushButton() self.quitarButton.setEnabled(True) self.quitarButton.setText("-") self.quitarButton.setIcon(self.style().standardIcon( QStyle.SP_FileIcon)) self.quitarButton.clicked.connect(self.removeFile) self.showPlayerButton = QPushButton() self.showPlayerButton.setEnabled(True) self.showPlayerButton.setText(self.strButtonShow) self.showPlayerButton.clicked.connect(self.showPlayer) self.maxButton = QPushButton() self.maxButton.setEnabled(True) self.maxButton.setText("Maximizar") self.maxButton.clicked.connect(self.maximizePlayer) self.minButton = QPushButton() self.minButton.setEnabled(True) self.minButton.setText("Normal") self.minButton.clicked.connect(self.minimizePlayer) self.screensButton = QPushButton() self.screensButton.setEnabled(True) self.screensButton.setText("Cambiar pantalla") self.screensButton.clicked.connect(self.elegirPantalla) self.sigScreenButton = QPushButton() self.sigScreenButton.setEnabled(True) self.sigScreenButton.setText(">") self.sigScreenButton.setIcon(self.style().standardIcon( QStyle.SP_ComputerIcon)) self.sigScreenButton.clicked.connect(self.sigPantalla) self.antScreenButton = QPushButton() self.antScreenButton.setEnabled(True) self.antScreenButton.setText("<") self.antScreenButton.setIcon(self.style().standardIcon( QStyle.SP_ComputerIcon)) self.antScreenButton.clicked.connect(self.antPantalla) self.lblMediaActual = QLabel() self.lblMediaActual.setText("Media actual: No seleccionado.") self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # Create a widget for window contents wid = QWidget(self) self.setCentralWidget(wid) # Create layouts to place inside widget #controlLayout = QHBoxLayout() controlLayout = QGridLayout() #controlLayout.setContentsMargins(0, 0, 0, 0) # row, col, rowspan, colspan# controlLayout.addWidget(self.maxButton, 0, 0, 1, 2) controlLayout.addWidget(self.minButton, 0, 2, 1, 2) controlLayout.addWidget(self.showPlayerButton, 0, 4, 1, 2) controlLayout.addWidget(self.screensButton, 0, 6, 1, 2) controlLayout.addWidget(self.positionSlider, 1, 0, 1, 8) controlLayout.addWidget(self.listwidget, 2, 0, 6, 4) controlLayout.addWidget(self.playButton, 2, 4, 1, 1) controlLayout.addWidget(self.stopButton, 3, 4, 1, 1) controlLayout.addWidget(self.anadirButton, 4, 4, 1, 1) controlLayout.addWidget(self.quitarButton, 4, 5, 1, 1) controlLayout.addWidget(self.lblMediaActual, 5, 4, 1, 4) controlLayout.addWidget(self.abrirListaButton, 2, 5, 1, 1) controlLayout.addWidget(self.sigScreenButton, 2, 7, 1, 1) controlLayout.addWidget(self.antScreenButton, 3, 7, 1, 1) controlLayout.addWidget(self.guardarListaButton, 3, 5, 1, 1) controlLayout.addWidget(self.errorLabel, 8, 0, 1, 8) layout = QVBoxLayout() layout.addLayout(controlLayout) #Eventos del reproductor self.videoVentana.mediaPlayer.stateChanged.connect( self.mediaStateChanged) self.videoVentana.mediaPlayer.positionChanged.connect( self.positionChanged) self.videoVentana.mediaPlayer.durationChanged.connect( self.durationChanged) self.videoVentana.mediaPlayer.error.connect(self.handleError) self.videoVentana.mediaPlayer.currentMediaChanged.connect( self.currentMediaChanged) # Set widget to contain window contents wid.setLayout(layout) #Server, receives commands to player self.server = Server(self.videoVentana) self.startServer() def startServer(self): import threading try: threading.Thread(target=self.server.start_server, args=(puerto, )).start() print("Server on port " + str(puerto)) #QMessageBox.question(self, 'Info', "Opening server on port "+str(800), QMessageBox.Ok) except Exception as err: print(str(err)) def reload(self): self.listwidget.clear() for x in range(0, self.videoVentana.count()): try: newUrl = str(self.videoVentana.mediaPlayer.playlist().media( x).canonicalUrl().toLocalFile()) self.listwidget.insertItem( self.listwidget.count(), os.path.splitext(os.path.basename(newUrl))[0]) except Exception as err: print(str(err)) #List functions def listclicked(self, qmodelindex): #item = self.listwidget.currentItem() #print(item.text()) #print(item.row()) item = self.listwidget.currentIndex() def openList(self): try: fileName, _ = QFileDialog.getOpenFileName(self, "Seleccionar lista", QDir.homePath()) #f = open(fileName,"r") self.listwidget.clear() for line in open(fileName, 'r'): self.addFile(line) except Exception as err: QMessageBox.question(self, 'Alerta', "Error" + str(err), QMessageBox.Ok) def saveList(self): try: fileName, _ = QFileDialog.getOpenFileName(self, "Seleccionar lista", QDir.homePath()) f = open(fileName, "w+") for i in range(0, self.listwidget.count()): newUrl = str(self.videoVentana.mediaPlayer.playlist().media( i).canonicalUrl().toLocalFile()) f.write(newUrl + "\n") f.close() except Exception as err: QMessageBox.question(self, 'Alerta', "Error" + str(err), QMessageBox.Ok) def addFile(self, fileName=''): try: if fileName == '' or fileName == False: fileName, _ = QFileDialog.getOpenFileName( self, "Seleccionar video", QDir.homePath() + "\\Videos") except: fileName, _ = QFileDialog.getOpenFileName(self, "Seleccionar video", QDir.homePath()) if fileName == '' or fileName == False: return for x in range(0, self.listwidget.count() ): #Valida que no exista el archivo a agregar try: if self.listwidget.itemAt(x, 0).text() == os.path.splitext( os.path.basename(fileName))[0]: QMessageBox.question(self, 'Alerta', "Video ya en la lista", QMessageBox.Ok) return except Exception as err: print(err) return self.listwidget.insertItem( self.listwidget.count(), os.path.splitext(os.path.basename(fileName))[0]) try: self.videoVentana.addFile(fileName) except Exception as err: #Si hay un error, vuelve a abrir la ventana de video y carga la lista self.listwidget.removeItemWidget( self.listwidget.itemAt(self.listwidget.count() - 1)) self.Reproduciendo = False self.videoVentana = VideoWindow() self.videoVentana.resize(640, 480) for x in range(0, self.listwidget.count()): self.videoVentana.addFile(self.listwidget.itemAt(x).text()) print(err) def removeFile(self): index = self.listwidget.currentRow() if index != -1: try: cantPlayList = self.videoVentana.count() self.videoVentana.removeFile(index) #Elimina del playlist #self.videoVentana.mediaPlayer.playlist().removeMedia(index) if cantPlayList != self.videoVentana.count( ): #Si se borro de la playlist self.listwidget.takeItem(index) #Elimina del comboBox print( str(self.listwidget.count()) + "<-listWidget playlist->" + str(self.videoVentana.count())) except Exception as err: print(str(err)) #Media functions def play(self): item = self.listwidget.currentRow() self.videoVentana.play(item) #play/pause def stop(self): self.videoVentana.stop() #play/pause #Window functions def elegirPantalla(self): self.seleccionarP = SeleccionPantalla() self.seleccionarP.AsignarVideoWidget(self.videoVentana) self.seleccionarP.resize(400, 300) self.seleccionarP.show() def sigPantalla(self): self.videoVentana.sigPantalla() def antPantalla(self): self.videoVentana.antPantalla() def showPlayer(self): if self.showPlayerButton.text() == self.strButtonShow: self.videoVentana.show() self.showPlayerButton.setText(self.strButtonHide) else: self.videoVentana.hide() self.showPlayerButton.setText(self.strButtonShow) def maximizePlayer(self): self.videoVentana.showFullScreen() self.showPlayerButton.setText(self.strButtonHide) def minimizePlayer(self): self.videoVentana.showNormalS() self.showPlayerButton.setText(self.strButtonHide) def playerVisible(self): return self.showPlayerButton.text() != self.strButtonShow #Events def closeEvent(self, event): buttonReply = QMessageBox.question( self, 'Question', "¿Close? Will close video window too.", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: try: self.server.stop() except Exception as err: print("Error at closing Thread: " + str(err)) self.videoVentana.close() self.close() else: print('No clicked.') event.ignore() return def currentMediaChanged(self, actualMedia): titulo = str(actualMedia.canonicalUrl().fileName()) self.videoVentana.setWindowTitle(titulo) self.lblMediaActual.setText("Media actual: \n" + titulo) def mediaStateChanged(self, state): if self.videoVentana.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.Reproduciendo = True else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.Reproduciendo = False def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) def setPosition(self, position): self.videoVentana.mediaPlayer.setPosition(position) def handleError(self): #self.playButton.setEnabled(False) self.errorLabel.setText("Error: " + self.videoVentana.mediaPlayer.errorString())
class UiMainWindow(object): def __init__(self): super(UiMainWindow, self).__init__() self.setupUi(self) self.numb1 = 0 def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") desktop = QtWidgets.QApplication.desktop() x = (desktop.width() - 801) // 2 y = (desktop.height() - 612) // 2 MainWindow.move(x, y) MainWindow.resize(801, 612) MainWindow.setFixedSize(801, 612) MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) MainWindow.setStyleSheet( 'QListWidget{border:1px solid gray; color:black; }' 'QListWidget::Item{padding-top:-2px; padding-bottom:-1px;}' "QListWidget::Item:hover{background:skyblue;padding-top:0px; padding-bottom:0px; }" #"QListWidget::item:selected{background:lightpink; color:red; }" #"QListWidget::item:selected:!active{active{border-width:0px;background:lightgreen; }" ) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.frame_2 = QtWidgets.QFrame(self.centralwidget) self.frame_2.setGeometry(QtCore.QRect(0, 20, 801, 591)) self.frame_2.setFrameShape(QtWidgets.QFrame.NoFrame) self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_2.setLineWidth(1) self.frame_2.setObjectName("frame_2") self.tabWidget = QtWidgets.QTabWidget(self.frame_2) self.tabWidget.setGeometry(QtCore.QRect(0, 0, 801, 338)) font = QtGui.QFont() font.setFamily("微软雅黑") font.setPointSize(10) font.setBold(False) font.setWeight(0) self.tabWidget.setFont(font) self.tabWidget.setContextMenuPolicy(QtCore.Qt.NoContextMenu) self.tabWidget.setToolTipDuration(0) self.tabWidget.setIconSize(QtCore.QSize(20, 20)) self.tabWidget.setObjectName("tabWidget") # ##设置 通用listwidget # self.liwidget = QListWidget() self.tab_1 = QtWidgets.QWidget() self.tab_1.setMouseTracking(True) self.tab_1.setTabletTracking(True) self.tab_1.setObjectName("tab_1") self.icon1 = QtGui.QIcon() self.icon1.addPixmap(QtGui.QPixmap(cwd + "/ico/fpg.ico"), QtGui.QIcon.Normal, QtGui.QIcon.On) self.icon2 = QtGui.QIcon() self.icon2.addPixmap(QtGui.QPixmap(cwd + "/ico/qpg.ico"), QtGui.QIcon.Normal, QtGui.QIcon.On) self.widget = QtWidgets.QWidget(self.tab_1) self.widget.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget.setObjectName("widget_1") self.pzbt = QtWidgets.QPushButton(self.widget) self.pzbt.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt.setObjectName("pzbt_1") self.uploadbt_1 = QtWidgets.QPushButton(self.widget) self.uploadbt_1.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_1.setObjectName("uploadbt_1") self.label_1 = QtWidgets.QLabel(self.widget) self.label_1.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_1.setText("已下载:") self.label_11 = QtWidgets.QLabel(self.widget) self.label_11.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.listWidget_1 = QListWidget(self.widget) self.listWidget_1.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_1.setObjectName("listWidget_1") ## 数据模型1 self.listWidget_1.addItems([ r'D:\workspace\project\pyqt\biguo2\wantiku\集群.xlsx', r'wantiku\2013年10月《中国法制史》真题.xlsx', r"wantiku\1.xlsx" ]) self.tabWidget.addTab(self.tab_1, "0") self.tab_2 = QtWidgets.QWidget() self.tab_2.setObjectName("tab_2") self.widget_2 = QtWidgets.QWidget(self.tab_2) self.widget_2.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget_2.setObjectName("widget_2") self.pzbt_2 = QtWidgets.QPushButton(self.widget_2) self.pzbt_2.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt_2.setObjectName("pzbt_2") self.uploadbt_2 = QtWidgets.QPushButton(self.widget_2) self.uploadbt_2.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_2.setObjectName("uploadbt_2") self.listWidget_2 = QListWidget(self.widget_2) self.listWidget_2.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_2.setObjectName("listWidget_2") self.label_2 = QtWidgets.QLabel(self.widget_2) self.label_2.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_2.setText("已下载:") self.label_22 = QtWidgets.QLabel(self.widget_2) self.label_22.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.label_22.setText("-----") self.tabWidget.addTab(self.tab_2, "1") self.tab_3 = QtWidgets.QWidget() self.tab_3.setObjectName("tab_3") self.widget_3 = QtWidgets.QWidget(self.tab_3) self.widget_3.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget_3.setObjectName("widget_3") self.pzbt_3 = QtWidgets.QPushButton(self.widget_3) self.pzbt_3.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt_3.setObjectName("pzbt_3") self.uploadbt_3 = QtWidgets.QPushButton(self.widget_3) self.uploadbt_3.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_3.setObjectName("uploadbt_3") self.listWidget_3 = QListWidget(self.widget_3) self.listWidget_3.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_3.setObjectName("listWidget_3") self.label_3 = QtWidgets.QLabel(self.widget_3) self.label_3.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_3.setText("已下载:") self.label_33 = QtWidgets.QLabel(self.widget_3) self.label_33.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.label_33.setText("-----") self.tabWidget.addTab(self.tab_3, "") self.tab_4 = QtWidgets.QWidget() self.tab_4.setObjectName("tab_4") self.widget_4 = QtWidgets.QWidget(self.tab_4) self.widget_4.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget_4.setObjectName("widget_4") self.pzbt_4 = QtWidgets.QPushButton(self.widget_4) self.pzbt_4.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt_4.setObjectName("pzbt_4") self.uploadbt_4 = QtWidgets.QPushButton(self.widget_4) self.uploadbt_4.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_4.setObjectName("uploadbt_4") self.listWidget_4 = QListWidget(self.widget_4) self.listWidget_4.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_4.setObjectName("listWidget_4") self.label_4 = QtWidgets.QLabel(self.widget_4) self.label_4.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_4.setText("已下载:") self.label_44 = QtWidgets.QLabel(self.widget_4) self.label_44.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.label_44.setText("-----") self.tabWidget.addTab(self.tab_4, "") self.tab_5 = QtWidgets.QWidget() self.tab_5.setObjectName("tab_5") self.widget_5 = QtWidgets.QWidget(self.tab_5) self.widget_5.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget_5.setObjectName("widget_5") self.pzbt_5 = QtWidgets.QPushButton(self.widget_5) self.pzbt_5.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt_5.setObjectName("pzbt_5") self.uploadbt_5 = QtWidgets.QPushButton(self.widget_5) self.uploadbt_5.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_5.setObjectName("uploadbt_5") self.listWidget_5 = QListWidget(self.widget_5) self.listWidget_5.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_5.setObjectName("listWidget_5") self.label_5 = QtWidgets.QLabel(self.widget_5) self.label_5.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_5.setText("已下载:") self.label_55 = QtWidgets.QLabel(self.widget_5) self.label_55.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.label_55.setText("-----") self.tabWidget.addTab(self.tab_5, "") self.tab_6 = QtWidgets.QWidget() self.tab_6.setObjectName("tab_6") self.widget_6 = QtWidgets.QWidget(self.tab_6) self.widget_6.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget_6.setObjectName("widget_6") self.pzbt_6 = QtWidgets.QPushButton(self.widget_6) self.pzbt_6.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt_6.setObjectName("pzbt_6") self.uploadbt_6 = QtWidgets.QPushButton(self.widget_6) self.uploadbt_6.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_6.setObjectName("uploadbt_6") self.listWidget_6 = QListWidget(self.widget_6) self.listWidget_6.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_6.setObjectName("listWidget_6") self.label_6 = QtWidgets.QLabel(self.widget_6) self.label_6.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_6.setText("已下载:") self.label_66 = QtWidgets.QLabel(self.widget_6) self.label_66.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.label_66.setText("-----") self.tabWidget.addTab(self.tab_6, "") self.tab_7 = QtWidgets.QWidget() self.tab_7.setObjectName("tab_7") self.widget_7 = QtWidgets.QWidget(self.tab_7) self.widget_7.setGeometry(QtCore.QRect(0, 0, 801, 309)) self.widget_7.setObjectName("widget_7") self.pzbt_7 = QtWidgets.QPushButton(self.widget_7) self.pzbt_7.setGeometry(QtCore.QRect(710, 20, 75, 23)) self.pzbt_7.setObjectName("pzbt_7") self.uploadbt_7 = QtWidgets.QPushButton(self.widget_7) self.uploadbt_7.setGeometry(QtCore.QRect(710, 80, 75, 23)) self.uploadbt_7.setObjectName("uploadbt_7") self.listWidget_7 = QListWidget(self.widget_7) self.listWidget_7.setGeometry(QtCore.QRect(0, 0, 691, 308)) self.listWidget_7.setObjectName("listWidget_7") self.label_7 = QtWidgets.QLabel(self.widget_7) self.label_7.setGeometry(QtCore.QRect(710, 270, 60, 23)) self.label_7.setText("已下载:") self.label_77 = QtWidgets.QLabel(self.widget_7) self.label_77.setGeometry(QtCore.QRect(750, 270, 40, 23)) self.label_77.setText("-----") self.tabWidget.addTab(self.tab_7, "") self.frame = QtWidgets.QFrame(self.frame_2) self.frame.setGeometry(QtCore.QRect(0, 330, 801, 71)) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.checkBox1 = QtWidgets.QCheckBox(self.frame) self.checkBox1.setGeometry(QtCore.QRect(20, 10, 71, 16)) self.checkBox1.setObjectName("checkBox1") self.checkBox3 = QtWidgets.QCheckBox(self.frame) self.checkBox3.setGeometry(QtCore.QRect(170, 10, 71, 16)) self.checkBox3.setObjectName("checkBox3") self.checkBox5 = QtWidgets.QCheckBox(self.frame) self.checkBox5.setGeometry(QtCore.QRect(340, 10, 71, 16)) self.checkBox5.setObjectName("checkBox5") self.checkBox6 = QtWidgets.QCheckBox(self.frame) self.checkBox6.setGeometry(QtCore.QRect(410, 10, 71, 16)) self.checkBox6.setObjectName("checkBox6") self.checkBox4 = QtWidgets.QCheckBox(self.frame) self.checkBox4.setGeometry(QtCore.QRect(250, 10, 71, 16)) self.checkBox4.setObjectName("checkBox4") self.checkBox7 = QtWidgets.QCheckBox(self.frame) self.checkBox7.setGeometry(QtCore.QRect(500, 10, 71, 16)) self.checkBox7.setObjectName("checkBox7") self.checkBox2 = QtWidgets.QCheckBox(self.frame) self.checkBox2.setGeometry(QtCore.QRect(90, 10, 71, 16)) self.checkBox2.setObjectName("checkBox2") self.stbt = QtWidgets.QPushButton(self.frame) self.stbt.setGeometry(QtCore.QRect(710, 40, 75, 23)) self.stbt.setAutoFillBackground(False) self.stbt.setStyleSheet("") self.stbt.setCheckable(True) self.stbt.setAutoDefault(False) self.stbt.setDefault(False) self.stbt.setFlat(False) self.stbt.setObjectName("stbt") self.spsetbt = QtWidgets.QPushButton(self.frame) self.spsetbt.setGeometry(QtCore.QRect(710, 10, 75, 23)) self.spsetbt.setObjectName("spsetbt") self.groupBox = QtWidgets.QGroupBox(self.frame_2) self.groupBox.setGeometry(QtCore.QRect(0, 400, 801, 191)) self.groupBox.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.groupBox.setToolTipDuration(-1) self.groupBox.setFlat(False) self.groupBox.setCheckable(False) self.groupBox.setObjectName("groupBox") self.printtext = QtWidgets.QTextEdit(self.groupBox) self.printtext.setGeometry(QtCore.QRect(0, 10, 801, 181)) self.printtext.setTextInteractionFlags( QtCore.Qt.TextSelectableByKeyboard | QtCore.Qt.TextSelectableByMouse) self.printtext.setObjectName("printtext") self.userlabel = QtWidgets.QLabel(self.centralwidget) self.userlabel.setGeometry(QtCore.QRect(700, 0, 91, 20)) self.userlabel.setScaledContents(False) self.userlabel.setWordWrap(False) self.userlabel.setObjectName("userlabel") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) self.tabWidget.setCurrentIndex(0) self.spsetbt.clicked.connect(MainWindow.set_spider) self.stbt.toggled['bool'].connect(MainWindow.spider_handle) self.uploadbt_1.clicked.connect(MainWindow.upload1) self.uploadbt_2.clicked.connect(MainWindow.upload1) self.uploadbt_3.clicked.connect(MainWindow.upload1) self.uploadbt_4.clicked.connect(MainWindow.upload1) self.uploadbt_5.clicked.connect(MainWindow.upload1) self.uploadbt_6.clicked.connect(MainWindow.upload1) self.uploadbt_7.clicked.connect(MainWindow.upload1) self.checkBox1.toggled.connect(MainWindow.cbedit1) self.checkBox2.toggled.connect(MainWindow.cbedit1) self.checkBox3.toggled.connect(MainWindow.cbedit1) self.checkBox4.toggled.connect(MainWindow.cbedit1) self.checkBox5.toggled.connect(MainWindow.cbedit1) self.checkBox6.toggled.connect(MainWindow.cbedit1) self.checkBox7.toggled.connect(MainWindow.cbedit1) #设置右键菜单 self.listWidget_1.setContextMenuPolicy(3) #self.listWidget_1.itemClicked.connect(self.rk_menu) self.listWidget_1.itemDoubleClicked.connect(MainWindow.file_open) self.listWidget_1.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_2.setContextMenuPolicy(3) self.listWidget_2.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_2.doubleClicked.connect(MainWindow.file_open) self.listWidget_3.setContextMenuPolicy(3) self.listWidget_3.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_3.doubleClicked.connect(MainWindow.file_open) self.listWidget_4.setContextMenuPolicy(3) self.listWidget_4.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_4.doubleClicked.connect(MainWindow.file_open) self.listWidget_5.setContextMenuPolicy(3) self.listWidget_5.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_5.doubleClicked.connect(MainWindow.file_open) self.listWidget_6.setContextMenuPolicy(3) self.listWidget_6.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_6.doubleClicked.connect(MainWindow.file_open) self.listWidget_7.setContextMenuPolicy(3) self.listWidget_7.customContextMenuRequested[QtCore.QPoint].connect( self.rk_menu) self.listWidget_7.doubleClicked.connect(MainWindow.file_open) # 列表设置字体 self.listWidget_1.setFont(font) self.listWidget_2.setFont(font) self.listWidget_3.setFont(font) self.listWidget_4.setFont(font) self.listWidget_5.setFont(font) self.listWidget_6.setFont(font) self.listWidget_7.setFont(font) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "笔果数据管理")) MainWindow.setWindowIcon(QtGui.QIcon('./ico/cm02.ico')) # self.tabWidget.setTabIcon(0,self.icon1) # self.tabWidget.setTabIcon(1, self.icon1) # self.tabWidget.setTabIcon(2, self.icon1) # self.tabWidget.setTabIcon(3, self.icon1) # self.tabWidget.setTabIcon(4, self.icon1) # self.tabWidget.setTabIcon(5, self.icon1) # self.tabWidget.setTabIcon(6, self.icon1) self.pzbt.setText(_translate("MainWindow", "配置修改")) self.uploadbt_1.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_1), _translate("MainWindow", "万题库")) self.pzbt_2.setText(_translate("MainWindow", "配置修改")) self.uploadbt_2.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "自考真题库")) self.pzbt_3.setText(_translate("MainWindow", "配置修改")) self.uploadbt_3.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "自考友")) self.pzbt_4.setText(_translate("MainWindow", "配置修改")) self.uploadbt_4.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "答题易")) self.pzbt_5.setText(_translate("MainWindow", "配置修改")) self.uploadbt_5.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "自考5网站")) self.pzbt_6.setText(_translate("MainWindow", "配置修改")) self.uploadbt_6.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_6), _translate("MainWindow", "百度文库")) self.pzbt_7.setText(_translate("MainWindow", "配置修改")) self.uploadbt_7.setText(_translate("MainWindow", "开始上传")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_7), _translate("MainWindow", "自考365app")) self.checkBox1.setText(_translate("MainWindow", "万题库")) self.checkBox3.setText(_translate("MainWindow", "自考友")) self.checkBox5.setText(_translate("MainWindow", "自考5")) self.checkBox6.setText(_translate("MainWindow", "百度文库")) self.checkBox4.setText(_translate("MainWindow", "答题易")) self.checkBox7.setText(_translate("MainWindow", "365app")) self.checkBox2.setText(_translate("MainWindow", "真题库")) self.stbt.setText(_translate("MainWindow", "开始")) self.spsetbt.setText(_translate("MainWindow", "爬虫设置")) self.groupBox.setTitle(_translate("MainWindow", "调试信息")) self.userlabel.setText(_translate("MainWindow", "User")) def set_spider(self): pass def file_open(self, e): print("doublec") # excelapp = client.Dispatch("Excel.Application") # excelapp.Visible = -1 # excelapp.Workbooks.Open("D:\workspace\project\pyqt\\biguo2\wantiku\\1.xlsx") # QtCore.QModelIndex # self.sender().setStyleSheet("QListWidget::item:selected{background:lightgray; color:green; }") try: #self.sender().item(e.row()).setForeground(QtGui.QColor('green')) e.setForeground(QtGui.QColor('green')) except Exception as re: print(re) def rk_menu(self, e): # 弹出右键菜单 try: if not self.listWidget_1.itemAt(e.x(), e.y()): return # print('弹出菜单',e.x(),e.y(),self.sender()) a = self.sender() popMenu = QtWidgets.QMenu(self.listWidget_1) popMenu.addAction(Qt.QAction('删除', self)) qp = Qt.QPoint(Qt.QCursor.pos().x() + 1, Qt.QCursor.pos().y()) try: # popMenu.triggered.connect(lambda: self.rm(a,e.x(),e.y())) popMenu.triggered.connect(partial(self.rm, a, e)) # 绑定删除按钮的方法,用 partial 函数传递额外参数,还可以用匿名函数,但是匿名函数不带默认参数 except Exception as e: print(e) popMenu.exec_(qp) except Exception as e: print(e) def rm(self, liw, pos, e): # 右键菜单删除功能 # print(liw, pos, e) try: if e.text() == "删除": item = liw.itemAt(pos.x(), pos.y()) print("删除第%d行:%s" % (liw.row(item) + 1, item.text())) liw.removeItemWidget(liw.takeItem(liw.row(item))) self.flushnum() #liw.updateEditorData() #print(e.text(),e.senderSignalIndex(),self.sender()) #QtWidgets.QMenu.at #QtWidgets.QAction. except Exception as e: print(e) def flushnum(self): # 实时显示列表中的试卷数目。*** self.label_11.setText(str(len(self.listWidget_1))) self.label_22.setText(str(len(self.listWidget_2))) self.label_33.setText(str(len(self.listWidget_3))) self.label_44.setText(str(len(self.listWidget_4))) self.label_55.setText(str(len(self.listWidget_5))) self.label_66.setText(str(len(self.listWidget_6))) self.label_77.setText(str(len(self.listWidget_7)))