def setMasteryTree(self, tree, imageList): yPos = 3 xPos = 7 column = 1 for element in imageList.keys(): if not isinstance(element, str): mastery = QLabel(tree) mastery.setScaledContents(True) mastery.move(xPos, yPos) mastery.resize(30, 30) mastery.setPixmap(imageList[element]) mastery_rank = QLabel(tree) mastery_rank.move(xPos + 31, yPos + 15) mastery_rank.resize(15, 15) mastery_rank.setAlignment(Qt.AlignCenter) mastery_rank.setText('0') mastery_rank.setStyleSheet( "QLabel {color:white; border-style: outset; border-width: 2px; border-color: black}" ) self.mastery_rank_labels[element] = mastery_rank if column < 3: xPos += 56 column += 1 else: column = 1 xPos = 7 yPos += 35
class ChampionsWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.widgetLayout = QVBoxLayout() self.setLayout(self.widgetLayout) self.container = QLabel() self.container.setStyleSheet("QLabel {background-color: black}") self.championPanel = QScrollArea() self.championPanel.resize(620, 240) self.championPanel.setWidget(self.container) self.widgetLayout.addWidget(self.championPanel) def showStats(self, values, championIconList): yPos = 5 self.container.resize(680, (len(values) * 55) + yPos) for x in values: temp = ChampionTab(self.container) temp.setIcon(championIconList[x['name']]) temp.setName(x['name']) temp.setNumOfSessions(x['sessions']) temp.setWinRatio(x['winRate']) temp.setKDA(x['kills'], x['deaths'], x['assists']) temp.setCS(x['cs']) temp.move(5, yPos) yPos += 55
def show(cursor, pos=None, num_lines=6): """Displays a tooltip showing part of the cursor's Document. If the cursor has a selection, those blocks are displayed. Otherwise, num_lines lines are displayed. If pos is not given, the global mouse position is used. """ block = cursor.document().findBlock(cursor.selectionStart()) c2 = QTextCursor(block) if cursor.hasSelection(): c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor) c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) else: c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines) data = textformats.formatData('editor') doc = QTextDocument() font = QFont(data.font) font.setPointSizeF(font.pointSizeF() * .8) doc.setDefaultFont(font) doc.setPlainText(c2.selection().toPlainText()) if metainfo.info(cursor.document()).highlighting: highlighter.highlight(doc, state=tokeniter.state(block)) size = doc.size().toSize() + QSize(8, -4) pix = QPixmap(size) pix.fill(data.baseColors['background']) doc.drawContents(QPainter(pix)) label = QLabel() label.setPixmap(pix) label.setStyleSheet("QLabel { border: 1px solid #777; }") label.resize(size) widgets.customtooltip.show(label, pos)
class App(QWidget): def __init__(self): super(App, self).__init__() self.title = 'PyQt4 IR Data' self.left = 0 self.top = 0 self.width = 640 self.height = 480 self.initUI() @pyqtSlot(QImage) def setImage(self, image): self.label.setPixmap(QPixmap.fromImage(image)) def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.resize(640, 480) # create a label # print('Create Label') self.label = QLabel(self) #self.label.move(280, 120) btn = QPushButton('Store Data', self) btn.clicked.connect(storeData) self.label.resize(640, 480) th = Thread(self) th.changePixmap.connect(self.setImage) th.start()
class App(QWidget): def __init__(self): super(App,self).__init__() self.title = 'PyQt4 Video' self.left = 100 self.top = 100 self.width = 640 self.height = 480 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.resize(800, 600) # create a label self.label = QLabel(self) self.label.move(0, 0) self.label.resize(640, 480) th = Thread(self) th.changePixmap.connect(lambda p: self.setPixMap(p)) th.start() def setPixMap(self, p): p = QPixmap.fromImage(p) p = p.scaled(640, 480, Qt.KeepAspectRatio) self.label.setPixmap(p)
def data(self, index, role): # Check if 'gorup' node requested if not index.parent().isValid(): # Yep, return title and some other group props if role == CCM.InheritanceDepth: return self.GROUP_POSITION # ATTENTION TODO NOTE # Due this BUG (https://bugs.kde.org/show_bug.cgi?id=247896) # we can't use CCM.GroupRole, so hardcoded value 47 is here! if role == 47: return Qt.DisplayRole if role == Qt.DisplayRole: return self.TITLE_AUTOCOMPLETION # Return 'invalid' for other roles return None # Leaf item props are requested item = self.resultList[index.row()] if role == CCM.IsExpandable: return bool(item['details']) elif role == CCM.ExpandingWidget: w = QLabel(item['details']) w.setWordWrap(True) w.setAlignment(Qt.AlignLeft | Qt.AlignTop) w.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) w.resize(w.minimumSizeHint()) item['expandable_widget'] = w return item['expandable_widget'] if index.column() == CCM.Name: if role == Qt.DisplayRole: return item['text'] if role == CCM.CompletionRole: return CCM.GlobalScope if role == CCM.ScopeIndex: return -1 # Return 'invalid' for other roles pass elif index.column() == CCM.Icon: if role == Qt.DecorationRole: # Show icon only if specified by a completer! if 'icon' in item and item['icon'] is not None: return KIcon(item['icon']).pixmap(QSize(16, 16)) pass elif index.column() == CCM.Arguments: item_args = item.get('args', None) if role == Qt.DisplayRole and item_args: return item_args elif index.column() == CCM.Postfix: item_description = item.get('description', None) if role == Qt.DisplayRole and item_description: return item_description elif index.column() == CCM.Prefix: item_prefix = item.get('prefix', None) if role == Qt.DisplayRole and item_prefix: return item_prefix return None
def addWidgets(self): opener = QLabel(self) self.pixmap_open = QPixmap(asset('png', 'triangle-open.png')) self.pixmap_closed = QPixmap(asset('png', 'triangle-closed.png')) opener.setPixmap(self.pixmap_open) opener.resize(opener.pixmap().size()) self.opener = opener self.setIndent(opener.width() + 12) self.setMargin(2)
def __init__(self): #self.setWindowIcon(QIcon("icon.png")) QMainWindow.__init__(self) myappid = u'ds.daishin.cbpProject Linker.10' # arbitrary string ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) #윈도우 특성 설정 self.setWindowTitle('CBP Project Linker') # 윈도우 타이틀 지정 선언문 self.setWindowIcon(QIcon("cbplinkericon.png")) self.setGeometry(600, 600, 450, 200) # 윈도우 위치/크기 설정 문법 #self.statusBar().showMessage('ready') idtext = QLabel(self) idtext.text() #idtext.resize(15,15) idtext.setText("Project Path : ") idtext.move(35, 20) pwtext = QLabel(self) pwtext.text() #idtext.resize(15,10) pwtext.setText("Link Impl Path : ") pwtext.move(35, 50) mdtext = QLabel(self) mdtext.text() mdtext.resize(300, 20) mdtext.setText("CBP Project Linker. Made ByJJuN. v1.0") mdtext.move(110, 180) #Project Text Box self.projectbox = QLineEdit(self) self.projectbox.setText("C:\GIT_AREA\cybos_psl") self.projectbox.resize(300, 25) self.projectbox.move(135, 20) #Link Project 용 Text Box self.linkimplbox = QLineEdit(self) self.linkimplbox.setText("C:\GIT_AREA\cybos_cii\CIIImpl") self.linkimplbox.resize(300, 25) self.linkimplbox.move(135, 50) # 버튼1 추가 btn1 = QPushButton('MAKE Link', self) #btn1.resize(btn1.sizeHint()) btn1.move(160, 90) btn1.clicked.connect(self.btnClicked) # 종료 버튼 추가 btnQuit = QPushButton('EXIT', self) btnQuit.move(160, 130) # 종료창 위치/크기 설정 btnQuit.clicked.connect(QCoreApplication.instance().quit) #윈도우 화면 출력 self.show()
def addWidgets(self): opener = QLabel(self) self.pixmap_open = QPixmap(asset('png', 'triangle-open.png')) self.pixmap_closed = QPixmap(asset('png', 'triangle-closed.png')) opener.setPixmap(self.pixmap_open) opener.resize(opener.pixmap().size()) self.opener = opener self.setIndent(opener.width() + 12) self.setMargin(2)
def create_label(self, name, pos_x, pos_y): """ Se define un metodo para la creacion de los labels de la interfaz grafica :param name: Nombre del label :param pos_x: Posicion horizontal :param pos_y: Posicion vertical """ label = QLabel(name, self) label.move(pos_x, pos_y) label.resize(label.minimumSizeHint())
def __init__(self, *args, **kwargs): super(SearchEditor, self).__init__(*args, **kwargs) self.setPlaceholderText('Enter a search term') icon = QLabel(self) pixmap = QPixmap(asset('png', 'search.png')) icon.setPixmap(pixmap) icon.resize(pixmap.size()) self.searchicn = icon self.clearbtn = ClearButton(self) self.setTextMargins(30, 0, 30, 0) self.setFocusPolicy(Qt.NoFocus) self.current_vault = None self.queries = {}
def _welcome_window(self): widget = QLabel(self) pm = QPixmap(':icons/glue_welcome.png') pm = pm.scaledToHeight(400, mode=Qt.SmoothTransformation) widget.setPixmap(pm) widget.show() widget.resize(pm.size()) sub = self._add_to_current_tab(widget, label='Getting Started') def do_close(win): sub.close() self.current_tab.subWindowActivated.connect(do_close)
def __init__(self, *args, **kwargs): super(SearchEditor, self).__init__(*args, **kwargs) self.setPlaceholderText('Enter a search term') icon = QLabel(self) pixmap = QPixmap(asset('png', 'search.png')) icon.setPixmap(pixmap) icon.resize(pixmap.size()) self.searchicn = icon self.clearbtn = ClearButton(self) self.setTextMargins(30, 0, 30, 0) self.setFocusPolicy(Qt.NoFocus) self.current_vault = None self.queries = {}
class example1(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setGeometry(0, 0, 400, 600) self.new_label = customQLabel("LABEL!", self, 50, 100, 100, 100, "color: red;") self.bg = QLabel(self) self.bg.setStyleSheet("background-color: rgb(255,123,100);") self.bg.setFixedSize(400, 600) # self.hello_label = QLabel("Hello NSL!!!", self) # self.hello_label.setStyleSheet("font-size: 50px;") # self.hello_label.setFixedSize(300, 50) # self.hello_label.move(250, 250) # self.hello_label.mousePressEvent = self.print_function self.bg_img = QPixmap('img/stars2.jpg') self.bg.setPixmap(self.bg_img) self.bg.resize(400, 600) self.textfield = QLineEdit("type your name..", self) self.textfield.move(20, 30) self.textfield.setFixedWidth(250) self.button = QPushButton("Save Name", self) self.button.move(300, 30) self.button.clicked.connect(self.print_name) QShortcut(QKeySequence("Return"), self.textfield, self.print_name) # self.timer = QLabel("", self) # self.timer.move(90, 120) # self.timer.setFixedSize(220, 60) # self.timer.setStyleSheet("color: white; border: 1px Solid White; font-size: 40px") # self.timer.setAlignment(Qt.AlignCenter) self.timer = customQLabel("", self, 90, 120, 220, 60 "color: white; border: 1px Solid White; font-size: 40px") self.show() self.raise_() def print_function(self, event): print "Pressed Hello NSL Button" def print_name(self): print self.textfield.text()
class RuneWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.page_name = QLabel(self) self.page_name.setMaximumHeight(30) self.field = QTextEdit(self) self.field.setReadOnly(True) self.field.setFontPointSize(14) self.field.move(0, 30) self.runesID = {} self.runesDescription = {} self.rune_name = {} def setSize(self, x, y): self.page_name.resize(x, 30) self.field.resize(x, y - 30) def setName(self, name): self.page_name.setText(name) def addRune(self, rune, description, runeName): if not (rune in self.runesID): self.runesID[rune] = 1 self.runesDescription[rune] = description self.rune_name[rune] = runeName.split(' ')[1] else: self.runesID[rune] += 1 def showRunes(self): for x in self.runesID.keys(): descript = self.runesDescription[x].replace('+', '').split(' ') stat = float(descript[0].replace('%', '')) del descript[0] info = ' '.join(descript).split('(')[0] self.field.insertPlainText("+" + str(self.runesID[x] * stat) + " " + info + " (" + self.rune_name[x] + ")" + "\n")
def show(cursor, pos=None, num_lines=6): """Displays a tooltip showing part of the cursor's Document. If the cursor has a selection, those blocks are displayed. Otherwise, num_lines lines are displayed. If pos is not given, the global mouse position is used. """ block = cursor.document().findBlock(cursor.selectionStart()) c2 = QTextCursor(block) if cursor.hasSelection(): c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor) c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) else: c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines) data = textformats.formatData('editor') doc = QTextDocument() font = QFont(data.font) font.setPointSizeF(font.pointSizeF() * .8) doc.setDefaultFont(font) doc.setPlainText(c2.selection().toPlainText()) if metainfo.info(cursor.document()).highlighting: highlighter.highlight(doc, state=tokeniter.state(block)) size = doc.size().toSize() + QSize(8, -4) pix = QPixmap(size) pix.fill(data.baseColors['background']) doc.drawContents(QPainter(pix)) label = QLabel() label.setPixmap(pix) label.setStyleSheet("QLabel { border: 1px solid #777; }") label.resize(size) widgets.customtooltip.show(label, pos)
class PipedImagerPQ(QMainWindow): ''' A PyQt graphics viewer that receives images and commands through a pipe. A command is a dictionary with string keys. For example, { "action":"save", "filename":"ferret.png", "fileformat":"png" } The command { "action":"exit" } will shutdown the viewer. ''' def __init__(self, cmndpipe, rspdpipe): ''' Create a PyQt viewer which reads commands from the Pipe cmndpipe and writes responses back to rspdpipe. ''' super(PipedImagerPQ, self).__init__() self.__cmndpipe = cmndpipe self.__rspdpipe = rspdpipe # ignore Ctrl-C signal.signal(signal.SIGINT, signal.SIG_IGN) # unmodified image for creating the scene self.__sceneimage = None # bytearray of data for the above image self.__scenedata = None # flag set if in the process of reading image data from commands self.__loadingimage = False # width and height of the unmodified scene image # when the image is defined # initialize the width and height to values that will create # a viewer (mainWindow) of the right size self.__scenewidth = int(10.8 * self.physicalDpiX()) self.__sceneheight = int(8.8 * self.physicalDpiY()) # by default pay attention to any alpha channel values in colors self.__noalpha = False # initial default color for the background (opaque white) self.__lastclearcolor = QColor(0xFFFFFF) self.__lastclearcolor.setAlpha(0xFF) # scaling factor for creating the displayed scene self.__scalefactor = 1.0 # automatically adjust the scaling factor to fit the window frame? self.__autoscale = True # minimum label width and height (for minimum scaling factor) # and minimum image width and height (for error checking) self.__minsize = 128 # create the label, that will serve as the canvas, in a scrolled area self.__scrollarea = QScrollArea(self) self.__label = QLabel(self.__scrollarea) # set the initial label size and other values for the scrolled area self.__label.setMinimumSize(self.__scenewidth, self.__sceneheight) self.__label.resize(self.__scenewidth, self.__sceneheight) # setup the scrolled area self.__scrollarea.setWidget(self.__label) self.__scrollarea.setBackgroundRole(QPalette.Dark) self.setCentralWidget(self.__scrollarea) # default file name and format for saving the image self.__lastfilename = "ferret.png" self.__lastformat = "png" # control whether the window will be destroyed or hidden self.__shuttingdown = False # command helper object self.__helper = CmndHelperPQ(self) # create the menubar self.__scaleact = QAction( self.tr("&Scale"), self, shortcut=self.tr("Ctrl+S"), statusTip=self.tr( "Scale the image (canvas and image change size)"), triggered=self.inquireSceneScale) self.__saveact = QAction(self.tr("Save &As..."), self, shortcut=self.tr("Ctrl+A"), statusTip=self.tr("Save the image to file"), triggered=self.inquireSaveFilename) self.__redrawact = QAction( self.tr("&Redraw"), self, shortcut=self.tr("Ctrl+R"), statusTip=self.tr("Clear and redraw the image"), triggered=self.redrawScene) self.__aboutact = QAction( self.tr("&About"), self, statusTip=self.tr("Show information about this viewer"), triggered=self.aboutMsg) self.__aboutqtact = QAction( self.tr("About &Qt"), self, statusTip=self.tr("Show information about the Qt library"), triggered=self.aboutQtMsg) self.createMenus() # set the initial size of the viewer self.__framedelta = 4 mwwidth = self.__scenewidth + self.__framedelta mwheight = self.__sceneheight + self.__framedelta \ + self.menuBar().height() \ + self.statusBar().height() self.resize(mwwidth, mwheight) # check the command queue any time there are no window events to deal with self.__timer = QTimer(self) self.__timer.timeout.connect(self.checkCommandPipe) self.__timer.setInterval(0) self.__timer.start() def createMenus(self): ''' Create the menu items for the viewer using the previously created actions. ''' menuBar = self.menuBar() sceneMenu = menuBar.addMenu(menuBar.tr("&Image")) sceneMenu.addAction(self.__scaleact) sceneMenu.addAction(self.__saveact) sceneMenu.addAction(self.__redrawact) helpMenu = menuBar.addMenu(menuBar.tr("&Help")) helpMenu.addAction(self.__aboutact) helpMenu.addAction(self.__aboutqtact) def resizeEvent(self, event): ''' Monitor resizing in case auto-scaling of the image is selected. ''' if self.__autoscale: if self.autoScaleScene(): # continue with the window resize event.accept() else: # another resize coming in, so ignore this one event.ignore() else: # continue with the window resize event.accept() def closeEvent(self, event): ''' Override so will just minimize if not shutting down ''' # If shutting down or minimized (escape hatch), # go ahead and close/exit if self.__shuttingdown or self.isMinimized(): self.__timer.stop() event.accept() return # Otherwise just minimize the window event.ignore() self.showMinimized() def exitViewer(self): ''' Close and exit the viewer. ''' self.__shuttingdown = True self.close() def aboutMsg(self): QMessageBox.about(self, self.tr("About PipedImagerPQ"), self.tr("\n" \ "PipedImagerPQ is a graphics viewer application that " \ "receives its displayed image and commands primarily from " \ "another application through a pipe. A limited number " \ "of commands are provided by the viewer itself to allow " \ "saving and some manipulation of the displayed image. " \ "The controlling application, however, may be unaware " \ "of these modifications made to the image. " \ "\n\n" \ "'Closing' this window (the window frame 'X' button) " \ "actually only minimizes this viewer as PyFerret expects " \ "it to exist until PyFerret closes it. Selecting the " \ "close menu option from the *minimized* window (using " \ "a right mouse click) will actually close (exit) the " \ "viewer if PyFerret exited and left it up. " \ "\n\n" \ "PipedImagerPQ was developed by the Thermal Modeling and Analysis " \ "Project (TMAP) of the National Oceanographic and Atmospheric " \ "Administration's (NOAA) Pacific Marine Environmental Lab (PMEL). ")) def aboutQtMsg(self): QMessageBox.aboutQt(self, self.tr("About Qt")) def ignoreAlpha(self): ''' Return whether the alpha channel in colors should always be ignored. ''' return self.__noalpha def updateScene(self): ''' Clear the displayed scene using self.__lastclearcolor, then draw the scaled current image. ''' # get the scaled scene size labelwidth = int(self.__scalefactor * self.__scenewidth + 0.5) labelheight = int(self.__scalefactor * self.__sceneheight + 0.5) # Create the new pixmap for the label to display newpixmap = QPixmap(labelwidth, labelheight) newpixmap.fill(self.__lastclearcolor) if self.__sceneimage != None: # Draw the scaled image to the pixmap mypainter = QPainter(newpixmap) trgrect = QRectF(0.0, 0.0, float(labelwidth), float(labelheight)) srcrect = QRectF(0.0, 0.0, float(self.__scenewidth), float(self.__sceneheight)) mypainter.drawImage(trgrect, self.__sceneimage, srcrect, Qt.AutoColor) mypainter.end() # Assign the new pixmap to the label self.__label.setPixmap(newpixmap) # set the label size and values # so the scrollarea knows of the new size self.__label.setMinimumSize(labelwidth, labelheight) self.__label.resize(labelwidth, labelheight) # update the label from the new pixmap self.__label.update() def clearScene(self, bkgcolor=None): ''' Deletes the scene image and fills the label with bkgcolor. If bkgcolor is None or an invalid color, the color used is the one used from the last clearScene or redrawScene call with a valid color (or opaque white if a color has never been specified). ''' # get the color to use for clearing (the background color) if bkgcolor: if bkgcolor.isValid(): self.__lastclearcolor = bkgcolor # Remove the image and its bytearray self.__sceneimage = None self.__scenedata = None # Update the scene label using the current clearing color and image self.updateScene() def redrawScene(self, bkgcolor=None): ''' Clear and redraw the displayed scene. ''' # get the background color if bkgcolor: if bkgcolor.isValid(): self.__lastclearcolor = bkgcolor # Update the scene label using the current clearing color and image QApplication.setOverrideCursor(Qt.WaitCursor) self.statusBar().showMessage(self.tr("Redrawing image")) try: self.updateScene() finally: self.statusBar().clearMessage() QApplication.restoreOverrideCursor() def resizeScene(self, width, height): ''' Resize the scene to the given width and height in units of pixels. If the size changes, this deletes the current image and clear the displayed scene. ''' newwidth = int(width + 0.5) if newwidth < self.__minsize: newwidth = self.__minsize newheight = int(height + 0.5) if newheight < self.__minsize: newheight = self.__minsize if (newwidth != self.__scenewidth) or (newheight != self.__sceneheight): # set the new size for the empty scene self.__scenewidth = newwidth self.__sceneheight = newheight # If auto-scaling, set scaling factor to 1.0 and resize the window if self.__autoscale: self.__scalefactor = 1.0 barheights = self.menuBar().height() + self.statusBar().height( ) self.resize(newwidth + self.__framedelta, newheight + self.__framedelta + barheights) # clear the scene with the last clearing color self.clearScene(None) def loadNewSceneImage(self, imageinfo): ''' Create a new scene image from the information given in this and subsequent dictionaries imageinfo. The image is created from multiple calls to this function since there is a limit on the size of a single object passed through a pipe. The first imageinfo dictionary given when creating an image must define the following key and value pairs: "width": width of the image in pixels "height": height of the image in pixels "stride": number of bytes in one line of the image in the bytearray The scene image data is initialized to all zero (transparent) at this time. This initialization call must be followed by (multiple) calls to this method with imageinfo dictionaries defining the key and value pairs: "blocknum": data block number (1, 2, ... numblocks) "numblocks": total number of image data blocks "startindex": index in the bytearray of image data where this block of image data starts "blockdata": this block of data as a bytearray On receipt of the last block of data (blocknum == numblocks) the scene image will be created and the scene will be updated. Raises: KeyError - if one of the above keys is not given ValueError - if a value for a key is not valid ''' if not self.__loadingimage: # prepare for a new image data from subsequent calls # get dimensions of the new image myimgwidth = int(imageinfo["width"]) myimgheight = int(imageinfo["height"]) myimgstride = int(imageinfo["stride"]) if (myimgwidth < self.__minsize) or (myimgheight < self.__minsize): raise ValueError( "image width and height cannot be less than %s" % str(self.__minsize)) # Newer PyQt versions allow separate specification of the stride if myimgstride != 4 * myimgwidth: raise ValueError( "image stride is not four times the image width") # create the bytearray to contain the new scene data # automatically initialized to zero self.__scenedata = bytearray(myimgstride * myimgheight) self.__scenewidth = myimgwidth self.__sceneheight = myimgheight # set the flag for subsequent calls to this method self.__loadingimage = True # change the cursor to warn the user this may take some time QApplication.setOverrideCursor(Qt.WaitCursor) # put up an appropriate status message self.statusBar().showMessage(self.tr("Loading new image")) return # loading an image; add the next block of data myblocknum = int(imageinfo["blocknum"]) mynumblocks = int(imageinfo["numblocks"]) mystartindex = int(imageinfo["startindex"]) myblockdata = imageinfo["blockdata"] if (myblocknum < 1) or (myblocknum > mynumblocks): self.statusBar().clearMessage() QApplication.restoreOverrideCursor() raise ValueError( "invalid image data block number or number of blocks") if (mystartindex < 0) or (mystartindex >= len(self.__scenedata)): self.statusBar().clearMessage() QApplication.restoreOverrideCursor() raise ValueError("invalid start index for an image data block") myblocksize = len(myblockdata) myendindex = mystartindex + myblocksize if (myblocksize < 1) or (myendindex > len(self.__scenedata)): self.statusBar().clearMessage() QApplication.restoreOverrideCursor() raise ValueError("invalid length of an image data block") # update the status message to show progress self.statusBar().showMessage( self.tr("Loading new image (block %1 of %2)") \ .arg(str(myblocknum)).arg(str(mynumblocks)) ) # assign the data self.__scenedata[mystartindex:myendindex] = myblockdata # if this is the last block of data, create and display the scene image if myblocknum == mynumblocks: self.__loadingimage = False self.statusBar().showMessage(self.tr("Creating new image")) try: self.__sceneimage = QImage(self.__scenedata, self.__scenewidth, self.__sceneheight, QImage.Format_ARGB32_Premultiplied) self.statusBar().showMessage(self.tr("Drawing new image")) # update the displayed scene in the label self.updateScene() finally: # clear the status message self.statusBar().clearMessage() # restore the cursor back to normal QApplication.restoreOverrideCursor() def inquireSceneScale(self): ''' Prompt the user for the desired scaling factor for the scene. ''' labelwidth = int(self.__scenewidth * self.__scalefactor + 0.5) labelheight = int(self.__sceneheight * self.__scalefactor + 0.5) scaledlg = ScaleDialogPQ(self.__scalefactor, labelwidth, labelheight, self.__minsize, self.__minsize, self.__autoscale, self) if scaledlg.exec_(): (newscale, autoscale, okay) = scaledlg.getValues() if okay: if autoscale: self.__autoscale = True self.autoScaleScene() else: self.__autoscale = False self.scaleScene(newscale, False) def autoScaleScene(self): ''' Selects a scaling factor that maximizes the scene within the window frame without requiring scroll bars. Intended to be called when the window size is changed by the user and auto-scaling is turn on. Returns: True if scaling of this scene is done (no window resize) False if the a window resize command was issued ''' barheights = self.menuBar().height() + self.statusBar().height() # get the size for the central widget cwheight = self.height() - barheights - self.__framedelta heightsf = float(cwheight) / float(self.__sceneheight) cwwidth = self.width() - self.__framedelta widthsf = float(cwwidth) / float(self.__scenewidth) if heightsf < widthsf: factor = heightsf else: factor = widthsf newcwheight = int(factor * self.__sceneheight + 0.5) newcwwidth = int(factor * self.__scenewidth + 0.5) # if the window does not have the correct aspect ratio, resize it so # it will; this will generate another call to this method. Otherwise, # scale the scene and be done. if self.isMaximized() or \ ( (abs(cwheight - newcwheight) <= self.__framedelta) and \ (abs(cwwidth - newcwwidth) <= self.__framedelta) ): self.scaleScene(factor, False) return True else: self.resize(newcwwidth + self.__framedelta, newcwheight + self.__framedelta + barheights) return False def scaleScene(self, factor, resizewin): ''' Scales both the horizontal and vertical directions by factor. Scaling factors are not accumulative. So if the scene was already scaled, that scaling is "removed" before this scaling factor is applied. If resizewin is True, the main window is resized to accommodate this new scaled scene size. If factor is zero, just switch to auto-scaling at the current window size. If factor is negative, rescale using the absolute value (possibly resizing the window) then switch to auto-scaling. ''' fltfactor = float(factor) if fltfactor != 0.0: if resizewin: # from command - turn off autoscaling for the following # then turn back on if appropriate self.__autoscale = False newfactor = abs(fltfactor) newlabwidth = int(newfactor * self.__scenewidth + 0.5) newlabheight = int(newfactor * self.__sceneheight + 0.5) if (newlabwidth < self.__minsize) or (newlabheight < self.__minsize): # Set to minimum size if self.__scenewidth <= self.__sceneheight: newfactor = float(self.__minsize) / float( self.__scenewidth) else: newfactor = float(self.__minsize) / float( self.__sceneheight) newlabwidth = int(newfactor * self.__scenewidth + 0.5) newlabheight = int(newfactor * self.__sceneheight + 0.5) oldlabwidth = int(self.__scalefactor * self.__scenewidth + 0.5) oldlabheight = int(self.__scalefactor * self.__sceneheight + 0.5) if (newlabwidth != oldlabwidth) or (newlabheight != oldlabheight): # Set the new scaling factor self.__scalefactor = newfactor # Update the scene label using the current clearing color and image QApplication.setOverrideCursor(Qt.WaitCursor) self.statusBar().showMessage(self.tr("Scaling image")) try: self.updateScene() finally: self.statusBar().clearMessage() QApplication.restoreOverrideCursor() if resizewin: # resize the main window (if possible) barheights = self.menuBar().height() + self.statusBar().height( ) mwheight = newlabheight + barheights + self.__framedelta mwwidth = newlabwidth + self.__framedelta # Do not exceed the available real estate on the screen. # If autoscaling is in effect, the resize will trigger # any required adjustments. scrnrect = QApplication.desktop().availableGeometry() if mwwidth > 0.95 * scrnrect.width(): mwwidth = int(0.9 * scrnrect.width() + 0.5) if mwheight > 0.95 * scrnrect.height(): mwheight = int(0.9 * scrnrect.height() + 0.5) self.resize(mwwidth, mwheight) if fltfactor <= 0.0: # From command - turn on autoscaling self.__autoscale = True self.autoScaleScene() def inquireSaveFilename(self): ''' Prompt the user for the name of the file into which to save the scene. The file format will be determined from the filename extension. ''' formattypes = [ ("png", self.tr("PNG - Portable Networks Graphics (*.png)")), ("jpeg", self. tr("JPEG - Joint Photographic Experts Group (*.jpeg *.jpg *.jpe)") ), ("tiff", self.tr("TIFF - Tagged Image File Format (*.tiff *.tif)")), ("bmp", self.tr("BMP - Windows Bitmap (*.bmp)")), ("ppm", self.tr("PPM - Portable Pixmap (*.ppm)")), ("xpm", self.tr("XPM - X11 Pixmap (*.xpm)")), ("xbm", self.tr("XBM - X11 Bitmap (*.xbm)")), ] # tr returns QStrings so the following does not work # filters = ";;".join( [ t[1] for t in formattypes ] ) filters = QString(formattypes[0][1]) for typePair in formattypes[1:]: filters.append(";;") filters.append(typePair[1]) # getSaveFileNameAndFilter does not want to accept a default filter # for (fmt, fmtQName) in formattypes: # if self.__lastformat == fmt: # dfltfilter = fmtQName # break # else: # dfltfilter = formattypes[0][1] # getSaveFileNameAndFilter is a PyQt (but not Qt?) method (fileName, fileFilter) = QFileDialog.getSaveFileNameAndFilter( self, self.tr("Save the current image as "), self.__lastfilename, filters) if fileName: for (fmt, fmtQName) in formattypes: if fmtQName.compare(fileFilter) == 0: fileFormat = fmt break else: raise RuntimeError("Unexpected file format name '%s'" % fileFilter) self.saveSceneToFile(fileName, fileFormat, None, None) self.__lastfilename = fileName self.__lastformat = fileFormat def saveSceneToFile(self, filename, imageformat, transparent, rastsize): ''' Save the current scene to the named file. If imageformat is empty or None, the format is guessed from the filename extension. If transparent is False, the entire scene is initialized to the last clearing color. If given, rastsize is the pixels size of the saved image. If rastsize is not given, the saved image will be saved at the current scaled image size. ''' # This could be called when there is no image present. # If this is the case, ignore the call. if (self.__sceneimage == None): return if not imageformat: # Guess the image format from the filename extension # This is only done to silently change gif to png fileext = (os.path.splitext(filename)[1]).lower() if fileext == '.gif': myformat = 'gif' else: # let QImage figure out the format myformat = None else: myformat = imageformat.lower() if myformat == 'gif': # Silently convert gif filename and format to png myformat = 'png' myfilename = os.path.splitext(filename)[0] + ".png" else: myfilename = filename # set the cursor and status message to indicate a save is happending QApplication.setOverrideCursor(Qt.WaitCursor) self.statusBar().showMessage(self.tr("Saving image")) try: if rastsize: imagewidth = int(rastsize.width() + 0.5) imageheight = int(rastsize.height() + 0.5) else: imagewidth = int(self.__scenewidth * self.__scalefactor + 0.5) imageheight = int(self.__sceneheight * self.__scalefactor + 0.5) myimage = QImage(QSize(imagewidth, imageheight), QImage.Format_ARGB32_Premultiplied) # Initialize the image if not transparent: # Clear the image with self.__lastclearcolor fillint = self.__helper.computeARGB32PreMultInt( self.__lastclearcolor) else: fillint = 0 myimage.fill(fillint) # draw the scaled scene to this QImage mypainter = QPainter(myimage) trgrect = QRectF(0.0, 0.0, float(imagewidth), float(imageheight)) srcrect = QRectF(0.0, 0.0, float(self.__scenewidth), float(self.__sceneheight)) mypainter.drawImage(trgrect, self.__sceneimage, srcrect, Qt.AutoColor) mypainter.end() # save the image to file if not myimage.save(myfilename, myformat): raise ValueError("Unable to save the plot as " + myfilename) finally: self.statusBar().clearMessage() QApplication.restoreOverrideCursor() def checkCommandPipe(self): ''' Get and perform commands waiting in the pipe. Stop when no more commands or if more than 50 milliseconds have passed. ''' try: starttime = time.clock() # Wait up to 2 milliseconds waiting for a command. # This prevents unchecked spinning when there is # nothing to do (Qt immediately calling this method # again only for this method to immediately return). while self.__cmndpipe.poll(0.002): cmnd = self.__cmndpipe.recv() self.processCommand(cmnd) # Continue to try to process commands until # more than 50 milliseconds have passed. # This reduces Qt overhead when there are lots # of commands waiting in the queue. if (time.clock() - starttime) > 0.050: break except Exception: # EOFError should never arise from recv since # the call is after poll returns True (exctype, excval) = sys.exc_info()[:2] try: if excval: self.__rspdpipe.send("**ERROR %s: %s" % (str(exctype), str(excval))) else: self.__rspdpipe.send("**ERROR %s" % str(exctype)) except Exception: pass self.exitViewer() def processCommand(self, cmnd): ''' Examine the action of cmnd and call the appropriate method to deal with this command. Raises a KeyError if the "action" key is missing. ''' try: cmndact = cmnd["action"] except KeyError: raise ValueError("Unknown command '%s'" % str(cmnd)) if cmndact == "clear": try: bkgcolor = self.__helper.getColorFromCmnd(cmnd) except KeyError: bkgcolor = None self.clearScene(bkgcolor) elif cmndact == "exit": self.exitViewer() elif cmndact == "hide": self.showMinimized() elif cmndact == "screenInfo": scrnrect = QApplication.desktop().availableGeometry() info = (self.physicalDpiX(), self.physicalDpiY(), scrnrect.width(), scrnrect.height()) self.__rspdpipe.send(info) elif cmndact == "redraw": try: bkgcolor = self.__helper.getColorFromCmnd(cmnd) except KeyError: bkgcolor = None self.redrawScene(bkgcolor) elif cmndact == "rescale": self.scaleScene(float(cmnd["factor"]), True) elif cmndact == "resize": mysize = self.__helper.getSizeFromCmnd(cmnd) self.resizeScene(mysize.width(), mysize.height()) elif cmndact == "newImage": self.loadNewSceneImage(cmnd) elif cmndact == "save": filename = cmnd["filename"] fileformat = cmnd.get("fileformat", None) try: bkgcolor = self.__helper.getColorFromCmnd(cmnd) except KeyError: bkgcolor = None rastsize = self.__helper.getSizeFromCmnd(cmnd["rastsize"]) self.saveSceneToFile(filename, fileformat, bkgcolor, rastsize) elif cmndact == "setTitle": self.setWindowTitle(cmnd["title"]) elif cmndact == "imgname": myvalue = cmnd.get("name", None) if myvalue: self.__lastfilename = myvalue myvalue = cmnd.get("format", None) if myvalue: self.__lastformat = myvalue.lower() elif cmndact == "show": if not self.isVisible(): self.show() elif cmndact == "noalpha": # ignore any alpha channel values in colors self.__noalpha = True else: raise ValueError("Unknown command action %s" % str(cmndact))
class filexplorerPluginMain(plugin.Plugin): ' main class for plugin ' def initialize(self, *args, **kwargs): ' class init ' global CONFIG_DIR ec = ExplorerContainer() super(filexplorerPluginMain, self).initialize(*args, **kwargs) self.dock = QDockWidget() self.dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.dock.setWindowTitle("fileXplorer") self.dock.setStyleSheet('QDockWidget::title { text-align: center; }') # search for the truth self.srch = QLineEdit() #self.srch.resize(self.srch.size().height(), self.dock.size().width()) self.srch.setPlaceholderText(' Search for Python files Local or PyPI ') self.srch.returnPressed.connect(self.search) # Disk Usage Bar self.hdbar = QProgressBar() if sys.platform != 'win32': self.hdbar.setMaximum(statvfs(HOME).f_blocks * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) self.hdbar.setValue(statvfs(HOME).f_bfree * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) self.hdbar.setToolTip(str(self.hdbar.value()) + '% Total Disk Use ') #self.hdbar.setStyleSheet('''QProgressBar{background-color: #QLinearGradient(spread:pad,x1:0,y1:0,x2:1,y2:1,stop:0 rgba(255,0,0,99), #stop:1 rgba(9,255,9,200));color:#fff;border:none;border-radius:9px;} #QProgressBar::chunk{background-color:QLinearGradient(spread:pad,y1:0, #x1:0,y2:1,x2:0.27,stop:0 rgb(0,0,0),stop:1 rgb(9,99,255));padding:0; #border:none;border-radius:9px;height:9px;margin:1px;}''') self.model = QDirModel() self.fileView = QColumnView(self.dock) self.fileView.setAlternatingRowColors(True) # self.fileView.setFont(QFont(self.fileView.font().setBold(True))) self.fileView.setIconSize(QSize(32, 32)) self.fileView.setModel(self.model) self.fileView.updatePreviewWidget.connect(self.runfile) self.sli = QSlider() self.sli.setRange(16, 128) self.sli.setValue(32) self.sli.setToolTip('Icon Size: 32 px. Move Slider to change.') self.sli.setOrientation(Qt.Horizontal) self.sli.valueChanged.connect(lambda: self.fileView.setIconSize( QSize(self.sli.value(), self.sli.value()))) self.sli.sliderReleased.connect(lambda: self.sli.setToolTip('Icon Size: ' + str(self.sli.value()))) class TransientWidget(QWidget): ' persistant widget thingy ' def __init__(self, widget_list): ' init sub class ' super(TransientWidget, self).__init__() vbox = QVBoxLayout(self) for each_widget in widget_list: vbox.addWidget(each_widget) tw = TransientWidget((self.srch, self.dock, self.sli, self.hdbar)) ec.addTab(tw, "fileXplorer") #### self.process = QProcess() self.process.finished.connect(self.processFinished) self.preview = QLabel(self.fileView) self.preview.setTextFormat(0) self.preview.setStyleSheet('QLabel{font-size:9px;}') self.preview.setAutoFillBackground(True) self.fileView.setPreviewWidget(self.preview) self.dock.setWidget(self.fileView) # take a shot self.pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self) self.pic.triggered.connect(lambda: QPixmap.grabWindow( QApplication.desktop().winId()).save(QFileDialog.getSaveFileName( self.dock, " Save Screenshot As ... ", HOME, ';;(*.png)'))) # copy time self.tim = QAction(QIcon.fromTheme("user-away"), 'Date and Time to Clipboard', self) self.tim.triggered.connect(lambda: QApplication.clipboard().setText( datetime.now().strftime(" %A %B %d-%m-%Y %H:%M:%S %p "))) # color chooser self.cl = QAction(QIcon.fromTheme("applications-graphics"), 'Color Chooser to Clipboard', self) self.cl.triggered.connect(lambda: QApplication.clipboard().setText( '{}'.format(QColorDialog.getColor().name()))) # icon chooser self.icn = QAction(QIcon.fromTheme("insert-image"), 'Icon Chooser to Clipboard', self) self.icn.triggered.connect(self.iconChooser) # tool bar with actions QToolBar(self.dock).addActions((self.cl, self.icn, self.tim, self.pic)) self.textBrowser = QTextBrowser(self.dock) self.textBrowser.setAutoFillBackground(True) self.textBrowser.setGeometry(self.dock.geometry()) self.textBrowser.hide() def processFinished(self): ' print info of finished processes ' print(" INFO: OK: QProcess finished . . . ") def search(self): ' function to search python files ' # get search results of python filenames local or remote pypi_url = 'http://pypi.python.org/pypi' # pypi query pypi = xmlrpclib.ServerProxy(pypi_url, transport=ProxyTransport()) try: pypi_query = pypi.search({'name': str(self.srch.text()).lower()}) pypi_fls = list(set(['pypi.python.org/pypi/' + a['name'] + ' | pip install ' + a['name'] for a in pypi_query])) except: pypi_fls = '<b> ERROR: Internet not available! ಠ_ಠ </b>' s_out = ('<br> <br> <br> <h3> Search Local Python files: </h3> <hr> ' + # Jedi list comprehension for LOCAL search str(["{}/{}".format(root, f) for root, f in list(itertools.chain(* [list(itertools.product([root], files)) for root, dirs, files in walk(str( QFileDialog.getExistingDirectory(self.dock, 'Open Directory to Search', path.expanduser("~"))))])) if f.endswith(('.py', '.pyw', '.pth')) and not f.startswith('.') and str(self.srch.text()).lower().strip() in f] ).replace(',', '<br>') + '<hr><h3> Search PyPI Python files: </h3>' + # wraped pypi query REMOTE search str(pypi_fls).replace(',', '<br>') + '<hr>Auto-Proxy:ON,DoNotTrack:ON') # print(s_out) try: call('notify-send fileXplorer Searching...', shell=True) except: pass self.srch.clear() self.textBrowser.setGeometry(self.dock.geometry()) self.textBrowser.setHtml(s_out) self.textBrowser.show() tmr = QTimer(self.fileView) tmr.timeout.connect(self.textBrowser.hide) tmr.start(20000) def iconChooser(self): ' Choose a Icon and copy it to clipboard ' # from .std_icon_naming import std_icon_naming as a # prv = QDialog(self.dock) prv.setWindowFlags(Qt.FramelessWindowHint) prv.setAutoFillBackground(True) prv.setGeometry(self.fileView.geometry()) table = QTableWidget(prv) table.setColumnCount(1) table.setRowCount(len(a)) table.verticalHeader().setVisible(True) table.horizontalHeader().setVisible(False) table.setShowGrid(True) table.setIconSize(QSize(128, 128)) for index, icon in enumerate(a): item = QTableWidgetItem(QIcon.fromTheme(icon), '') # item.setData(Qt.UserRole, '') item.setToolTip(icon) table.setItem(index, 0, item) table.clicked.connect(lambda: QApplication.clipboard().setText( 'QtGui.QIcon.fromTheme("{}")'.format(table.currentItem().toolTip()))) table.doubleClicked.connect(prv.close) table.resizeColumnsToContents() table.resizeRowsToContents() QLabel('<h3> <br> 1 Click Copy, 2 Clicks Close </h3>', table) table.resize(prv.size()) prv.exec_() def runfile(self, index): ' run the choosed file ' s = str(file(self.model.filePath(index), 'r').read().strip()) f = str(self.model.filePath(index)) # ctime is NOT crossplatform,metadata change on *nix,creation on Window # http://docs.python.org/library/os.path.html#os.path.getctime m = ''.join((f, N, str(path.getsize(f) / 1024), ' Kilobytes', N, str(len(file(f, 'r').readlines())), ' Lines', N, str(len(s.replace(N, ''))), ' Characters', N, str(len([a for a in sub('[^a-zA-Z0-9 ]', '', s).split(' ') if a != ''])), ' Words', N, str(len([a for a in s if a in punctuation])), ' Punctuation', N, oct(stat(f).st_mode)[-3:], ' Permissions', N, time.ctime(path.getatime(f)), ' Accessed', N, time.ctime(path.getmtime(f)), ' Modified', N, 'Owner: ', str(self.model.fileInfo(index).owner()), N, 'Is Writable: ', str(self.model.fileInfo(index).isWritable()), N, 'Is Executable: ', str(self.model.fileInfo(index).isExecutable()), N, 'Is Hidden: ', str(self.model.fileInfo(index).isHidden()), N, 'Is SymLink: ', str(self.model.fileInfo(index).isSymLink()), N, 'File Extension: ', str(self.model.fileInfo(index).suffix()) )) #print(m) self.preview.setToolTip(m) self.preview.setText(s) self.preview.resize(self.preview.size().width(), self.dock.size().height()) self.process.start('xdg-open {}'.format(f)) if not self.process.waitForStarted(): print((" ERROR: Process {} Failed ! ".format(str(f)))) return
class PixmapWidget( QScrollArea ): " The pixmap widget " escapePressed = pyqtSignal() formatStrings = { QImage.Format_Invalid: "invalid", QImage.Format_Mono: "1-bit per pixel", QImage.Format_MonoLSB: "1-bit per pixel", QImage.Format_Indexed8: "8-bit indexes", QImage.Format_RGB32: "32-bit RG", QImage.Format_ARGB32: "32-bit ARGB", QImage.Format_ARGB32_Premultiplied: "32-bit ARGB", QImage.Format_RGB16: "16-bit RGB", QImage.Format_ARGB8565_Premultiplied: "24-bit ARGB", QImage.Format_RGB666: "24-bit RGB", QImage.Format_ARGB6666_Premultiplied: "24-bit ARGB", QImage.Format_RGB555: "16-bit RGB", QImage.Format_ARGB8555_Premultiplied: "24-bit ARGB", QImage.Format_RGB888: "24-bit RGB", QImage.Format_RGB444: "16-bit RGB", QImage.Format_ARGB4444_Premultiplied: "16-bit ARGB" } def __init__( self, parent = None ): QScrollArea.__init__( self, parent ) self.pixmapLabel = QLabel() self.pixmapLabel.setBackgroundRole( QPalette.Base ) self.pixmapLabel.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Ignored ) self.pixmapLabel.setScaledContents( True ) self.zoom = 1.0 self.info = "" self.formatInfo = "" self.fileSize = 0 self.setBackgroundRole( QPalette.Dark ) self.setWidget( self.pixmapLabel ) self.setAlignment( Qt.AlignCenter ) return def loadFromFile( self, fileName ): " Loads a pixmap from a file " image = QImage( fileName ) if image.isNull(): raise Exception( "Unsupported pixmap format (" + fileName + ")" ) self.pixmapLabel.setPixmap( QPixmap.fromImage( image ) ) self.pixmapLabel.adjustSize() self.fileSize = os.path.getsize( fileName ) if self.fileSize < 1024: fileSizeString = str( self.fileSize ) + "bytes" else: kiloBytes = self.fileSize / 1024 if (self.fileSize % 1024) >= 512: kiloBytes += 1 fileSizeString = str( kiloBytes ) + "kb" self.info = str( image.width() ) + "px/" + \ str( image.height() ) + "px/" + fileSizeString try: self.formatInfo = self.formatStrings[ image.format() ] except: self.formatInfo = "Unknown" return def setPixmap( self, pixmap ): " Shows the provided pixmap " pix = QPixmap.fromImage( pixmap ) self.pixmapLabel.setPixmap( pix ) self.pixmapLabel.adjustSize() self.info = str( pix.width() ) + "px/" + str( pix.height() ) + "px" self.formatInfo = str( pix.depth() ) + " bpp" return def keyPressEvent( self, event ): """ Handles the key press events """ if event.key() == Qt.Key_Escape: self.escapePressed.emit() event.accept() else: QScrollArea.keyPressEvent( self, event ) return def resetZoom( self ): " Resets the zoom " self.zoom = 1.0 self.pixmapLabel.adjustSize() return def doZoom( self, factor ): " Performs zooming " self.zoom *= factor self.pixmapLabel.resize( self.zoom * self.pixmapLabel.pixmap().size() ) self.__adjustScrollBar( self.horizontalScrollBar(), factor ) self.__adjustScrollBar( self.verticalScrollBar(), factor ) return def __adjustScrollBar( self, scrollBar, factor ): " Adjusts a scrollbar by a certain factor " scrollBar.setValue( int( factor * scrollBar.value() + ( (factor - 1) * scrollBar.pageStep()/2) ) ) return def setReadOnly( self, newValue ): " Make it similar to a text editor " return
class Panel(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.clean_up_queue = [] self.summoner = SummonerData() self.summoner.getStaticData() ### Search Bar ### ################## #label self.search_label = QLabel(self) self.search_label.move(20, 15) self.search_label.resize(220, 25) self.search_label.setText('Enter summoner name(s):') self.search_label.setStyleSheet("QLabel {font:14pt}") #text field self.search_field = QLineEdit(self) self.search_field.move(260, 15) self.search_field.resize(250, 25) self.search_field.setPlaceholderText("ex: mcnuggets, teltor, ...") self.search_field.setFocusPolicy(Qt.ClickFocus) #search button self.search_button = QPushButton(self) self.search_button.move(520, 15) self.search_button.resize(150, 25) self.search_button.setText('Search Summoner') #region combobox self.region_list = QComboBox(self) self.region_list.move(680, 15) self.region_list.resize(75, 25) regions = ['NA', 'LAN', 'BR', 'LAS', 'EUW', 'EUNE', 'TR', 'RU', 'OCE'] self.region_list.addItems(regions) #error label self.error_label = QLabel(self) self.error_label.move(775, 15) self.error_label.resize(160, 25) self.error_label.setStyleSheet("QLabel {font:14pt}") ### Summoner Information ### ############################ #summoner Icon label self.icon_label = QLabel(self) self.icon_label.setScaledContents(True) self.icon_label.move(260, 50) self.icon_label.resize(110, 110) #name label self.name_label = QLabel(self) self.name_label.move(380, 50) self.name_label.resize(620, 50) self.name_label.setText('SUMMONER NAME') self.name_label.setStyleSheet("QLabel {font:32pt}") #rank label self.rank_label = QLabel(self) self.rank_label.move(380, 100) self.rank_label.resize(200, 60) self.rank_label.setText('summoner rank') self.rank_label.setStyleSheet("QLabel {font:18pt}") #miniseries labels self.series_labels = {} self.pixmap_win = QPixmap() self.pixmap_loss = QPixmap() self.pixmap_n = QPixmap() self.pixmap_win.load("./images/win.png") self.pixmap_loss.load("./images/loss.png") self.pixmap_n.load("./images/n.png") xPos = 600 for x in range(5): match_label = QLabel(self) match_label.move(xPos, 120) match_label.resize(35, 35) match_label.setScaledContents(True) match_label.hide() self.series_labels[x] = match_label xPos += 40 #mastery image labels print 'loading mastery images ...' self.ferocity_tree_images = self.getMasteryImages( self.summoner.ferocityMasteryTree()) self.cunning_tree_images = self.getMasteryImages( self.summoner.cunningMasteryTree()) self.resolve_tree_images = self.getMasteryImages( self.summoner.resolveMasteryTree()) print 'Done' #champion icon image labels print 'loading champion icon images ...' self.championIcons = self.getChampionIconImages( self.summoner.championList()) print 'Done' #overview widget self.overview_widget = QWidget() self.overview_menu = QTabWidget(self.overview_widget) self.overview_menu.resize(720, 270) #runes widget self.runes_widget = QWidget() self.runes_menu = QTabWidget(self.runes_widget) self.runes_menu.resize(720, 270) #masteries widget self.masteries_widget = QWidget() self.masteries_menu = QTabWidget(self.masteries_widget) self.masteries_menu.resize(720, 270) #summoner menu self.menu = QTabWidget(self) self.menu.move(260, 180) self.menu.resize(720, 300) self.menu.addTab(self.overview_widget, "Overview") self.menu.addTab(self.runes_widget, "Runes") self.menu.addTab(self.masteries_widget, "Masteries") self.menu.hide() #summoners buttons self.button_list = {} yPos = 150 for x in range(10): sum_button = QPushButton(self) sum_button.move(50, yPos) sum_button.resize(150, 25) sum_button.hide() self.button_list[x] = sum_button yPos += 25 ### Connecting Widgets ### ########################## self.connect(self.search_button, QtCore.SIGNAL("clicked()"), self.getData) self.connect(self.search_button, QtCore.SIGNAL("clicked()"), self.getRankedData) self.connect(self.button_list[0], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[0].text()))) self.connect(self.button_list[1], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[1].text()))) self.connect(self.button_list[2], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[2].text()))) self.connect(self.button_list[3], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[3].text()))) self.connect(self.button_list[4], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[4].text()))) self.connect(self.button_list[5], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[5].text()))) self.connect(self.button_list[6], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[6].text()))) self.connect(self.button_list[7], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[7].text()))) self.connect(self.button_list[8], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[8].text()))) self.connect(self.button_list[9], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[9].text()))) ### Window Configuration ### ############################ #window settings self.setGeometry(200, 150, 1000, 500) self.setMaximumSize(1000, 500) self.setWindowTitle('summoner App') self.show() ### GUI methods ### ################### ############### GUI get methods ############### #get data related to given summoner names def getData(self): self.cleanUp() name_list = str(self.search_field.text()).replace( ' ', '').lower().split(',') region = str(self.region_list.currentText()).lower() if name_list != ['']: try: self.summoner.getSummonerData(name_list, region) for x in range(len(name_list)): sum_name = self.summoner.getName(name_list[x]) if sum_name != None: self.button_list[x].setText(sum_name) self.clean_up_queue.append(self.button_list[x]) else: self.button_list[x].setText(name_list[x]) self.clean_up_queue.append(self.button_list[x]) self.button_list[x].setEnabled(False) self.button_list[x].show() except RiotError as e: response = e.message print response if response == 'ServiceUnavailable': self.error_label.setText(response) elif response == '429': self.error_label.setText('Rate limit reached') elif response == 'InternalServerError': self.error_label.setText(response) elif response == 'Unauthorized': self.error_label.setText('Invalid Input') elif response == 'ServerError': self.error_label.setText(response) else: self.error_label.setText('Not Found') except KeyError as k: self.error_label.setText('Invalid Input') #get summoner ranked data def getRankedData(self): if str(self.search_field.text()) != '': region = str(self.region_list.currentText()).lower() try: self.summoner.getRankedData(region) except RiotError: print 'Rank info not found' #get mastery images def getMasteryImages(self, masteryList): pixmap_list = collections.OrderedDict() empty_spaces = 0 for row in masteryList: if len(row['masteryTreeItems']) == 2: #if len(row) == 3: row['masteryTreeItems'].append(None) #row.append(None) for element in row['masteryTreeItems']: #for element in row: if element != None: pixmap = QPixmap() pixmap.loadFromData( self.summoner.getImage( 'mastery', str(element['masteryId']) + '.png')) pixmap_list[element['masteryId']] = pixmap else: pixmap_list['null' + str(empty_spaces)] = None empty_spaces += 1 return pixmap_list #get champion icon images def getChampionIconImages(self, clist): pixmap_list = {} for champ in clist.values(): pixmap = QPixmap() pixmap.loadFromData( self.summoner.getImage('champion', champ['key'] + '.png')) pixmap_list[champ['name']] = pixmap return pixmap_list ############### GUI update methods ############### #removes previous data from GUI def cleanUp(self): self.error_label.setText("") #clears summoner info self.icon_label.setPixmap(QPixmap()) self.icon_label.setStyleSheet("QLabel {}") self.name_label.setText("") self.rank_label.setText("") #hides elements in clean up queue for x in self.clean_up_queue: x.hide() x.setEnabled(True) #display data def displayData(self, buttonName): sum_ID = self.summoner.getID(buttonName) self.displayIcon(buttonName.replace(' ', '').lower()) self.name_label.setText(buttonName) self.displayRank(sum_ID) self.displayMenu(sum_ID) #display summoner icon def displayIcon(self, summoner_name): iconName = self.summoner.getIcon(summoner_name) iconPixmap = QPixmap() self.icon_label.setStyleSheet( "QLabel {border-style: outset; border-width: 3px; border-color: gold}" ) try: iconPixmap.loadFromData( self.summoner.getImage('profileicon', iconName)) self.icon_label.setPixmap(iconPixmap) except RiotError: iconPixmap.load("./images/no_image.png") self.icon_label.setPixmap(iconPixmap) #display summoner rank def displayRank(self, sumID): for x in range(len(self.series_labels)): self.series_labels[x].setPixmap(QPixmap()) try: tier = self.summoner.getTier(sumID) division = self.summoner.getDivision(sumID) points = self.summoner.getLeaguePoints(sumID) self.rank_label.setText(tier + ': ' + division + '\n' + str(points) + ' league points') if points == 100: self.displayMiniseries(sumID) except KeyError: self.rank_label.setText('UNRANKED') #display promotion series def displayMiniseries(self, sumID): progress = self.summoner.getRankSeries(sumID) i = 0 for x in progress: if x == 'W': self.series_labels[i].setPixmap(self.pixmap_win) elif x == 'L': self.series_labels[i].setPixmap(self.pixmap_loss) else: self.series_labels[i].setPixmap(self.pixmap_n) self.clean_up_queue.append(self.series_labels[i]) self.series_labels[i].show() i += 1 #display summoner menu def displayMenu(self, sumID): self.displayOverviewMenu(sumID) self.displayRuneMenu(sumID) self.displayMasteryMenu(sumID) self.clean_up_queue.append(self.menu) self.menu.show() #display overview menu def displayOverviewMenu(self, sumID): self.overview_menu.clear() overview_normal = OverviewWidget() overview_ranked_solo = OverviewWidget() overview_ranked_team = OverviewWidget() overview_champions = ChampionsWidget() overview_normal.showStats(self.summoner.getStats(sumID, 'Normal')) overview_ranked_solo.showStats( self.summoner.getStats(sumID, 'Ranked Solo')) overview_ranked_team.showStats( self.summoner.getStats(sumID, 'Ranked Team')) overview_champions.showStats(self.summoner.getChampionStats(sumID), self.championIcons) self.overview_menu.addTab(overview_normal, 'Normal') self.overview_menu.addTab(overview_ranked_solo, 'Ranked Solo') self.overview_menu.addTab(overview_ranked_team, 'Ranked Team') self.overview_menu.addTab(overview_champions, 'Champions') #display rune menu def displayRuneMenu(self, sumID): self.runes_menu.clear() for x in range(self.summoner.getNumOfRunePages(sumID)): rune_page = RuneWidget() rune_page.setSize(700, 225) rune_page.setName(self.summoner.getRunePageName(sumID, x)) rune_data = self.summoner.getRunes(sumID, x) if rune_data != None: for y in rune_data: rid = self.summoner.getRuneID(y) desc = self.summoner.runeDescription(rid) rname = self.summoner.runeName(rid) rune_page.addRune(rid, desc, rname) rune_page.showRunes() self.runes_menu.addTab(rune_page, str(x + 1)) #display mastery menu def displayMasteryMenu(self, sumID): self.masteries_menu.clear() for x in range(self.summoner.getNumOfMasteryPages(sumID)): mastery_page = MasteryWidget() mastery_page.setMasteryLabels(self.ferocity_tree_images, self.cunning_tree_images, self.resolve_tree_images) mastery_page.setName(self.summoner.getMasteryPageName(sumID, x)) mastery_data = self.summoner.getMasteries(sumID, x) if mastery_data != None: for y in mastery_data: mid = self.summoner.getMasteryID(y) rank = self.summoner.getMasteryRank(y) mastery_page.setMasteryRank(mid, rank) mastery_page.setTotalPoints() self.masteries_menu.addTab(mastery_page, str(x + 1))
def punchcard(ui, repo, *pats, **opts): """Generate a "punch card" graph of commit times. For drawing the graph, either PyQt4 or matplotlib can be used. The default is PyQt4, unless the --mpl option is given. Normally, all commits are registered in local time, so that commits at 10 AM local time in Europe and the USA show up on the same punch card entry. If --utc is given, all commit times are converted to UTC before registered. """ if pats: raise util.Abort('no argument allowed') filename = opts['filename'] if opts['datemin']: datemin = datetime.strptime(opts['datemin'], '%Y-%m-%d') else: datemin = None if opts['datemax']: datemax = datetime.strptime(opts['datemax'], '%Y-%m-%d') else: datemax = None users_include = set(opts['user']) users_exclude = set(opts['notuser']) user_filter = bool(users_include or users_exclude) title = opts.get('title') font = opts.get('font') or 'Arial' utc = opts.get('utc') data = [[0] * 24 for i in range(7)] cl = repo.changelog n = 0 ui.status('filtering changesets\n') for i in xrange(len(cl)): node = cl.read(cl.node(i)) # node[2] is a tuple of the date in UTC and the timezone offset. # If --utc is given, the offset can be ignored; otherwise if utc: date = datetime.utcfromtimestamp(node[2][0]) else: date = datetime.utcfromtimestamp(node[2][0] - node[2][1]) if (datemin and date < datemin) or (datemax and date > datemax): continue if user_filter: user = node[1] if users_include and user not in users_include: continue if user in users_exclude: continue day = (int(date.strftime('%w')) - 1) % 7 data[day][date.hour] += 1 n += 1 if n == 0: raise util.Abort('no matching changesets found') else: ui.status('punched %d changesets\n' % n) maxvalue = max(max(i) for i in data) or 1 xs, ys, rs, ss = [], [], [], [] for y, d in enumerate(data): for x, n in enumerate(d): xs.append(x); ys.append(y); rs.append(13.*n/maxvalue) ss.append(4.*n**2/maxvalue) try: if opts.get('mpl') or opts.get('svg'): raise ImportError from PyQt4.QtCore import Qt, QPointF, QRectF from PyQt4.QtGui import QApplication, QColor, QFont, QImage, QLabel, \ QMainWindow, QPainter, QPixmap except ImportError: try: if opts.get('svg'): raise ImportError from matplotlib import pyplot except ImportError: if not opts.get('svg'): ui.status('Writing as SVG since neither PyQt4 nor ' 'matplotlib is available\n') if filename.endswith('.png'): filename = filename[:-4] + '.svg' f = open(filename, 'w') f.write('<?xml version="1.0" standalone="no"?>\n') f.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ' '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n') o = title and 30 or 0 # y coordinate offset f.write('<svg width="800" height="{0}" version="1.1" ' 'xmlns="http://www.w3.org/2000/svg">\n'.format(300+o)) f.write('<style type="text/css"> circle {{fill: black;}} ' 'text {{font-family:{0};font-size:12;}} ' '.label{{font-size:12px;}}</style>\n'.format(font)) f.write('<rect x="0" y="0" width="800" height="{0}" ' 'style="fill:#efefef;"/>\n'.format(300+o)) f.write('<line x1="35.5" y1="{0}" x2="{1}" y2="{0}" ' 'style="stroke:black;stroke-width:2"/>\n' .format(264.5+o,45.5+24*31)) f.write('<line x1="35.5" y1="{0}" x2="35.5" y2="{1}" ' 'style="stroke:black;stroke-width:2"/>\n' .format(14.5+o,264.5+o)) for i, text in enumerate(days): f.write('<text class="label" x="7.5" y="{0}">{1}</text>\n' .format(34.5+i*34+o,text)) for i in range(24): f.write('<text class="label" x="{0}" y="{1}">{2:02}</text>\n' .format(53.5 + i*31, 280.5 + o, i)) for x, y, r in zip(xs, ys, rs): f.write('<circle cx="{0}" cy="{1}" r="{2}" fill="black"/>\n' .format(58.5 + x*31, 30.5 + y*34 + o, r)) if title: f.write('<text x="400" y="20" style="text-anchor:middle;">' '{0}</text>\n'.format(title)) f.write('</svg>') f.close() ui.status('created punch card in %s\n' % filename) else: pyplot.rc('font', family=font) # create a figure an axes with the same background color fig = pyplot.figure(figsize=(8, title and 3 or 2.5), facecolor='#efefef') ax = fig.add_subplot('111', axisbg='#efefef') # make the figure margins smaller if title: fig.subplots_adjust(left=0.06, bottom=0.04, right=0.98, top=0.95) ax.set_title(title, y=0.96).set_color('#333333') else: fig.subplots_adjust(left=0.06, bottom=0.08, right=0.98, top=0.99) # don't display the axes frame ax.set_frame_on(False) # plot the punch card data ax.scatter(xs, ys[::-1], s=ss, c='#333333', edgecolor='#333333') # hide the tick lines for line in ax.get_xticklines() + ax.get_yticklines(): line.set_alpha(0.0) # draw x and y lines (instead of axes frame) dist = -0.8 ax.plot([dist, 23.5], [dist, dist], c='#555555') ax.plot([dist, dist], [dist, 6.4], c='#555555') # select new axis limits ax.set_xlim(-1, 24) ax.set_ylim(-0.9, 6.9) # set tick labels and draw them smaller than normal ax.set_yticks(range(7)) for tx in ax.set_yticklabels(days[::-1]): tx.set_color('#555555') tx.set_size('x-small') ax.set_xticks(range(24)) for tx in ax.set_xticklabels(['%02d' % x for x in range(24)]): tx.set_color('#555555') tx.set_size('x-small') # get equal spacing for days and hours ax.set_aspect('equal') fig.savefig(filename) ui.status('created punch card in %s\n' % filename) if opts.get('display'): pyplot.show() else: app = QApplication([]) o = title and 30 or 0 # y coordinate offset image = QImage(800, 300 + o, QImage.Format_RGB32) painter = QPainter(image) painter.setRenderHints(QPainter.Antialiasing) painter.fillRect(0, 0, 800, 300 + o, QColor('#efefef')) painter.setPen(QColor('#555555')) painter.drawLine(QPointF(35.5, 264.5 + o), QPointF(45.5 + 24 * 31, 264.5 + o)) painter.drawLine(QPointF(35.5, 14.5 + o), QPointF(35.5, 264.5 + o)) painter.setFont(QFont(font, 8)) for i, text in enumerate(days): painter.drawText(QPointF(7.5, 34.5 + i * 34 + o), text) for i in range(24): text = '%02d' % i painter.drawText(QPointF(53.5 + i * 31, 280.5 + o), text) painter.setBrush(QColor('#333333')) painter.setPen(QColor('#333333')) for x, y, r in zip(xs, ys, rs): painter.drawEllipse(QPointF(58.5 + x * 31, 30.5 + y * 34 + o), r, r) if title: painter.setFont(QFont(font, 12)) painter.drawText(QRectF(0, 15, 800, 20), Qt.AlignCenter, title) painter.end() image.save(filename) ui.status('created punch card in %s\n' % filename) if opts.get('display'): win = QMainWindow() win.setWindowTitle('punchcard display') win.resize(800, 300 + o) lbl = QLabel(win) lbl.resize(800, 300 + o) lbl.setPixmap(QPixmap.fromImage(image)) win.show() app.exec_()
class App(QWidget): def __init__(self): super(App, self).__init__() self.title = 'IR Data v10b' self.left = 0 self.top = 0 self.width = 840 self.height = 480 self.grid = QGridLayout() self.myButtons = QVBoxLayout() self.labelRec = QLabel('Recording') self.initUI() @pyqtSlot(QImage) def setImage(self, image): self.label.setPixmap(QPixmap.fromImage(image)) #@pyqtSlot(QImage) #def displayRec(self): #self.myButtons.addWidget(self.labelRec) def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.resize(self.width, self.height) self.label = QLabel(self) self.timerLabel = QLabel('Display Date and Time', self) self.recLabel = QLabel('Not Recording', self) #buttons and actions self.btn = QPushButton('Start Recording Raw Data', self) self.btn2 = QPushButton('Stop Recording and Save', self) self.btn.clicked.connect(startRec) self.btn2.clicked.connect(stopRecAndSave) self.btn.clicked.connect(self.displayRec) self.btn2.clicked.connect(self.displayNotRec) self.connect(self, SIGNAL('triggered()'), self.closeEvent) #layout self.grid.addWidget(self.label, 1, 1) self.myButtons.addWidget(self.btn) self.myButtons.addWidget(self.btn2) self.myButtons.addWidget(self.timerLabel) self.myButtons.addWidget(self.recLabel) self.myButtons.addStretch() self.grid.addLayout(self.myButtons, 1, 2) self.setLayout(self.grid) self.label.resize(self.width, self.height) #time display self.timer = QTimer(self) self.timer.setInterval(1000) self.timer.timeout.connect(self.displayTime) self.timer.start() self.th = Thread(self) self.th.changePixmap.connect(self.setImage) self.th.start() def displayTime(self): self.timerLabel.setText(QDateTime.currentDateTime().toString()) def displayRec(self): self.recLabel.setText('Recording') def displayNotRec(self): self.recLabel.setText('Not Recording') def closeEvent(self, event): print("Close Event Called") if camState == 'recording': reply = QMessageBox.question( self, 'Message', "Recording still in progress. Are you sure you want to quit?", QMessageBox.Yes, QMessageBox.No) print('Message Box Displayed') if reply == QMessageBox.Yes: print('Exited Application Without Saving Raw Data') event.accept() else: event.ignore() else: print('Exited Application') event.accept()
@pyqtSlot("QString") def setText__2(self, msg): # print "setText__2" self.setText(msg) if __name__ == "__main__": from PyQt4.QtGui import QApplication, QLabel, QMessageBox import sys import os print os.getpid() app = QApplication(sys.argv) text = QLabel(" QLocalServer tests") # text = Label(" QLocalServer tests") text.resize(600, 400) s = Server() if (s.init("localserver-test") == False): QMessageBox.information( text, "info", "There is already exist one!") #// 初使化失败, 说明已经有一个在运行了 sys.exit(-1) # QObject.connect(s,SIGNAL("newMessage(PyQt_PyObject)"),text, SLOT("setText__2(PyQt_PyObject)")) # QObject.connect(s,SIGNAL("newMessage(QString)"),text, SLOT("setText__2(QString)")) QObject.connect(s, SIGNAL("newMessage(QString)"), text, SLOT("setText(QString)")) text.show()
class EGPSWindow(QMainWindow): def __init__(self): # Inicializo el parent y audio module super(EGPSWindow, self).__init__() self.audio_mod = AudioModule(OUTPUT_FILE_PATH) # Titulo, tamano y tamano fijo (no resize) win_height = 130 + len(TRANSFER_FUNCTIONS) * 40 self.setWindowTitle("EGPS-1") self.setGeometry(70, 70, 600, win_height) self.setFixedSize(600, win_height) # Funcion y lista de parametros para la creacion de las labels labels_func = self.create_label nm_px_py_labels = [("Transductor de entrada", 10, 105), ("Grabacion", 400, 120), ("Salida", 400, 330), ("Archivo de entrada", 10, 10), ("Transductor de salida", 200, 105), ("Entrada a procesar", 400, 230)] # Funcion y lista de parametros para la creacion de radiobuttons in_bq = QButtonGroup(self) out_bq = QButtonGroup(self) process_bq = QButtonGroup(self) radio_buttons_func = self.create_radio_button nm_px_py_cb_radio_buttons = [ ("Archivo de entrada", 405, 255, PROCESS_GROUP, process_bq), ("Grabacion", 405, 280, PROCESS_GROUP, process_bq) ] #Creacion de los radio buttons para el grupo de transductores de entrada y de salida for index, transfer_function in enumerate(TRANSFER_FUNCTIONS.keys()): nm_px_py_cb_radio_buttons.append( (transfer_function, 30, 125 + index * 40, INPUT_GROUP, in_bq)) nm_px_py_cb_radio_buttons.append( (transfer_function, 220, 125 + index * 40, OUTPUT_GROUP, out_bq)) # Funcion y lista de parametros para la creacion de los pushbuttons push_buttons_func = self.define_push_button nm_px_py_callb_push_buttons = [ ("", 55, 70, self.audio_mod.stop_file, STOP_IMAGE_PATH, True), ("Elegir archivo", 15, 35, self.select_file), ("", 15, 70, self.audio_mod.play_file, PLAY_IMAGE_PATH, True), ("", 405, 145, self.audio_mod.rec, REC_IMAGE_PATH, True), ("", 445, 145, self.audio_mod.stop_rec, STOP_IMAGE_PATH, True), ("", 485, 145, self.audio_mod.play_rec, PLAY_IMAGE_PATH, True), ("", 525, 145, self.rec_file_save, SAVE_IMAGE_PATH, True), ("", 405, 355, self.out_file_play, PLAY_IMAGE_PATH, True), ("", 445, 355, self.audio_mod.stop_out, STOP_IMAGE_PATH, True), ("", 485, 355, self.out_file_save, SAVE_IMAGE_PATH, True) ] # Se define una lista de tuplas con (constructor, lista de parametros del constructor) para los diferentes # tipos de elementos elements_constructors = [ (labels_func, nm_px_py_labels), (radio_buttons_func, nm_px_py_cb_radio_buttons), (push_buttons_func, nm_px_py_callb_push_buttons) ] for const, params_list in elements_constructors: for params in params_list: const(*params) # Se eligen los radiobuttons iniciales self.input_output = dict() self.input_output[INPUT_GROUP] = str(in_bq.buttons()[0].text()) self.input_output[OUTPUT_GROUP] = str(out_bq.buttons()[1].text()) self.input_output[PROCESS_GROUP] = str(process_bq.buttons()[0].text()) in_bq.buttons()[0].setChecked(True) out_bq.buttons()[1].setChecked(True) process_bq.buttons()[0].setChecked(True) # Se define el pop up para salir de la aplicacion self.msg_box = QMessageBox() self.msg_box.setWindowTitle("Salir") self.msg_box.setText("Esta seguro que desea salir?") self.msg_box.addButton("Si", QMessageBox.AcceptRole) self.msg_box.addButton("No", QMessageBox.RejectRole) # Error para formato incorrecto self.wrong_file_box = QMessageBox() self.wrong_file_box.setWindowTitle("Error") self.wrong_file_box.setText("El archivo tiene formato incorrecto") # Error para el path file self.no_data_box = QMessageBox() self.no_data_box.setWindowTitle("Error") self.no_data_box.setText( "No se puede utilizar la ruta indicada o los datos son inexistentes" ) # Create select play file self.path_label = QLabel(os.path.abspath(OUTPUT_FILE_PATH), self) self.path_label.move(128, 40) self.path_label.resize(self.path_label.minimumSizeHint()) # Metodo del parent QWidget. QWidget -> QMainWindow -> EGPSWindow self.show() def select_file(self): """ Se define un metodo para la eleccion de un archivo de audio existente """ self.audio_mod.stop_rec() file_path = str(QFileDialog.getOpenFileName(self, "Elegir archivo")) if file_path != "": if file_path.endswith(".wav"): self.path_label.setText(file_path) self.path_label.resize(self.path_label.minimumSizeHint()) self.audio_mod.load_file(file_path) else: self.wrong_file_box.exec_() def rec_file_save(self): """ Metodo para almacenar el archivo que fue grabado en la etapa de grabacion """ file_path = str(QFileDialog.getSaveFileName(self, 'Guardar archivo')) if file_path != "" and not self.audio_mod.save_rec(file_path): self.no_data_box.exec_() def out_file_save(self): """ Metodo para almacenar el archivo que fue procesado en la etapa de salida """ file_path = str(QFileDialog.getSaveFileName(self, 'Guardar archivo')) recorded = self.input_output[PROCESS_GROUP] == "Grabacion" tfs = TRANSFER_FUNCTIONS[self.input_output[ INPUT_GROUP]] + TRANSFER_FUNCTIONS[self.input_output[OUTPUT_GROUP]] if file_path != "" and not self.audio_mod.save_out( file_path, recorded, *tfs): self.no_data_box.exec_() def out_file_play(self): """ Metodo para reproducir el archivo que fue procesado en la etapa de salida """ tfs = TRANSFER_FUNCTIONS[self.input_output[ INPUT_GROUP]] + TRANSFER_FUNCTIONS[self.input_output[OUTPUT_GROUP]] self.audio_mod.play_out( self.input_output[PROCESS_GROUP] == "Grabacion", *tfs) def closeEvent(self, event): """ Metodo para cerrar la ventana principal """ # Overwriten method from parent QWidget. QWidget -> QMainWindow -> EGPSWindow event.ignore() if self.msg_box.exec_() == QMessageBox.AcceptRole: sys.exit() def radio_button_clicked(self, text_option, group_option): self.input_output[group_option] = text_option print(str(self.input_output)) #----------------------------------------------------------------------------------------------------------------------- """Creacion de labels, pushbuttons y radiobuttons""" def create_label(self, name, pos_x, pos_y): """ Se define un metodo para la creacion de los labels de la interfaz grafica :param name: Nombre del label :param pos_x: Posicion horizontal :param pos_y: Posicion vertical """ label = QLabel(name, self) label.move(pos_x, pos_y) label.resize(label.minimumSizeHint()) def define_push_button(self, text, pos_x, pos_y, callback, image_path=None, resize=False): """ Se define un metodo para la creacion de push buttons en la interfaz grafica :param text: Texto que muestra el pushbutton :param pos_x: Posicion horizontal :param pos_y: Posicion Vertical :param callback: :param image_path: Ruta del icono o imagen asociada al push button :param resize: Cambia el tamano del pushbutton :return: """ btn = QPushButton(text, self) btn.move(pos_x, pos_y) if image_path: btn.setIcon(QIcon(image_path)) if resize: btn.resize(btn.minimumSizeHint()) # This binds the signal clicked() from the button to the callback. self.connect(btn, SIGNAL("clicked()"), callback) def create_radio_button(self, text, pos_x, pos_y, group, button_group): """ Se define un metodo para la creacion de radio buttons :param text: Texto que acompana al radio button :param pos_x: Posicion horizontal :param pos_y: Posicion vertical :param group: :param button_group: :return: """ radio_button = QRadioButton(text, self) radio_button.move(pos_x, pos_y) # This binds the signal pressed() from the radio button to the radio_button_clicked method. self.connect(radio_button, SIGNAL("pressed()"), partial(self.radio_button_clicked, text, group)) radio_button.resize(radio_button.minimumSizeHint()) button_group.addButton(radio_button)
class QmsSearchResultItemWidget(QWidget): def __init__(self, geoservice, image_ba, parent=None): QWidget.__init__(self, parent) self.layout = QHBoxLayout(self) # self.layout.addSpacing(0) self.layout.setContentsMargins(5, 10, 5, 10) self.setLayout(self.layout) self.service_icon = QLabel(self) self.service_icon.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.service_icon.resize(24, 24) qimg = QImage.fromData(image_ba) pixmap = QPixmap.fromImage(qimg) self.service_icon.setPixmap(pixmap) self.layout.addWidget(self.service_icon) self.service_desc_layout = QGridLayout(self) self.service_desc_layout.setSpacing(0) self.layout.addLayout(self.service_desc_layout) self.service_name = QLabel(self) self.service_name.setTextFormat(Qt.RichText) self.service_name.setWordWrap(True) self.service_name.setText(u" <strong> {} </strong>".format( geoservice.get('name', u""))) self.service_desc_layout.addWidget(self.service_name, 0, 0, 1, 3) self.service_type = QLabel(self) self.service_type.setTextFormat(Qt.RichText) self.service_type.setWordWrap(True) self.service_type.setText(geoservice.get('type', u"").upper() + " ") self.service_desc_layout.addWidget(self.service_type, 1, 0) self.service_deteils = QLabel(self) self.service_deteils.setTextFormat(Qt.RichText) self.service_deteils.setWordWrap(True) self.service_deteils.setOpenExternalLinks(True) self.service_deteils.setText(u"<a href=\"{}\">details</a>, ".format( Client().geoservice_info_url(geoservice.get('id', u"")))) self.service_desc_layout.addWidget(self.service_deteils, 1, 1) self.service_report = QLabel(self) self.service_report.setTextFormat(Qt.RichText) self.service_report.setWordWrap(True) self.service_report.setOpenExternalLinks(True) self.service_report.setText( u"<a href=\"{}\">report a problem</a><div/>".format( Client().geoservice_report_url(geoservice.get('id', u"")))) self.service_desc_layout.addWidget(self.service_report, 1, 2) self.service_desc_layout.setColumnStretch(2, 1) # self.service_desc = QLabel(self) # self.service_desc.setTextFormat(Qt.RichText) # self.service_desc.setOpenExternalLinks(True) # self.service_desc.setWordWrap(True) # self.service_desc.setText( # u"<strong> {} </strong><div style=\"margin-top: 3px\">{}, <a href=\"{}\">details</a>, <a href=\"{}\">report</a><div/>".format( # # "{}<div style=\"margin-top: 3px\"> <em> {} </em>, <a href=\"{}\"> details <a/> <div/>".format( # geoservice.get('name', u""), # geoservice.get('type', u"").upper(), # Client().geoservice_info_url(geoservice.get('id', u"")), # Client().geoservice_report_url(geoservice.get('id', u"")) # ) # ) # self.layout.addWidget(self.service_desc) self.addButton = QToolButton() self.addButton.setText("Add") self.addButton.clicked.connect(self.addToMap) self.layout.addWidget(self.addButton) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) self.geoservice = geoservice self.image_ba = image_ba def addToMap(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) client = Client() client.set_proxy(*QGISSettings.get_qgis_proxy()) geoservice_info = client.get_geoservice_info(self.geoservice) ds = DataSourceSerializer.read_from_json(geoservice_info) add_layer_to_map(ds) CachedServices().add_service(self.geoservice, self.image_ba) except Exception as ex: plPrint(unicode(ex)) pass finally: QApplication.restoreOverrideCursor() def mouseDoubleClickEvent(self, event): self.addToMap()
class WelcomeWindow( QMainWindow): """ The welcome window """ def __init__(self, parent=None): QMainWindow.__init__(self,None) self.parent = parent #This is for the case we aren't on Maemo try: self.setAttribute( Qt.WA_Maemo5AutoOrientation, True) self.setAttribute(Qt.WA_Maemo5StackedWindow, True) self.isMaemo = True except AttributeError: self.isMaemo = False self.resize(800,600) self.setupMain(self.isMaemo) self.setupMenu() self.setCentralWidget(self.scrollArea) self.setWindowTitle("KhtEditor") def do_about(self): """ Display about dialog from parent """ self.parent.about(self) def enterEvent(self,event): """ Redefine the enter event to refresh recent file list """ self.refreshMain() def refreshMain(self): """ Refresh the recent files list """ recentfiles = RecentFiles().get() print self._layout.count() for index in range(0,self._layout.count()-4): recentFileButton = self._layout.itemAt(index+4).widget() try: if self.isMaemo: recentFileButton.setText(os.path.basename(unicode(recentfiles[index]).encode('utf-8')).decode('utf-8')) recentFileButton.setValueText(os.path.abspath(unicode(recentfiles[index]).encode('utf-8')).decode('utf-8')) else: recentFileButton.setText(os.path.abspath(unicode(recentfiles[index]).encode('utf-8')).decode('utf-8')) except StandardError: recentFileButton.setDisabled(True) def setupMain(self, isMaemo=False): """ GUI Initialization """ self.scrollArea = QScrollArea(self) self.scrollArea.setWidgetResizable(True) awidget = QWidget(self.scrollArea) if isMaemo: awidget.setMinimumSize(480,1000) awidget.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding) self.scrollArea.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding) #Kinetic scroller is available on Maemo and should be on meego try: scroller = self.scrollArea.property("kineticScroller") #.toPyObject() scroller.setEnabled(True) except: pass self._layout = QVBoxLayout(awidget) self.icon = QLabel() self.icon.setPixmap( QPixmap(os.path.join(os.path.dirname(__file__) ,'icons','khteditor.png')).scaledToHeight(64)) self.icon.setAlignment( Qt.AlignCenter or Qt.AlignHCenter ) self.icon.resize(70,70) self.label = QLabel("KhtEditor Version "+self.parent.version) self.label.setAlignment( Qt.AlignCenter or Qt.AlignHCenter ) self._layout.addWidget(self.icon) self._layout.addWidget(self.label) self._layout_button = QHBoxLayout() self.new_button = QPushButton("New") self.new_button.clicked.connect(self.parent.newFile) self.open_button = QPushButton("Open") self.open_button.clicked.connect(self.parent.openFile) self._layout_button.addWidget(self.new_button) self._layout_button.addWidget(self.open_button) self._layout.addLayout(self._layout_button) label = QLabel("Recent Files") label.setAlignment( Qt.AlignCenter or Qt.AlignHCenter ) self._layout.addWidget(label) awidget.setLayout(self._layout) self.scrollArea.setWidget(awidget) for index in range(10): if isMaemo: recentFileButton = QtMaemo5.QMaemo5ValueButton() else: recentFileButton = QPushButton() recentFileButton.clicked.connect(Curry(self.openRecentFile,recentFileButton)) self._layout.addWidget(recentFileButton) def openRecentFile(self,button, Useless=None): """ Call back which open a recent file """ if self.isMaemo: self.setAttribute( Qt.WA_Maemo5ShowProgressIndicator,True) self.parent.openRecentFile(button) if self.isMaemo: self.setAttribute( Qt.WA_Maemo5ShowProgressIndicator,False) def setupMenu(self): """ Initialization of the maemo menu """ fileMenu = QMenu(self.tr("&Menu"), self) self.menuBar().addMenu(fileMenu) fileMenu.addAction(self.tr("&New..."), self.parent.newFile, QKeySequence(self.tr("Ctrl+N", "New"))) fileMenu.addAction(self.tr("&Open..."), self.parent.openFile, QKeySequence(self.tr("Ctrl+O", "Open"))) fileMenu.addAction(self.tr("&Preferences..."), self.showPrefs) fileMenu.addAction(self.tr("&About"), self.do_about) def showPrefs(self): """ Call the parent class to show window """ self.parent.showPrefs(self)
class AppMainWindow(Ui_mainWindow, QMainWindow): """ Main application window """ # internal decorator to perform common checks required # for many calls ############################# class CallChecker(object): def __init__(self): pass def setWindow(self, main_window): self.main_window = main_window def __call__(self, f): @functools.wraps(f) def wrapper(*args, **kw): self.main_window.setEnabled(False) try: logUICall.log( 'function call %s from module %s' % (f.__name__, f.__module__), logUICall.DEBUG) return f(*args, **kw) except SIDDUIException as uie: logUICall.log(uie, logUICall.WARNING) self.main_window.ui.statusbar.showMessage( get_ui_string('app.error.ui')) except SIDDException as se: logUICall.log(se, logUICall.WARNING) self.main_window.ui.statusbar.showMessage( get_ui_string('app.error.model')) except Exception as e: logUICall.log(e, logUICall.ERROR) self.main_window.ui.statusbar.showMessage( get_ui_string('app.error.unexpected')) finally: self.main_window.setEnabled(True) return wrapper apiCallChecker = CallChecker() # CONSTANTS ############################# UI_WINDOW_GEOM = 'app_main/geometry' UI_WINDOW_STATE = 'app_main/windowState' TAB_DATA, TAB_MS, TAB_MOD, TAB_RESULT = range(4) # constructor / destructor ############################# def __init__(self, qtapp, app_config): """ constructor - initialize UI elements - connect UI elements to callback """ # create UI super(AppMainWindow, self).__init__() AppMainWindow.apiCallChecker.setWindow(self) self.qtapp = qtapp self.app_config = app_config self.taxonomy = get_taxonomy( app_config.get('options', 'taxonomy', 'gem')) self.ui = Ui_mainWindow() self.ui.setupUi(self) self.settings = QSettings(SIDD_COMPANY, '%s %s' % (SIDD_APP_NAME, SIDD_VERSION)) self.restoreGeometry( self.settings.value(self.UI_WINDOW_GEOM).toByteArray()) self.restoreState( self.settings.value(self.UI_WINDOW_STATE).toByteArray()) self.lb_map_location = QLabel(self) self.lb_map_location.resize(self.ui.statusbar.width() / 3, self.ui.statusbar.height()) self.ui.statusbar.addPermanentWidget(self.lb_map_location) self.msdb_dao = MSDatabaseDAO(FILE_MS_DB) self.tab_datainput = WidgetDataInput(self) self.ui.mainTabs.addTab(self.tab_datainput, get_ui_string("app.window.tab.input")) self.tab_ms = WidgetMappingSchemes(self) self.ui.mainTabs.addTab(self.tab_ms, get_ui_string("app.window.tab.ms")) self.tab_mod = WidgetSecondaryModifier(self) self.ui.mainTabs.addTab(self.tab_mod, get_ui_string("app.window.tab.mod")) self.tab_result = WidgetResult(self) self.ui.mainTabs.addTab(self.tab_result, get_ui_string("app.window.tab.result")) self.previewInput = True self.about = DialogAbout(self) self.about.setModal(True) self.dlgAttrRange = DialogAttrRanges() self.dlgAttrRange.setModal(True) self.progress = DialogApply(self) self.progress.setModal(True) self.proc_options = DialogProcessingOptions(self) self.proc_options.setModal(True) # connect menu action to slots (ui events) self.ui.mainTabs.currentChanged.connect(self.tabChanged) self.ui.actionProject_Blank.triggered.connect(self.createBlank) self.ui.actionUsing_Data_Wizard.triggered.connect(self.createWizard) self.ui.actionOpen_Existing.triggered.connect(self.loadProj) self.ui.actionSave.triggered.connect(self.saveProj) self.ui.actionSave_as.triggered.connect(self.saveProjAs) self.ui.actionExit.triggered.connect(self.close) self.ui.actionData_Input.triggered.connect(self.changeTab) self.ui.actionMapping_Schemes.triggered.connect(self.changeTab) self.ui.actionResult.triggered.connect(self.changeTab) self.ui.actionProcessing_Options.triggered.connect( self.setProcessingOptions) self.ui.actionAbout.triggered.connect(self.showAbout) # set project to None and adjust ui as needed self.closeProject() self.ui.statusbar.showMessage(get_ui_string("app.status.ready")) # perform clean up from previous runs try: delete_folders_in_dir(get_temp_dir(), "tmp*") except: # cleanup is not-critical. no action taken even if fails pass # hide features if not app_config.get('options', 'parse_modifier', True, bool): self.tab_mod.setVisible(False) self.ui.mainTabs.removeTab(self.TAB_MOD) self.TAB_MOD = self.TAB_MS self.TAB_RESULT -= 1 # hide view menu self.ui.menuView.menuAction().setVisible(False) # hide data wizard self.ui.actionUsing_Data_Wizard.setVisible(False) # event handlers ############################# @pyqtSlot(QCloseEvent) def resizeEvent(self, event): """ handle window resize """ self.ui.mainTabs.resize(self.width(), self.height() - 40) @pyqtSlot(QCloseEvent) def closeEvent(self, event): self.closeProject() self.settings.setValue(self.UI_WINDOW_GEOM, self.saveGeometry()) self.settings.setValue(self.UI_WINDOW_STATE, self.saveState()) self.msdb_dao.close() super(AppMainWindow, self).closeEvent(event) @logUICall @pyqtSlot() def createBlank(self): """ create a new project """ # create new project file project = Project(self.app_config, self.taxonomy) # open project and sync UI self.setProject(project, skipVerify=True) self.ui.statusbar.showMessage( get_ui_string("app.status.project.created")) @logUICall @pyqtSlot() def createWizard(self): try: # should not update preview while using wizard self.setVisible(False) self.previewInput = False wizard = WidgetDataWizard(self, Project(self.app_config, self.taxonomy)) if wizard.exec_() == QDialog.Accepted: # setProject makes call to GIS component that requires visibility self.setVisible(True) self.previewInput = True self.setProject(wizard.project) self.ui.statusbar.showMessage( get_ui_string("app.status.project.created")) # else # do nothing? except: pass finally: # return to normal window # these calls are reached # 1. in case any exception occurs, # 2. wizard finished or cancelled self.setVisible(True) self.previewInput = True @logUICall @pyqtSlot() def loadProj(self): """ open file dialog to load an existing application """ self.getOpenFileName(self, get_ui_string("app.window.msg.project.open"), get_ui_string("app.extension.db"), self.openProjectFile) self.ui.statusbar.showMessage( get_ui_string("app.status.project.loaded")) @logUICall @pyqtSlot() def saveProj(self): """ save active project """ if self.project is None: return try: self.project.sync(SyncModes.Write) self.ui.statusbar.showMessage( get_ui_string("app.status.project.saved")) except SIDDProjectException as se: if se.error == ProjectErrors.FileNotSet: self.saveProjAs() @logUICall @pyqtSlot() def saveProjAs(self): if self.project is None: return filename = QFileDialog.getSaveFileName( self, get_ui_string("app.window.msg.project.create"), get_app_dir(), get_ui_string("app.extension.db")) # no need to check for file overwrite, because QFileDialog return always confirmed overwrite if not filename.isNull(): filename = str(filename) self.project.set_project_path(filename) self.project.sync(SyncModes.Write) self.saveLastOpenDir(filename[0:filename.rfind("/")]) self.ui.statusbar.showMessage( get_ui_string("app.status.project.saved")) @logUICall @pyqtSlot() def setProcessingOptions(self): if self.project is None: return # set options to be those defined in project self.proc_options.resetOptions() for attribute in dir(self.proc_options): try: proc_attribute = self.project.operator_options['proc.%s' % attribute] setattr(self.proc_options, attribute, proc_attribute) except: # for empty project, this is the first time proc.options is set # just use default from proc_option dialogbox pass if self.proc_options.exec_() == QDialog.Accepted: for attribute in dir(self.proc_options): self.project.operator_options['proc.%s' % attribute] = getattr( self.proc_options, attribute) # alert user answer = QMessageBox.question( self, get_ui_string("app.confirm.title"), get_ui_string("app.confirm.build.exposure"), buttons=QMessageBox.No | QMessageBox.Yes, defaultButton=QMessageBox.No) if answer == QMessageBox.No: return self.buildExposure() @logUICall @pyqtSlot() def showAbout(self): """ event handler for menu item show about box """ self.about.setVisible(True) @logUICall @pyqtSlot() def changeTab(self): """ event handler for menu item in menu - switch view to tab according to menu item pushed """ sender = self.sender() if sender == self.ui.actionData_Input: self.showTab(self.TAB_DATA) elif sender == self.ui.actionMapping_Schemes: self.showTab(self.TAB_MS) elif sender == self.ui.actionResult: self.showTab(self.TAB_RESULT) else: logUICall.log('\tdo nothing. should not even be here', logUICall.WARNING) @logUICall @pyqtSlot(int) def tabChanged(self, index): if index == self.TAB_RESULT: self.lb_map_location.setVisible(True) else: self.lb_map_location.setVisible(False) # public methods ############################# @apiCallChecker def openProjectFile(self, path_to_file): """ load project from given path shows error if path does not exist """ # NOTE: set_project_path will create new project if path_to_file # does not exist, os.path.exists check is not optional if os.path.exists(path_to_file): # read file to create project project = Project(self.app_config, self.taxonomy) project.set_project_path(path_to_file) project.sync(SyncModes.Read) # open project and sync UI self.setProject(project) @apiCallChecker def setProject(self, project, skipVerify=False): """ open a project and sync UI accordingly""" # close and reset UI self.closeProject() self.project = project # sync ui self.tab_datainput.setProject(project) # set processing options for attribute in dir(self.proc_options): if self.project.operator_options.has_key('proc.%s' % attribute): setattr(self.proc_options, attribute, self.project.operator_options['proc.%s' % attribute]) if not skipVerify: # verify to make sure input file are still in same place self.verifyInputs() if self.project.ms is not None: self.visualizeMappingScheme(self.project.ms) self.ui.mainTabs.setTabEnabled(self.TAB_MS, True) self.ui.mainTabs.setTabEnabled(self.TAB_MOD, True) self.ui.mainTabs.setTabEnabled(self.TAB_DATA, True) self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, True) self.ui.actionSave.setEnabled(True) self.ui.actionSave_as.setEnabled(True) self.tab_result.set_project(project) @apiCallChecker def closeProject(self): """ close opened project and update UI elements accordingly """ # adjust UI in application window self.tab_result.closeAll() # this call must happen first. # otherwise, it locks temporary GIS files self.ui.mainTabs.setTabEnabled(self.TAB_DATA, False) self.ui.mainTabs.setTabEnabled(self.TAB_MS, False) self.ui.mainTabs.setTabEnabled(self.TAB_MOD, False) self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, False) self.showTab(self.TAB_DATA) # disable menu/menu items self.ui.actionSave.setEnabled(False) self.ui.actionSave_as.setEnabled(False) self.ui.actionMapping_Schemes.setEnabled(False) self.ui.actionResult.setEnabled(False) self.ui.actionProcessing_Options.setEnabled(False) if getattr(self, 'project', None) is not None: # save existing project is needed if self.project.require_save: ans = QMessageBox.question( self, get_ui_string("app.window.msg.project.not_saved"), get_ui_string("app.window.msg.project.save_or_not"), buttons=QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.Yes) if ans == QMessageBox.Yes: self.saveProj() # adjust UI in tabs self.tab_datainput.closeProject() self.tab_ms.clearMappingScheme() self.tab_mod.closeMappingScheme() self.project.clean_up() del self.project self.project = None @apiCallChecker def verifyInputs(self): """ perform checks on current dataset provided and update UI accordingly """ # remove result self.tab_result.closeResult() # verify current dataset self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.verify_data) self.tab_datainput.showVerificationResults() # always allow mapping scheme self.ui.mainTabs.setTabEnabled(self.TAB_MS, True) self.ui.mainTabs.setTabEnabled(self.TAB_MOD, True) self.ui.actionMapping_Schemes.setEnabled(True) self.ui.actionResult.setEnabled(True) self.ui.actionProcessing_Options.setEnabled(True) self.ui.statusbar.showMessage( get_ui_string("app.status.input.verified")) @apiCallChecker def buildMappingScheme(self): """ build mapping scheme with given data """ self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) # invoke asynchronously try: invoke_async(get_ui_string("app.status.processing"), self.project.build_ms) except SIDDException as err: # different error message used in this case raise SIDDUIException( get_ui_string('project.error.sampling', str(err))) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.created")) @apiCallChecker def createEmptyMS(self): """ build an empty mapping scheme tree for user to manipulate manually """ self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.create_empty_ms) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.created")) @apiCallChecker def appendMSBranch(self, node, branch): """ append a branch (from library) to a node in a mapping scheme tree """ self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) self.project.ms.append_branch(node, branch) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.modified")) @apiCallChecker def deleteMSBranch(self, node): """ delete selected node and children from mapping scheme tree """ self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) self.project.ms.delete_branch(node) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.modified")) @apiCallChecker def exportMS(self, path, format): """ export mapping scheme leaves as CSV """ self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.export_ms, path, format) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.exported")) @apiCallChecker def loadMS(self, path): self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.load_ms, path) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.created")) @apiCallChecker def exportResults(self, export_format, export_path): """ export mapping scheme leaves as CSV """ self.ui.statusbar.showMessage( get_ui_string("app.status.exposure.exported")) # invoke asynchronously self.project.set_export(export_format, export_path) invoke_async(get_ui_string("app.status.processing"), self.project.export_data) self.ui.statusbar.showMessage( get_ui_string("app.status.exposure.exported")) @apiCallChecker def buildExposure(self): """ build exposure """ self.ui.statusbar.showMessage( get_ui_string("app.status.ms.processing")) # verify current dataset to make sure can process exposure self.project.verify_data() # can not proceed if project is not ready for exposure if self.project.status != ProjectStatus.ReadyForExposure: logUICall.log(get_ui_string("project.error.NotEnoughData"), logUICall.WARNING) # show result self.tab_datainput.showVerificationResults() self.ui.mainTabs.setCurrentIndex(self.TAB_DATA) return # close current results self.tab_result.closeResult() self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, True) # reset progress dialog self.progress.setVisible(True) self.progress.ui.pb_progress.setRange( 0, self.project.build_exposure_total_steps()) self.progress.ui.txt_progress.clear() self.progress.ui.txt_progress.appendPlainText( get_ui_string("app.status.processing")) self.qtapp.processEvents() cancelled = False error_occured = False error_message = "" curStep = 0 try: for step in self.project.build_exposure_steps(): if cancelled or error_occured: break # use introspection to get operator class class_name = str(step.__class__) # result of above call has format # <class '...'> where ... is the class name of interest class_name = class_name[class_name.find("'") + 1:class_name.rfind("'")] # update UI logAPICall.log('\t %s' % step.name, logAPICall.DEBUG) self.progress.ui.txt_progress.appendPlainText( get_ui_string('message.%s' % class_name)) self.progress.ui.pb_progress.setValue(curStep) self.qtapp.processEvents() sleep(0.5) # perform operation step.do_operation() if not self.progress.isVisible(): cancelled = True # operation successful curStep += 1 except Exception as err: # exception are thrown if data is not ready for exposure error_message = err.message error_occured = True self.progress.setVisible(False) if error_occured: # processing cancelled logUICall.log(error_message, logUICall.WARNING) self.ui.statusbar.showMessage( get_ui_string("app.status.cancelled")) elif cancelled: # processing cancelled logUICall.log(get_ui_string("app.status.cancelled"), logUICall.WARNING) self.ui.statusbar.showMessage( get_ui_string("app.status.cancelled")) else: # processing completed self.project.verify_result() self.progress.setVisible(False) # show result self.tab_result.refreshResult() self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, True) self.ui.mainTabs.setCurrentIndex(self.TAB_RESULT) self.ui.statusbar.showMessage( get_ui_string("app.status.exposure.created")) def showTab(self, index): """ switch view to tab with given index. do nothing if index is not valid """ if index >= self.TAB_DATA and index <= self.TAB_RESULT: self.ui.mainTabs.setCurrentIndex(index) def refreshPreview(self): """ refresh all layers shown in Preview tab """ if self.previewInput: self.tab_result.refreshView() def visualizeMappingScheme(self, ms): """ display the given mapping scheme in Mapping scheme and Modifier tabs""" self.tab_ms.showMappingScheme(ms) self.tab_mod.showMappingScheme(ms) def updateMapLocation(self, x, y): self.lb_map_location.setText("Longitude %.4f latitude %4f" % (x, y)) # utility methods # no error checking is performed in these functions # caller must catch possible exception ############################### def setRange(self, ranges, attribute): if ranges.has_key(attribute): range = ranges[attribute] self.dlgAttrRange.set_values(attribute, range['min_values'], range['max_values']) else: self.dlgAttrRange.set_values(attribute, [], []) range_updated = self.dlgAttrRange.exec_() == QDialog.Accepted if range_updated: ranges[attribute] = { 'min_values': self.dlgAttrRange.min_values, 'max_values': self.dlgAttrRange.max_values } return range_updated def getOpenFileName(self, parent, title, extension, callback): """ show open file dialog box to get a filename """ filename = QFileDialog.getOpenFileName(parent, title, self.getLastOpenDir(), extension) if not filename.isNull(): filename = str(filename) if os.path.exists(filename): # store directory to file, so next Open will be in same dir self.saveLastOpenDir(filename[0:filename.rfind("/")]) callback( filename ) # no error catching to make sure callback is actually a function def saveLastOpenDir(self, dir_path): """ store path so it can be retrieved by other parts of the application """ self.settings.setValue('LAST_OPEN_DIR', dir_path) def getLastOpenDir(self): """ retrieve remembered path """ last_dir = self.settings.value('LAST_OPEN_DIR').toString() if last_dir is None: return get_app_dir() else: return str(last_dir)
class WTestPng(Document.WDocument): """ Test png widget """ def __init__(self, parent=None, path=None, filename=None, extension=None, nonameId=None, remoteFile=True, repoDest=None, project=0): """ Constructs WScript widget @param parent: @type parent: @param path: @type path: @param filename: @type filename: @param extension: @type extension: @param nonameId: @type nonameId: """ Document.WDocument.__init__(self, parent, path, filename, extension, nonameId, remoteFile, repoDest, project) self.scaleFactor = 0.0 self.rawContent = '' self.createWidgets() self.createActions() self.createToolbar() self.createConnections() def createActions(self): """ Create qt actions """ self.zoomInAct = QtHelper.createAction(self, "&Zoom &In (25%.", self.zoomIn, icon=QIcon(":/zoom-in.png")) self.zoomOutAct = QtHelper.createAction(self, "Zoom &Out (25%.", self.zoomOut, icon=QIcon(":/zoom-out.png")) self.normalSizeAct = QtHelper.createAction( self, "&Normal Size", self.normalSize, icon=QIcon(":/zoom-normal.png")) def createToolbar(self): """ Toolbar creation ||------|------||| || Open | Save ||| ||------|------||| """ self.dockToolbar.setObjectName("Test Config toolbar") self.dockToolbar.addAction(self.zoomInAct) self.dockToolbar.addAction(self.zoomOutAct) self.dockToolbar.addAction(self.normalSizeAct) self.dockToolbar.addSeparator() self.dockToolbar.setIconSize(QSize(16, 16)) def createWidgets(self): """ QtWidgets creation """ self.dockToolbar = QToolBar(self) self.dockToolbar.setStyleSheet( "QToolBar { border: 0px }") # remove 3D border self.imageLabel = QLabel(self) self.imageLabel.setBackgroundRole(QPalette.Base) self.imageLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabel.setScaledContents(True) self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.imageLabel) title = QLabel("Image:") title.setStyleSheet("QLabel { padding-left: 2px; padding-top: 2px }") font = QFont() font.setBold(True) title.setFont(font) layout = QVBoxLayout() layout.addWidget(title) layout.addWidget(self.dockToolbar) layout.addWidget(self.scrollArea) layout.setContentsMargins(2, 2, 2, 2) self.setLayout(layout) def zoomIn(self): """ Zoom in """ self.scaleImage(1.25) def zoomOut(self): """ Zoom out """ self.scaleImage(0.8) def normalSize(self): """ Normal size """ self.imageLabel.adjustSize() self.scaleFactor = 1.0 def scaleImage(self, factor): """ Scale image """ self.scaleFactor *= factor self.imageLabel.resize(self.scaleFactor * self.imageLabel.pixmap().size()) self.adjustScrollBar(self.scrollArea.horizontalScrollBar(), factor) self.adjustScrollBar(self.scrollArea.verticalScrollBar(), factor) def adjustScrollBar(self, scrollBar, factor): """ Adjust scrollbar """ scrollBar.setValue( int(factor * scrollBar.value() + ((factor - 1) * scrollBar.pageStep() / 2))) def createConnections(self): """ QtSignals connection """ pass def write(self, force=False): """ Save """ absPath = '%s/%s.%s' % (self.path, self.filename, self.extension) try: with open(absPath, mode='wb') as myfile: myfile.write(self.rawContent) except Exception as e: self.error("unable to write png file: %s" % e) return None else: self.setUnmodify() return True def load(self, content=None): """ Open file """ if content is None: absPath = '%s/%s.%s' % (self.path, self.filename, self.extension) file = QFile(absPath) if not file.open(QIODevice.ReadOnly): self.error("Error opening image file: %s" % absPath) return False else: content = file.readAll() self.rawContent = content image = QImage() image.loadFromData(content) if image.isNull(): self.error("cannot load image") return False else: self.imageLabel.setPixmap(QPixmap.fromImage(QImage(image))) self.scaleFactor = 1.0 self.imageLabel.adjustSize() return True def getraw_encoded(self): """ Returns raw data encoded """ encoded = '' try: encoded = base64.b64encode(self.rawContent) except Exception as e: self.error('unable to encode raw image: %s' % str(e)) return encoded
class main(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setWindowTitle("Images!") ## Create BackGround to Load images into self.bg = QLabel(self) self.bg.move(0, 30) self.bg.resize(400, 550) self.bg.setStyleSheet("background-color: black;") self.setGeometry(100, 100, 400, 600) self.button = QLabel("Open..", self) self.button.setFixedSize(55, 24) self.button.setStyleSheet("border: 1px solid black; font-size: 15px") self.button. move(330, 2) self.button.mousePressEvent = self.open_label ## Create File QAction for MenuBar openFileAction = QAction('&Open Image...', self) openFileAction.setShortcut('Ctrl+O') openFileAction.setStatusTip('Open Image File') ## Connect to the open_image function openFileAction.triggered.connect(self.open_file) #Exit Action exitAction = QAction('Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.triggered.connect(app.quit) ## Create Menu Bar and Add File Menu to it self.menubar = self.menuBar() self.file_menu = self.menubar.addMenu("&File") ## Link the File Menu to the QActions. self.file_menu.addAction(openFileAction) self.file_menu.addAction(exitAction) def open_label(self, event): self.open_file() def open_file(self): filename = QFileDialog.getOpenFileName() print filename ## import Image as a QPixMap self.bg_img = QPixmap(filename) ## Resize Window to the Size of opened image self.setFixedSize(self.bg_img.size()) #<---~ 'self is the QMainWindow' self.bg.setFixedSize(self.bg_img.size()) ## set the Image to the background QLabel self.bg.setPixmap(self.bg_img) self.button.move(int(self.bg_img.width()) - 70, 2)
class LogoDialog(QDialog): def __init__(self, parent=None): super(LogoDialog, self).__init__(parent) self.pagetitle = 'School Data' stylesheet = Valid().background() + Valid().font() self.setStyleSheet(stylesheet) data = Db().selectn('datas', '', 1, {'pubID':'datas', 'name':'logo'}) d = '' if data: d = data['description'] else: d = '' self.pic1 = QLabel() self.pic1.setAlignment(Qt.AlignCenter) if os.path.isfile('./pic_main/logo.png'): image1 = Image.open('pic_main/logo.png') else: image1 = Image.open('img/stdpic.png') self.mainLink = '' imageQ1 = ImageQt(image1) imagep1 = QPixmap(QPixmap.fromImage(QImage(imageQ1).scaled(250, 300, Qt.IgnoreAspectRatio))) self.pic1.resize(250, 300) self.pic1.setPixmap(imagep1) self.pic1.setMaximumHeight(250) #self.pic1.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.picBtn1 = QPushButton('Select Image') self.picBtn1.clicked.connect(lambda:self.getFilez()) self.colorLbl = QLabel('Please use only only images in png format prferablly with transperent background') self.colorLbl1 = QLabel('Image should be a perfect square') Gbo = QGridLayout() Gbo.addWidget(self.colorLbl, 0, 0) Gbo.addWidget(self.colorLbl1, 1, 0) Gbo.addWidget(self.pic1, 2, 0) Gbo.addWidget(self.picBtn1, 3, 0) groupBox1 = QGroupBox('Upload School Logo') groupBox1.setLayout(Gbo) self.pb = QPushButton() self.pb.setObjectName("Add") self.pb.setText("Save") self.pb1 = QPushButton() self.pb1.setObjectName("Cancel") self.pb1.setText("Close") hbo = QHBoxLayout() hbo.addWidget(self.pb1) hbo.addStretch() hbo.addWidget(self.pb) groupBox2 = QGroupBox('') groupBox2.setLayout(hbo) grid = QGridLayout() grid.addWidget(groupBox1, 0, 0) grid.addWidget(groupBox2, 1, 0) self.setLayout(grid) self.connect(self.pb, SIGNAL("clicked()"), lambda: self.button_click()) self.connect(self.pb1, SIGNAL("clicked()"), lambda: self.button_close(self)) self.setWindowTitle(self.pagetitle) def getFilez(self): fname = QFileDialog.getOpenFileName(self, 'Select Image', 'c:\\', '*.png') image1 = Image.open(fname) imageQ1 = ImageQt(image1) imagep1 = QPixmap(QPixmap.fromImage(QImage(imageQ1).scaled(300, 300, Qt.IgnoreAspectRatio))) self.pic1.resize(300, 300) self.pic1.setPixmap(imagep1) self.mainLink = image1 def setCurrentPix(self): file1 = "pic_main/" img = '' img = str(file1)+'logo.png' image1 = Image.open(img) imageQ1 = ImageQt(image1) imagep1 = QPixmap(QPixmap.fromImage(QImage(imageQ1).scaled(250, 250, Qt.IgnoreAspectRatio))) self.pic1.resize(250, 250) self.pic1.setPixmap(imagep1) def button_close(self, a): a.close() def button_click(self): fname = self.mainLink im1 = fname file1 = 'pic_thumb/' file2 = 'pic_main/' lnk = "logo.png" im1.thumbnail((128, 128)) im1.save(file1 + lnk, "PNG" ) im1.thumbnail((300, 300)) im1.save(file2 + lnk, "PNG") g = Db() sel = g.selectn('datas', '', 1, {'pubID':'datas', 'name':'logo'}) if sel and sel['id'] > 0: pass else: g.insert('datas', {'pubID':'datas', 'name':'logo', 'description': lnk}) self.setCurrentPix() self.button_close(self)
class main_window(QMainWindow): def __init__(self): super(main_window, self).__init__() self.setWindowTitle('Minecraft Backup Manager') self.setGeometry(0, 0, 700, 520) self.setMinimumSize(700, 520) self.setMaximumSize(700, 520) center_widget(self) #Header self.header_label = QLabel(self) self.header_label.resize(700, 170) self.header_label.setPixmap(QPixmap(IMAGES['header'])) #menu_about self.menu_about = QMenu(self) self.menu_about.addAction('About Minecraft Backup Manager', lambda: self.open_about_minebackup()) self.menu_about.addAction('About Qt', lambda: msg_about_qt(self)) #btn_config self.btn_config = QPushButton(QIcon(IMAGES['config_icon']), '', self) self.btn_config.setGeometry(QRect(7, 7, 32, 32)) self.btn_config.setToolTip('Configuration') #btn_about self.btn_about = QPushButton('About', self) self.btn_about.setGeometry(QRect(45, 7, 80, 32)) self.btn_about.setMenu(self.menu_about) # list_backup self.list_backup = QListWidget(self) self.list_backup.setGeometry(QRect(20, 190, 450, 310)) # btn_new_backup self.btn_new_backup = QPushButton('New backup', self) self.btn_new_backup.setGeometry(QRect(485, 190, 200, 30)) # btn_restore_backup self.btn_restore_backup = QPushButton('Restore backup', self) self.btn_restore_backup.setGeometry(QRect(485, 260, 200, 30)) self.btn_restore_backup.setEnabled(False) # btn_remove_backup self.btn_remove_backup = QPushButton('Remove Backup', self) self.btn_remove_backup.setGeometry(QRect(485, 300, 200, 30)) self.btn_remove_backup.setEnabled(False) # CONNECT SIGNALS self.connect(self.btn_config, SIGNAL('clicked()'), self.open_config) self.connect(self.btn_new_backup, SIGNAL('clicked()'), self.open_new_backup) self.connect(self.btn_remove_backup, SIGNAL('clicked()'), self.remove_backup) self.connect(self.btn_restore_backup, SIGNAL('clicked()'), self.restore_backup) self.connect(self.list_backup, SIGNAL('itemClicked(QListWidgetItem *)'), self.enabled_buttons) self.load_backup_list() def load_backup_list(self): self.list_backup.clear() self.backup_list = load_backup_list() if self.backup_list is not False: for backup in self.backup_list.values(): if path.exists(backup['path']): self.list_item = QListWidgetItem(backup['name']) self.list_item.setToolTip('<b>Directory:</b> %s' % backup['path']) self.list_backup.addItem(self.list_item) else: msg_backup_folder_not_exists(self, backup['name']) remove_backup_name(backup['name']) def remove_backup(self): self.remove_question = msg_remove_backup(self) if self.remove_question is not False: self.backup_name = self.list_backup.currentItem().text() remove_backup(unicode(self.backup_name)) self.load_backup_list() def restore_backup(self): self.restore_question = msg_restore_backup(self) if self.restore_question is not False: self.backup_name = self.list_backup.currentItem().text() restore_backup(unicode(self.backup_name)) msg_restore_finishied(self, self.backup_name) def enabled_buttons(self): self.btn_remove_backup.setEnabled(True) self.btn_restore_backup.setEnabled(True) def open_config(self): self.configuration_window = config_window.config_window(self) self.configuration_window.show() def open_about_minebackup(self): self.about_minebackup = about_minebackup.about_minebackup(self) self.about_minebackup.show() def open_new_backup(self): self.new_backup_window = new_backup_window.new_backup_window(self) self.new_backup_window.show() # CONNECT SIGNALS self.connect(self.new_backup_window, SIGNAL('close()'), self.load_backup_list)
class pngDisplay(QWidget): def __init__(self, parent=None): super(pngDisplay, self).__init__(parent) #self.profiler = cProfile.Profile() # create the label that displays the image - cribbing from the Image # Viewer example in the Qt docs. self.imLabel = QLabel() self.imLabel.setBackgroundRole(QPalette.Base) self.imLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imLabel.setScaledContents(True) # Create a gray field to use when no png is available self.defaultPM = QPixmap(700,900) self.defaultPM.fill(QColor("gray")) # Create a scroll area within which to display our imLabel, this # enables the creation of horizontal and vertical scroll bars, when # the imLabel exceeds the size of the scroll area. self.scarea = QScrollArea() # The following two lines make sure that page up/dn gets through # the scrollarea widget and up to us. self.setFocusPolicy(Qt.ClickFocus) self.scarea.setFocusProxy(self) self.scarea.setBackgroundRole(QPalette.Dark) #self.scarea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) #self.scarea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scarea.setWidget(self.imLabel) # create the text label that will have the page number in it self.txLabel = QLabel(u"No image") self.txLabel.setAlignment(Qt.AlignBottom | Qt.AlignHCenter) self.txLabel.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel) # Create a spinbox to set the zoom from 15 to 200 with a label: # (originally a slider, hence the name) self.minZoom = 0.15 self.maxZoom = 2.00 self.zlider = QSpinBox() self.zlider.setRange(int(100*self.minZoom),int(100*self.maxZoom)) # connect the value change signal to a slot to handle it self.connect(self.zlider, SIGNAL("valueChanged(int)"), self.newZoomFactor) # create the to-width and to-height zoom buttons zoomWidthButton = QPushButton(u'to Width') self.connect(zoomWidthButton, SIGNAL("clicked()"), self.zoomToWidth) zoomHeightButton = QPushButton(u'to Height') self.connect(zoomHeightButton, SIGNAL("clicked()"), self.zoomToHeight) # Make an hbox to contain the spinbox and two pushbuttons, with # stretch on left and right to center the group. zlabel = QLabel( u'&Zoom ' + str(self.zlider.minimum()) + '-' + str(self.zlider.maximum()) + '%') zlabel.setBuddy(self.zlider) zhbox = QHBoxLayout() zhbox.addStretch(1) zhbox.addWidget(zlabel,0,Qt.AlignLeft) zhbox.addWidget(self.zlider,0) zhbox.addStretch(1) zhbox.addWidget(zoomWidthButton) zhbox.addWidget(zoomHeightButton) zhbox.addStretch(1) # With all the pieces in hand, create our layout basically a # vertical stack: scroll area, label, slider box. vbox = QVBoxLayout() # the image gets a high stretch and default alignment, the text # label hugs the bottom and doesn't stretch at all. vbox.addWidget(self.txLabel,0,Qt.AlignBottom) vbox.addWidget(self.scarea,10) vbox.addLayout(zhbox,0) self.setLayout(vbox) # Initialize assuming no book is open. self.ready = False # nothing to display # Recover the last-set zoom factor from the settings object, default 1.0 qv = IMC.settings.value("pngs/zoomFactor",QVariant(1.0)) self.zoomFactor = qv.toFloat()[0] # The following causes entry into newZoomFactor, below, which tests # self.ready, hence the latter has to be assigned-to first. self.zlider.setValue(int(self.zoomFactor*100)) self.clear() # local subroutine to initialize our contents for an empty edit. # called from _init_ and from newPosition when we discover the file # has been cleared on us. Don't reset the zoomFactor, leave it as # the user last set it. def clear(self): # Clear the page name, used by pqNotes IMC.currentImageNumber = None # will be name of last png file e.g. "002" # Clear the page filename, used in our caption label self.lastPage = QString() # last file name e.g. "002.png" # Clear the path to the pngs folder, used to fetch image files self.pngPath = QString() # Clear the index of the last-shown page in the page table # -1 means no page is being displayed. self.lastIndex = -1 # Clear the index of the next page to display, normally same as last self.nextIndex = -1 # Set not-ready to indicate no pngs directory available. self.ready = False # Clear out & release storage of our QImage and QPixmaps self.pixmap = QPixmap() # null pixmap self.image = QImage() self.noImage() # show gray image # Display a blank gray frame and "No Image" below. # Called from clear() above and from showPage when no valid image. def noImage(self) : self.imLabel.setPixmap(self.defaultPM) self.txLabel.setText(u"No image") self.lastIndex = -1 # didn't see a prior page self.nextIndex = -1 # This slot gets the main window's signal shuttingDown. # We save our current zoom factor into IMC.settings. def shuttingDown(self): IMC.settings.setValue("pngs/zoomFactor",QVariant(self.zoomFactor)) # This slot gets pqMain's signal docHasChanged(QString), telling # us that a different document has been loaded. This could be for # a successful File>Open, or a failed File>Open or File>New. # The bookPath is a null QString for File>New, or the full bookPath. # If the latter, we convert that into the path to the pngs folder, # and see if bookPath/pngs is a directory. If so, we set self.ready # to true, indicating it is worthwhile to try opening image files. # At this point the gray image is displayed and previously would remain displayed # until the user moved the cursor in some way, generating cursorPositionChanged. # That's a minor annoyance, to avoid it we will fake that signal now. def newFile(self, bookPath): if not bookPath.isNull(): # this was successful File>Open finf = QFileInfo(bookPath) self.pngPath = finf.absolutePath().append(u"/pngs/") finf = QFileInfo(self.pngPath) if finf.exists() and finf.isDir(): # looking good self.ready = True self.newPosition() else: # We could inform the user we couldn't find a pngs folder, # but you know -- the user is probably already aware of that. self.clear() # just put up the gray default image else: # It was a File>New self.clear() # This function is the slot that is connected to the editor's # cursorPositionChanged signal. Its input is cursor position and # the page table. Its output is to set self.nextIndex to the # desired next image table row, and to call showPage. def newPosition(self): if self.ready : # We have a book and some pngs. Find the position of the higher end # of the current selection. pos = IMC.editWidget.textCursor().selectionEnd() # Get the page table index that matches this position, or -1 # if that is above the first psep, or there is no page data self.nextIndex = IMC.pageTable.getIndex(pos) else :# No file loaded or no pngs folder found. self.nextIndex = -1 if self.nextIndex != self.lastIndex : self.showPage() # Display the page indexed by self.nextIndex. This is called when the cursor # moves to a new page (newPosition, above), or when the PageUp/Dn keys are used, # (keyPressEvent, below) or when the zoom factor changes in any of several ways. def showPage(self): # If self.lastIndex is different from self.nextIndex, the page has # changed, and we need to load a new image. if self.lastIndex != self.nextIndex : self.lastIndex = self.nextIndex # don't come here again until it changes. if self.lastIndex > -1 : # Form the image filename as a Qstring, e.g. "025" and save that for # use by pqNotes: IMC.currentImageNumber = IMC.pageTable.getScan(self.lastIndex) # dbg = unicode(IMC.currentImageNumber) # Form the complete filename by appending ".png" and save as # self.lastPage for use in forming our caption label. self.lastPage = QString(IMC.currentImageNumber).append(QString(u".png")) # dbg = unicode(self.lastPage) # Form the full path to the image. Try to load it as a QImage. pngName = QString(self.pngPath).append(self.lastPage) self.image = QImage(pngName,'PNG') # dbg = unicode(self.image) # dbg = self.image.isNull() # If that successfully loaded an image, make sure it is one byte/pixel. if not self.image.isNull() \ and self.image.format() != QImage.Format_Indexed8 : # It might be Format_Mono (1 bit/pixel) or even Format_RGB32. self.image = self.image.convertToFormat(QImage.Format_Indexed8,Qt.ColorOnly) # Convert the image to a pixmap. If it's null, so is the pixmap. self.pixmap = QPixmap.fromImage(self.image,Qt.ColorOnly) else : IMC.currentImageNumber = QString(u"n.a.") self.lastPage = QString() self.image = QImage() self.pixmap = QPixmap() if not self.pixmap.isNull(): # We successfully found and loaded an image and converted it to pixmap. # Load it in our label for display, set the zoom factor, and the caption. # We do this every time through (even if lastIndex equalled nextIndex) # because the zoomfactor might have changed. self.imLabel.setPixmap(self.pixmap) self.imLabel.resize( self.zoomFactor * self.pixmap.size() ) folio = IMC.pageTable.getDisplay(self.lastIndex) self.txLabel.setText(u"image {0} (folio {1})".format(self.lastPage,folio)) else: # no file was loaded. It's ok if pages are missing self.noImage() # display the gray image. # Catch the signal from the Zoom spinbox with a new value. # Store the new value as a float, and if we have a page, repaint it. def newZoomFactor(self,new_value): self.zoomFactor = new_value / 100 if self.ready : self.showPage() # Catch the click on zoom-to-width and zoom-to height. The job is basically # the same for both. 1: Using the QImage that should be in self.image, # scan the pixels to find the width (height) of the nonwhite area. # 2. Get the ratio of that to our image label's viewport width (height). # 4. Set that ratio as the zoom factor and redraw the image. And finally # 5. Set the scroll position(s) of our scroll area to left-justify the text. # # We get access to the pixels using QImage:bits() which gives us a PyQt4 # "voidptr" that we can index to get byte values. # def zoomToWidth(self): if (not self.ready) or (self.image.isNull()) : return # nothing to do here #self.profiler.enable() #dbg # Query the Color look-up table and build a list of the Green values # corresponding to each possible pixel value. Probably there are just # two colors so colortab is [0,255] but there could be more, depending # on how the PNG was defined, 16 or 32 or even 255 grayscale. colortab = [ int((self.image.color(c) >> 4) & 255) for c in range(self.image.colorCount()) ] ncols = self.image.width() # number of logical pixels across stride = (ncols + 3) & (-4) # number of bytes per scanline nrows = self.image.height() # number of pixels high vptr = self.image.bits() # uchar * bunch-o-pixel-bytes vptr.setsize(stride * nrows) # make the pointer indexable # Scan in from left and right to find the outermost dark spots. # Looking for single pixels yeilds too many false positives, so we # look for three adjacent pixels that sum to less than 32. # Most pages start with many lines of white pixels so in hopes of # establishing the outer edge early, we start at the middle, go to # the end, then do the top half. left_side = int(ncols/2) # leftmost dark spot seen so far # scan from the middle down for r in xrange(int(nrows/2)*stride, (nrows-1)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(left_side): pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair left_side = c # new, further-left, left margin break # no need to look further on this line pa = pb pb = pc # scan from the top to the middle, hopefully left_side is small now for r in xrange(0, int(nrows/2)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(left_side): pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair left_side = c # new, further-left, left margin break # no need to look further on this line pa = pb pb = pc # Now do the same for the right margin. right_side = int(ncols/2) # rightmost dark spot seen so far for r in xrange(int(nrows/2)*stride, (nrows-1)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(ncols-1,right_side,-1) : pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair right_side = c # new, further-right, right margin break pa = pb pb = pc for r in xrange(0, int(nrows/2)*stride, stride) : pa, pb = 255, 255 # virtual white outside border for c in xrange(ncols-1,right_side,-1) : pc = colortab[ ord(vptr[c + r]) ] if (pa + pb + pc) < 32 : # black or dark gray pair right_side = c # new, further-right, right margin break pa = pb pb = pc # The area with color runs from left_side to right_side. How does # that compare to the size of our viewport? Scale to that and redraw. #print('ls {0} rs {1} vp {2}'.format(left_side,right_side,self.scarea.viewport().width())) text_size = right_side - left_side + 2 port_width = self.scarea.viewport().width() self.zoomFactor = max( self.minZoom, min( self.maxZoom, port_width / text_size ) ) # the next line signals newZoomFactor, which calls showPage. self.zlider.setValue(int(100*self.zoomFactor)) # Set the scrollbar to show the page from its left margin. self.scarea.horizontalScrollBar().setValue(int( left_side * self.zoomFactor) ) #self.profiler.disable() #dbg #pstats.Stats(self.profiler).print_stats() # dbg def zoomToHeight(self): if (not self.ready) or (self.image.isNull()) : return # nothing to do here # Query the Color look-up table and build a list of the Green values # corresponding to each possible pixel value. Probably there are just # two colors so colortab is [0,255] but there could be more, depending # on how the PNG was defined, 16 or 32 or even 255 grayscale. colortab = [ int((self.image.color(c) >> 4) & 255) for c in range(self.image.colorCount()) ] ncols = self.image.width() # number of logical pixels across stride = (ncols + 3) & (-4) # number of bytes per scanline nrows = self.image.height() # number of pixels high vptr = self.image.bits() # uchar * bunch-o-pixel-bytes vptr.setsize(stride * nrows) # make the pointer indexable # Scan in from top and bottom to find the outermost rows with # significant pixels. top_side = -1 # The uppermost row with a significant spot of black offset = 0 # vptr index to the first/next pixel row for r in range(nrows) : pa, pb = 255, 255 # virtual white outside border for c in range(ncols) : pc = colortab[ ord(vptr[offset + c]) ] if (pa + pb + pc) < 32 : # black or dark gray triplet top_side = r # that's the row, break # ..so stop scanning pa, pb = pb, pc if top_side >= 0 : # we hit break # ..so don't scan down any further offset += stride # continue to next row # top_side indexes the first row with a significant blot if top_side == -1 : # never found one: an all-white page. bug out. return bottom_side = nrows # The lowest row with a significant blot offset = stride * nrows # vptr index to last/next row of pixels for r in range(nrows,top_side,-1) : offset -= stride pa, pb = 255, 255 # virtual white outside border for c in range(ncols) : pc = colortab[ ord(vptr[offset + c]) ] if (pa + pb + pc) < 32 : # black or dark gray triplet bottom_side = r break pa, pb = pb, pc if bottom_side < nrows : # we hit break # bottom_side is the lowest row with significant pixels. It must be # < nrows, there is at least one row (top_side) with a dot in it. # However if the page is mostly white, don't zoom to that extent. if bottom_side < (top_side+100) : return # seems to be a mostly-white page, give up # The text area runs from scanline top_side to bottom_side. text_height = bottom_side - top_side + 1 port_height = self.scarea.viewport().height() self.zoomFactor = max( self.minZoom, min( self.maxZoom, port_height / text_height ) ) self.zlider.setValue(int(100*self.zoomFactor)) # signals newZoomFactor->showPage # Set the scrollbar to show the page from its top margin. self.scarea.verticalScrollBar().setValue(int( top_side * self.zoomFactor) ) # Re-implement the parent's keyPressEvent in order to provide zoom: # ctrl-plus increases the image size by 1.25 # ctrl-minus decreases the image size by 0.8 # Also trap pageup/dn and use to walk through images. # At this point we do not reposition the editor to match the page viewed. # we page up/dn but as soon as focus returns to the editor and the cursor # moves, this display will snap back to the edited page. As a user that # seems best, come over to Pngs and page ahead to see what's coming, then # back to the editor to read or type. def keyPressEvent(self, event): # assume we will not handle this key and clear its accepted flag event.ignore() # If we are initialized and have displayed some page, look at the key if self.ready: kkey = int( int(event.modifiers()) & IMC.keypadDeModifier) | int(event.key()) if kkey in IMC.zoomKeys : # ctl/cmd + or -, do the zoom event.accept() fac = (0.8) if (kkey == IMC.ctl_minus) else (1.25) fac *= self.zoomFactor # target zoom factor if (fac >= self.minZoom) and (fac <= self.maxZoom): # keep in bounds self.zoomFactor = fac self.zlider.setValue(int(100*fac)) self.showPage() elif (event.key() == Qt.Key_PageUp) or (event.key() == Qt.Key_PageDown) : event.accept() # real pgUp or pgDn, we do it fac = 1 if (event.key() == Qt.Key_PageDown) else -1 fac += self.lastIndex if (fac >= 0) and (fac < IMC.pageTable.size()) : # not off either end of the book, so, self.nextIndex = fac self.showPage() if not event.isAccepted() : # we don't do those, pass them on super(pngDisplay, self).keyPressEvent(event)
class FindDlg(QDialog): #def __init__(self, info, parent=None): def __init__(self, tab, dlg, parent=None): super(FindDlg, self).__init__(parent, Qt.CustomizeWindowHint|Qt.WindowTitleHint) #self.setModal(False) #self.table = tab.currentWidget() self.tab = tab self.dlg = dlg #print(self.dlg) self.setWindowTitle('PV Search') self.pattern = "" self.foundPVCount = 0 self.foundPVPos = [] self.pvIndex = 0 #self.pvListStr = "" self.findLineEdit = QLineEdit() self.findLineEdit.setToolTip("use *, ? in the search pattern") QObject.connect(self.findLineEdit, SIGNAL(_fromUtf8("textChanged(QString)")), self.getPattern) self.findNextButton = QPushButton("> Next", self) self.findNextButton.setToolTip("Find next PV which matches the pattern") self.findNextButton.resize(self.findNextButton.sizeHint()) self.findNextButton.clicked.connect(self.findNext) findPrevButton = QPushButton("< Previous",self) findPrevButton.setToolTip("Find previous PV which matches the pattern") findPrevButton.resize(findPrevButton.sizeHint()) findPrevButton.clicked.connect(self.findPrev) closeButton = QPushButton("Close") closeButton.resize(closeButton.sizeHint()) #closeButton.clicked.connect(self.close) closeButton.clicked.connect(self.cleanup) self.infoLabel = QLabel("%d PVs found"%self.foundPVCount) self.infoLabel.resize(self.infoLabel.sizeHint()) layout = QGridLayout(self) layout.addWidget(self.findLineEdit, 0, 0, 1, 3)#row, col, how-many-rows, col-span layout.addWidget(self.findNextButton, 1, 0, 1, 1) layout.addWidget(findPrevButton, 1, 1, 1, 1) layout.addWidget(closeButton, 1, 2, 1, 1) layout.addWidget(self.infoLabel, 2, 0, 1, 3) self.setLayout(layout) def getPattern(self): self.pattern = str(self.findLineEdit.text()) def highlightPV(self): table = self.tab.currentWidget() for j in range(table.rowCount()): table.item(j,0).setBackground(QBrush(Qt.white)) pattern_ = self.pattern pattern = fnmatch.translate(pattern_) regex = re.compile(pattern, re.IGNORECASE) foundPVPos = []#pv position -- the row where PV is for i in range(table.rowCount()): pvName = str(table.item(i,0).text()) if regex.search(pvName): foundPVPos.append(i) table.item(i,0).setBackground(QBrush(Qt.yellow)) self.foundPVCount = len(foundPVPos) #print(foundPVPos) if self.foundPVCount > 0: self.infoLabel.setText("%d PVs found: the first PV is at row #%d, the last @%d" %(self.foundPVCount,foundPVPos[0]+1, foundPVPos[-1]+1)) else: self.infoLabel.setText("No matching PV found. Remember to use * or ? for searching") return foundPVPos def findNext(self): table = self.tab.currentWidget() self.foundPVPos = self.highlightPV() #print("find next %d PVs: %s"%(self.foundPVCount, self.pattern)) if self.foundPVCount>0: #print("pv index: %d"%self.pvIndex) if self.pvIndex >= self.foundPVCount or self.pvIndex < 0: self.pvIndex = 0 table.setCurrentCell(self.foundPVPos[self.pvIndex], 0) self.pvIndex += 1 #print("next pv position: %d / %d"%(self.pvIndex, self.foundPVPos[self.pvIndex])) def findPrev(self): table = self.tab.currentWidget() self.foundPVPos = self.highlightPV() #print("find prev %d PVs: %s"%(self.foundPVCount, self.pattern)) if self.foundPVCount>0: #print("pv index: %d"%self.pvIndex) if self.pvIndex <= 0 or self.pvIndex >= self.foundPVCount: self.pvIndex = self.foundPVCount self.pvIndex -= 1 table.setCurrentCell(self.foundPVPos[self.pvIndex], 0) #print("prev pv position: %d / %d"%(self.pvIndex, self.foundPVPos[self.pvIndex])) def cleanup(self): #print("cleanup, then close") self.dlg[0]=0 # make sure Find Dialog could pop up after it is closed #print(self.dlg) table = self.tab.currentWidget() for i in range(len(self.foundPVPos)): table.item(self.foundPVPos[i],0).setBackground(QBrush(Qt.white)) self.close()
class BillboardDisplay(QMainWindow): def __init__(self, parent=None, workdir=None, fontsize=42): super(BillboardDisplay, self).__init__(parent) self.workdir = workdir self.logger = logging.getLogger('display') self.logger.info('Working directory: {}'.format(self.workdir)) self.current_display = os.path.join(self.workdir, 'current.jpg') desktop = QDesktopWidget() self.display = QWidget(self) size = desktop.availableGeometry(desktop.primaryScreen()) self.display.resize(size.width(), size.height()) self.display.setWindowTitle("Billboard") self.image_label = QLabel(self.display) self.image_label.resize(size.width(), size.height()) self.text_label = QLabel(self.display) self.text_label.resize(size.width(), size.height()) self.text_label.setMargin(100) self.text_label.setStyleSheet(''' QLabel {{ font-size: {}pt; font-weight: bold; color: #eeeeee; text-align: center; }} '''.format(fontsize)) self.text_label.setWordWrap(True) self.text_label.setAlignment(Qt.AlignCenter) dse = QGraphicsDropShadowEffect() dse.setBlurRadius(0) dse.setXOffset(5) dse.setYOffset(5) dse.setColor(QColor(0, 0, 0, 255)) self.text_label.setGraphicsEffect(dse) QObject.connect(self, SIGNAL("updateimage"), self.display_image) QObject.connect(self, SIGNAL("updatecurrent"), self.take_screenshot) def update_image(self, imagepath): self.emit(SIGNAL("updateimage"), imagepath) def update_current(self): self.emit(SIGNAL("updatecurrent"), self.current_display) def display(self, imagepath, text): self.display_text(text) self.display_image(imagepath) self.showFullScreen() def display_image(self, imagepath): pix = QPixmap(imagepath) self.image_label.setPixmap( pix.scaled(self.display.size(), Qt.KeepAspectRatioByExpanding)) def display_text(self, text): self.text_label.setText('"{}"'.format(text)) def take_screenshot(self, path): pixmap = QPixmap(QPixmap.grabWidget(self.display)) pixmap.save(path) self.logger.debug('Saving {}'.format(path))
#!/usr/bin/env python '''minimal Qt example''' if __name__ == '__main__': import require import cothread from cothread.catools import * from PyQt4.QtGui import QLabel cothread.iqt() # make a label widget (None is the parent, this is top-level widget) label = QLabel('Hello World', None) label.resize(200, 50) # must show top-level widgets manually label.show() # animate label def signal(value): label.setText('DCCT %f %s' % (value, value.units)) camonitor('SR21C-DI-DCCT-01:SIGNAL', signal, format=FORMAT_CTRL) if __name__ == '__main__': cothread.WaitForQuit()
class OverviewWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.neutral_monsters_title = QLabel(self) self.neutral_monsters_total = QLabel(self) self.neutral_monsters_title.resize(230, 30) self.neutral_monsters_total.resize(230, 70) self.neutral_monsters_title.move(240, 115) self.neutral_monsters_total.move(240, 155) self.neutral_monsters_title.setAlignment(Qt.AlignCenter) self.neutral_monsters_total.setAlignment(Qt.AlignCenter) self.neutral_monsters_title.setStyleSheet( "QLabel {font: 14pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.neutral_monsters_total.setStyleSheet( "QLabel {font: 24pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.minions_title = QLabel(self) self.minions_total = QLabel(self) self.minions_title.resize(230, 30) self.minions_total.resize(230, 70) self.minions_title.move(0, 115) self.minions_total.move(0, 155) self.minions_title.setAlignment(Qt.AlignCenter) self.minions_total.setAlignment(Qt.AlignCenter) self.minions_title.setStyleSheet( "QLabel {font: 14pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.minions_total.setStyleSheet( "QLabel {font: 24pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.champions_title = QLabel(self) self.champions_total = QLabel(self) self.champions_title.resize(230, 30) self.champions_total.resize(230, 70) self.champions_title.move(240, 0) self.champions_total.move(240, 40) self.champions_title.setAlignment(Qt.AlignCenter) self.champions_total.setAlignment(Qt.AlignCenter) self.champions_title.setStyleSheet( "QLabel {font: 14pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.champions_total.setStyleSheet( "QLabel {font: 24pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.assists_title = QLabel(self) self.assists_total = QLabel(self) self.assists_title.resize(230, 30) self.assists_total.resize(230, 70) self.assists_title.move(480, 0) self.assists_total.move(480, 40) self.assists_title.setAlignment(Qt.AlignCenter) self.assists_total.setAlignment(Qt.AlignCenter) self.assists_title.setStyleSheet( "QLabel {font: 14pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.assists_total.setStyleSheet( "QLabel {font: 24pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.turrets_title = QLabel(self) self.turrets_total = QLabel(self) self.turrets_title.resize(230, 30) self.turrets_total.resize(230, 70) self.turrets_title.move(480, 115) self.turrets_total.move(480, 155) self.turrets_title.setAlignment(Qt.AlignCenter) self.turrets_total.setAlignment(Qt.AlignCenter) self.turrets_title.setStyleSheet( "QLabel {font: 14pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.turrets_total.setStyleSheet( "QLabel {font: 24pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.win_loss_title = QLabel(self) self.win_loss_total = QLabel(self) self.win_loss_title.resize(230, 30) self.win_loss_total.resize(230, 70) self.win_loss_title.move(0, 0) self.win_loss_total.move(0, 40) self.win_loss_title.setAlignment(Qt.AlignCenter) self.win_loss_total.setAlignment(Qt.AlignCenter) self.win_loss_title.setStyleSheet( "QLabel {font: 14pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) self.win_loss_total.setStyleSheet( "QLabel {font: 24pt ;color:black; background-color:tan; border-style: outset; border-width: 2px; border-color: black}" ) def showStats(self, values): if len(values) == 7: self.win_loss_title.setText('Wins/Losses') self.win_loss_total.setText(str(values[0]) + '/' + str(values[6])) else: self.win_loss_title.setText('Wins') self.win_loss_total.setText(str(values[0])) if len(values) > 2: self.neutral_monsters_title.setText('Neutral Monsters Killed') self.neutral_monsters_total.setText(str(values[4])) self.champions_title.setText('Champions Killed') self.champions_total.setText(str(values[1])) self.minions_title.setText('Minions Killed') self.minions_total.setText(str(values[3])) self.assists_title.setText('Assists') self.assists_total.setText(str(values[2])) self.turrets_title.setText('Turrets Killed') self.turrets_total.setText(str(values[5]))
class Window(QtGui.QMainWindow): def __init__(self): super(Window, self).__init__() self.setGeometry(50, 50, 900, 590) self.setWindowTitle("CUBS FaceDemo Enroller") self.home() def home(self): self.imgindex = 0 self.selectedname = "" self.imglen = 0 self.delbtn = QtGui.QPushButton("Delete Entry", self) self.delbtn.resize(100, 30) self.delbtn.move(200, 125) # self.delbtn.move(0, 0) self.rightname = QLabel("", self) self.rightname.move(350, 5) self.rightname.resize(600, 20) self.rightname.setAlignment(Qt.AlignCenter) self.btn = QtGui.QPushButton("Enroll", self) # self.btn.clicked.connect() self.btn.resize(80, 30) self.btn.move(10, 125) self.nextbtn = QtGui.QPushButton("Next", self) self.delimagebtn = QtGui.QPushButton("Delete Image", self) self.previousbtn = QtGui.QPushButton("Previous", self) self.nextbtn.move(750, 530) self.delimagebtn.move(550, 530) self.previousbtn.move(450, 530) self.firstnametext = QLabel(self) self.firstnametext.setText("First Name:") self.firstnametext.move(10, 10) self.firstnamefield = QLineEdit(self) self.firstnamefield.setObjectName("First Name") self.firstnamefield.resize(300, 30) self.firstnamefield.move(100, 10) lastnametext = QLabel(self) lastnametext.setText("Last Name:") lastnametext.move(10, 50) self.lastnamefield = QLineEdit(self) self.lastnamefield.setObjectName("First Name") self.lastnamefield.resize(300, 30) self.lastnamefield.move(100, 50) self.dirbtn = QtGui.QPushButton("Choose Directory", self) self.dirbtn.resize(140, 30) self.dirbtn.move(10, 90) self.dirfield = QLineEdit(self) self.dirfield.setObjectName("Directory") self.dirfield.resize(250, 30) self.dirfield.move(150, 90) self.status = QLabel(self) self.status.move(10, 563) self.status.resize(400, 20) self.status.setText("Ready") self.rebuild = QtGui.QPushButton("Add Image", self) self.rebuild.move(650, 530) self.rebuild.resize(100, 30) self.listsize = QtGui.QLabel(self) self.listsize.setText(" Persons Enrolled") self.listsize.resize(200, 20) self.listsize.move(10, 160) self.list = QListWidget(self) self.list.resize(389, 380) self.list.move(10, 180) self.stat("Pulling list") refresh_list_elements(self.list, self.listsize) self.stat("Ready") self.image = QLabel(self) self.image.resize(490, 490) self.image.move(405, 30) self.list.doubleClicked.connect(self.on_double_click) self.connect(self, SIGNAL('triggered()'), self.closeEvent) self.connect(self.rebuild, SIGNAL("clicked()"), self.add_image) self.connect(self.nextbtn, SIGNAL("clicked()"), self.next_image) self.connect(self.previousbtn, SIGNAL("clicked()"), self.previous_image) self.connect(self.delimagebtn, SIGNAL("clicked()"), self.delete_image) self.connect(self.dirbtn, SIGNAL("clicked()"), self.opendir) self.connect(self.delbtn, SIGNAL("clicked()"), self.button_delete) self.connect(self.btn, SIGNAL("clicked()"), self.button_click) self.show() def closeEvent(self, event): self.stat("Saving Changes") save() print "Changes saved" print "Rebuilding Vectors" self.rebuild_vector() self.destroy() def rebuild_vector(self): # feature_build.generate_vectors() pass def stat(self, stat): self.status.setText(stat) def add_image(self): self.dialog = QFileDialog(self) directory = self.dialog.getOpenFileName(self, 'Select Directory') if directory: self.dirfield.setText(directory) img_directory = str(self.dirfield.text()) picarray = test_create_image(img_directory, True) # enroll_images.images_to_array(img_directory, True) dict_personinfo[self.selectedname].append(picarray) refresh_list_elements(self.list, self.listsize) self.init_images() self.dirfield.setText('') def next_image(self): check = self.imgindex + 1 if (check >= self.imglen): self.display_image(0) self.imgindex = 0 else: self.display_image(check) self.imgindex += 1 def previous_image(self): check = self.imgindex - 1 if (check < 0): self.display_image(self.imglen - 1) self.imgindex = self.imglen - 1 else: self.display_image(check) self.imgindex -= 1 def delete_image(self): # dict_personinfo = obtain_info() dict_personinfo[self.selectedname].pop(self.imgindex) if (len(dict_personinfo[self.selectedname]) == 0): dict_personinfo.pop(self.selectedname, None) # with open('data/gui_dict.pickle', 'wb') as handle: # cPickle.dump(dict_personinfo, handle) self.stat("Deleted " + self.selectedname) refresh_list_elements(self.list, self.listsize) self.image.clear() self.rightname.setText("") else: # with open('data/gui_dict.pickle', 'wb') as handle: # cPickle.dump(dict_personinfo, handle) self.stat("Deleted image for " + self.selectedname) refresh_list_elements(self.list, self.listsize) self.init_images() def display_image(self, index=0): img = self.get_images() self.imglen = len(img) img = img[index] img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) height, width, channel = img.shape bytesPerLine = 3 * width qimg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888) pixmap = QtGui.QPixmap(qimg) pixmap = pixmap.scaled(self.image.size()) self.image.setPixmap(pixmap) def get_images(self): # dict_personinfo = obtain_info() arr_images = [] for i in range(len(dict_personinfo[self.selectedname])): frame = dict_personinfo[self.selectedname][i][0] rectangle = dict_personinfo[self.selectedname][i][1] img = np.array(Image.fromarray(frame)) cv2.rectangle(img, (int(rectangle[0][0]), int(rectangle[0][3])), (int(rectangle[0][2]), int(rectangle[0][1])), (0, 255, 0), 40) cv2.circle(img, (int(rectangle[0][5]), int(rectangle[0][6])), 10, (0, 255, 0), 40) cv2.circle(img, (int(rectangle[0][7]), int(rectangle[0][8])), 10, (0, 255, 0), 40) cv2.circle(img, (int(rectangle[0][9]), int(rectangle[0][10])), 10, (0, 255, 0), 40) cv2.circle(img, (int(rectangle[0][11]), int(rectangle[0][12])), 10, (0, 255, 0), 40) cv2.circle(img, (int(rectangle[0][13]), int(rectangle[0][14])), 10, (0, 255, 0), 40) print(rectangle) arr_images.append(img) self.imglen = len(arr_images) return arr_images def on_double_click(self): self.selectedname = str(self.list.currentItem().text()) self.rightname.setText(self.selectedname) self.init_images() def init_images(self): self.imgindex = 0 img = self.get_images() img = img[0] img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) height, width, channel = img.shape bytesPerLine = 3 * width qimg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888) pixmap = QtGui.QPixmap(qimg) pixmap = pixmap.scaled(self.image.size()) self.image.setPixmap(pixmap) def opendir(self): self.dialog = QFileDialog(self) directory = self.dialog.getExistingDirectory(self, 'Select Directory') if directory: self.dirfield.setText(directory) def button_delete(self): if (str(self.list.currentItem().text()) != None): # dict_personinfo = obtain_info() dict_personinfo.pop(str(self.list.currentItem().text()), None) # with open('data/gui_dict.pickle', 'wb') as handle: # cPickle.dump(dict_personinfo, handle) self.stat("Deleted " + str(self.list.currentItem().text())) refresh_list_elements(self.list, self.listsize) self.image.clear() self.rightname.clear() else: pass def button_click(self): self.stat("Pulling list") # dict_personinfo = obtain_info() self.stat("Ready") name = ['', ''] name[0] = str(self.firstnamefield.text()) name[1] = str(self.lastnamefield.text()) name[0] = name[0].replace(" ", "") name[1] = name[1].replace(" ", "") img_directory = str(self.dirfield.text()) self.stat("Detecting Face") if img_directory == "" or len(name[0]) == 0: picarray = [] else: picarray = test_create_image( img_directory, False) # Just a testing filler for now # picarray = enroll_images.images_to_array(img_directory, False) # feature_build.generate_vectors() if len(picarray) != 0: dict_personinfo[name[0] + " " + name[1]] = {} dict_personinfo[name[0] + " " + name[1]] = picarray if img_directory == "" or len(name[0]) == 0: self.stat("Failed to add " + name[0] + " " + name[1]) else: self.stat("Writing") # with open('data/gui_dict.pickle', 'wb') as handle: # cPickle.dump(dict_personinfo, handle) self.stat("Added " + name[0] + " " + name[1] + " with " + str(len(picarray)) + " images") else: self.stat("Failed to add " + name[0] + " " + name[1]) # feature_build.generate_vectors() self.firstnamefield.setText('') self.lastnamefield.setText('') self.dirfield.setText('') # self.list.addItem(name[0] + " " + name[1]) refresh_list_elements(self.list, self.listsize)
class ChampionTab(QLabel): def __init__(self, parent=None): QWidget.__init__(self, parent) self.resize(670, 50) self.setStyleSheet( "QLabel {color: black; background-color: gold; border-radius:10px}" ) self.champPic = QLabel(self) self.champPic.setScaledContents(True) self.champPic.resize(40, 40) self.champPic.move(5, 5) self.champName = QLabel(self) self.champName.setStyleSheet("QLabel {font: 14px}") self.champName.resize(100, 40) self.champName.move(46, 5) self.numOfSessions = QLabel(self) self.numOfSessions.setAlignment(Qt.AlignCenter) self.numOfSessions.resize(40, 40) self.numOfSessions.move(147, 5) self.winRatio = QLabel(self) self.winRatio.setAlignment(Qt.AlignCenter) self.winRatio.resize(60, 40) self.winRatio.move(188, 5) self.kda = QLabel(self) self.kda.setAlignment(Qt.AlignCenter) self.kda.resize(200, 40) self.kda.move(249, 5) self.cs = QLabel(self) self.cs.setAlignment(Qt.AlignCenter) self.cs.resize(60, 40) self.cs.move(450, 5) def setIcon(self, champIcon): self.champPic.setPixmap(champIcon) def setName(self, name): self.champName.setText(name) def setNumOfSessions(self, num): self.numOfSessions.setText(str(num)) def setWinRatio(self, winRate): self.winRatio.setText(str(winRate) + '%') def setKDA(self, kills, deaths, assists): self.kda.setText( str(kills) + " / " + str(deaths) + " / " + str(assists)) def setCS(self, cs): self.cs.setText(str(cs))
class CImprovedButton(QToolButton): def __init__(self, parent=None): QToolButton.__init__(self, parent) #TESTO ALTERNATIVO #Spesso se il pulsante ha icona troppo grossa e quando per ragioni di spazio o altro non si può spostare #o ridimensionare il pulsante stesso, la label ha posizioni assurde e schifose. Aggiungerne una "+ controllabile" #è l'unico modo.. self.__fixed_label = QLabel("alternative label", self) self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.__fixed_label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__font = QtGui.QFont("Arial", 10) self.__fixed_label.setFont(self.__font) self.__fixed_label.show() #INDICATORE STILE iOS self.__indicator = QLabel("0", self) self.__indicator.setStyleSheet("border-image: url(':/images/backgrounds/indicator.png'); padding-right:1px; color: white;") self.__indicator.geometry().setWidth(25) self.__indicator.geometry().setHeight(20) self.__indicator.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__indicator.setVisible(False) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) #default top-right corner #Quando il pulsante viene ridimensionato (designer o meno) devo anche sistemare la label di conseguenza self.resizeEvent = self.__onResize self.__indicator.resizeEvent = self.__on_indicator_Resize self.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.clicked.connect(self.stopAllAnimations) #BLINK self.__blink_timer = QTimer(parent) self.__blink_timer.timeout.connect(self.__on_blink_timer) self.__blink_timer_interval = 1000 #FADING self.__opacity_effect = QGraphicsOpacityEffect() self.__fading_timer = QTimer(parent) self.__fading_timer.timeout.connect(self.__on_fading_timer) self.__FADE_TYPE = Enum("IN", "OUT") self.__fade_time = 20 self.__opacity = 1.0 self.__opacity_fading_coefficient = 0.02 self.__selected_fade_type = self.__FADE_TYPE.IN # ANIMAZIONI GROW self.__animationGrow = QPropertyAnimation(self, "iconSize", self) self.__animationGrow.setDuration(1000) self.__animationGrow.setEasingCurve(QEasingCurve.Linear) self.__animationGrow.finished.connect(self.__on_growed) self.__animationShrink = QPropertyAnimation(self, "iconSize", self) self.__animationShrink.setDuration(1000) self.__animationShrink.setEasingCurve(QEasingCurve.Linear) self.__animationShrink.finished.connect(self.__on_shrinked) self.__defaultIconDimension = 60 self.__iconGrowsBy = 40 self.__growing = False # ANIMAZIONI BOUNCE self.__animationUp = QPropertyAnimation(self, "pos", self) self.__animationUp.setDuration(200) self.__animationUp.setEasingCurve(QEasingCurve.Linear) self.__animationUp.finished.connect(self.__on_top_reached) self.__animationBounce = QPropertyAnimation(self, "pos", self) self.__animationBounce.setDuration(1000) self.__animationBounce.setEasingCurve(QEasingCurve.OutBounce) self.__animationBounce.finished.connect(self.__on_bounce_finished) self.__bouncing = False self.__startPos = QPoint(self.pos().x(), self.pos().y()) #PIXMAP & MASCHERA self.__pmap = QPixmap(self.size()) self.__pmap_fname = "" self.__show_mask_preview = False def setDefaultIconSize(self, value): """ Sets default icon size when growing stops. @param value: size (both width and height) @type value: int """ self.__defaultIconDimension = value def getDefaultIconSize(self): return self.__defaultIconDimension defaultIconSize = QtCore.pyqtProperty("int", getDefaultIconSize, setDefaultIconSize) def setFixetTextVisibility(self, bool): """ Sets if fixed text is visible or not. @param bool: visible or not @type bool: bool """ self.__fixed_label.setVisible(bool) def getFixetTextVisibility(self): return self.__fixed_label.isVisible() fixetTextVisibility = QtCore.pyqtProperty("bool", fget=getFixetTextVisibility, fset=setFixetTextVisibility) def setFixedText(self, txt): """ Sets text on the button. @param txt: text @type txt: string """ self.__fixed_label.setText(txt) def getFixedText(self): return self.__fixed_label.text() fixedText = QtCore.pyqtProperty("QString", getFixedText, setFixedText) def setFixedTextPos(self, qpoint): """ Sets text position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__fixed_label.move(qpoint) def getFixedTextPos(self): return self.__fixed_label.pos() fixedTextPos = QtCore.pyqtProperty("QPoint", getFixedTextPos, setFixedTextPos) def setFixedTextFont(self, font): """ Sets text font. @param font: Font for fixed text. @type font: QFont """ self.__font = font self.__fixed_label.setFont(self.__font) def getFixedTextFont(self): return self.__font fixedTextFont = QtCore.pyqtProperty("QFont", getFixedTextFont, setFixedTextFont) #FUNZIONI INDICATORE def setIndicatorVisibility(self, bool): """ Sets if indicator is visible or not. @param bool: visible or not @type bool: bool """ self.__indicator.setVisible(bool) def getIndicatorVisibility(self): return self.__indicator.isVisible() indicatorVisibility = QtCore.pyqtProperty("bool", fget=getIndicatorVisibility, fset=setIndicatorVisibility) def setIndicatorPos(self, qpoint): """ Sets indicator position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__indicator.move(qpoint) def getIndicatorPos(self): return self.__indicator.pos() indicatorPos = QtCore.pyqtProperty("QPoint", getIndicatorPos, setIndicatorPos) def setIndicatorSize(self, size): """ Sets indicator size. @param size: Size @type size: QSize """ self.__indicator.resize(size) def getIndicatorSize(self): return self.__indicator.size() indicatorSize = QtCore.pyqtProperty("QSize", getIndicatorSize, setIndicatorSize) def setIndicatorFont(self, font): """ Sets indicator text font. @param font: Font for indicator text. @type font: QFont """ self.__indicator.setFont(font) def getIndicatorFont(self): return self.__indicator.font() indicatorFont = QtCore.pyqtProperty("QFont", getIndicatorFont, setIndicatorFont) ## FUNZIONI PER BLINK def __on_blink_timer(self): self.setVisible(not (self.isVisible())) def setBlinking(self, blink): """ Sets if the button have to blink or not. @param blink: blinking or not @type blink: bool """ if blink: self.__blink_timer.setInterval(self.__blink_timer_interval) self.__blink_timer.start() else: self.__blink_timer.stop() self.setVisible(True) def setBlinkInterval(self, value): """ Sets blink interval. @param blink: blink interval (msec) @type blink: int """ self.__blink_timer_interval = value def getBlinkInterval(self): return self.__blink_timer_interval blinkInterval = QtCore.pyqtProperty("int", getBlinkInterval, setBlinkInterval) ##FUNZIONI PER FADING def fadeIn(self): """ Button fades in from completely invisible to completely visible. """ self.__opacity = 0.0 self.__selected_fade_type = self.__FADE_TYPE.IN self.__fading_timer.start(self.__fade_time) def fadeOut(self): """ Button fades out from completely visible to completely invisible. """ self.__selected_fade_type = self.__FADE_TYPE.OUT self.__fading_timer.start(self.__fade_time) def setFadeTime(self, value): """ Sets fading time. Everytime interval is reached, alpha is increased (or decreased) by __opacity_fading_coefficient. @param value: fade time (msec) @type value: int """ self.__fade_time = value def getFadeTime(self): return self.__fade_time fadeInterval = QtCore.pyqtProperty("int", getFadeTime, setFadeTime) def setFadeCoefficient(self, value): """ Sets fading coefficient. Alpha is increased (or decreased) by this value. @param value: coefficient (min 0.0 - max 1.0) @type value: float """ self.__opacity_fading_coefficient = value def getFadeCoefficient(self): return self.__opacity_fading_coefficient fadeCoefficient = QtCore.pyqtProperty("double", getFadeCoefficient, setFadeCoefficient) def __on_fading_timer(self): if self.__selected_fade_type == self.__FADE_TYPE.OUT: if self.__opacity > 0: self.__opacity -= self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() if self.__selected_fade_type == self.__FADE_TYPE.IN: if self.__opacity <= 1.0: self.__opacity += self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() # FUNZIONI PER GROW\SHRINK def __on_growed(self): self.__animationShrink.setStartValue(QSize(self.iconSize().width(), self.iconSize().height())) self.__animationShrink.setEndValue( QSize(self.iconSize().width() - self.__iconGrowsBy, self.iconSize().height() - self.__iconGrowsBy)) self.__animationShrink.start() def __on_shrinked(self): self.__animationGrow.setStartValue(QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() def startGrow(self): """ Button ICON starts to grow and shrink to standard value when maximum size (configured) is reached """ if self.__growing: return self.__animationGrow.setStartValue(QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() self.__growing = True def stopGrow(self): if self.__animationGrow.startValue().toSize() != QSize(0, 0) and self.__animationShrink.startValue().toSize() != QPoint( 0, 0): self.__animationGrow.stop() self.__animationShrink.stop() self.setIconSize(QSize(self.__defaultIconDimension, self.__defaultIconDimension)) self.__growing = False #FUNZIONI PER BOUNCE def startBounce(self): """ Button starts to bounce requiring attention. """ if self.__bouncing: return self.__startPos = QPoint(self.pos().x(), self.pos().y()) self.__animationUp.setStartValue(QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationUp.setEndValue(QPoint(self.__startPos.x(), self.__startPos.y() - self.geometry().height())) self.__animationUp.start() self.__bouncing = True def stopBounce(self): if self.__animationUp.startValue().toPoint() != QPoint(0,0) and self.__animationBounce.startValue().toPoint() != QPoint(0,0): self.__animationBounce.stop() self.__animationUp.stop() self.setGeometry(self.__startPos.x(), self.__startPos.y(), self.geometry().width(), self.geometry().height()) self.__bouncing = False def __on_top_reached(self): self.__animationBounce.setStartValue(QPoint(self.pos().x(), self.pos().y())) self.__animationBounce.setEndValue(QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationBounce.start() def __on_bounce_finished(self): self.__animationUp.start() def stopAllAnimations(self): self.stopBounce() self.stopGrow() #FUNZIONI PER PIXMAP & MASCHERA def setPixmapFile(self, image_file): self.__pmap = image_file self.__pmap.scaled(self.size()) #NB: Il pixmap deve essere BIANCO e NERO. Con heuristicMask il primo pixel in alto a sinistra (0,0) viene #usato per decidere il colore trasparente, tutto il resto è visibile. def getPixmapFile(self): return self.__pmap pixmapFile = QtCore.pyqtProperty("QPixmap", getPixmapFile, setPixmapFile) def applyMask(self, bool): self.__show_mask_preview = bool if bool: self.setMask(QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) else: self.setMask(QBitmap()) def getMask(self): return self.__show_mask_preview appliedMask = QtCore.pyqtProperty("bool", fget=getMask, fset=applyMask) def __onResize(self, event): self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) self.__pmap.scaled(self.size()) if self.__show_mask_preview: self.setMask(QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) def __on_indicator_Resize(self, event): self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0))
def __init__(self, parent=None): QMainWindow.__init__(self,parent) self.parent = parent self.settings = QSettings() try: self.setAttribute(Qt.WA_Maemo5AutoOrientation, True) self.setAttribute(Qt.WA_Maemo5StackedWindow, True) isMAEMO = True except: isMAEMO = False self.setWindowTitle("KhtSync About") #Resize window if not maemo if not isMAEMO: self.resize(800, 600) aboutScrollArea = QScrollArea(self) aboutScrollArea.setWidgetResizable(True) awidget = QWidget(aboutScrollArea) awidget.setMinimumSize(480,600) awidget.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding) aboutScrollArea.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding) #Kinetic scroller is available on Maemo and should be on meego try: scroller = aboutScrollArea.property("kineticScroller") #.toPyObject() scroller.setEnabled(True) except: pass aboutLayout = QVBoxLayout(awidget) aboutIcon = QLabel() aboutIcon.setPixmap( QIcon.fromTheme('khtsync').pixmap(128,128)) aboutIcon.setAlignment( Qt.AlignCenter or Qt.AlignHCenter ) aboutIcon.resize(128,128) aboutLayout.addWidget(aboutIcon) aboutLabel = QLabel('''<center><b>KhtSync</b> %s <br><br>A tool to sync folder over SSH <br>Licenced under GPLv3 <br>By Benoît HERVIER (Khertan) <br><br><br><b>Bugtracker : </b>http://khertan.net/khtsync:bugs <br><b>Sources : </b>http://gitorious.org/khtsync <br><b>Www : </b>http://khertan.net/khtsync </center>''' % __version__) aboutLayout.addWidget(aboutLabel) self.bugtracker_button = QPushButton('BugTracker') self.bugtracker_button.clicked.connect(self.open_bugtracker) self.website_button = QPushButton('Website') self.website_button.clicked.connect(self.open_website) awidget2 = QWidget() buttonLayout = QHBoxLayout(awidget2) buttonLayout.addWidget(self.bugtracker_button) buttonLayout.addWidget(self.website_button) aboutLayout.addWidget(awidget2) awidget.setLayout(aboutLayout) aboutScrollArea.setWidget(awidget) self.setCentralWidget(aboutScrollArea) self.show()
@pyqtSlot("QString") def setText__2(self,msg): # print "setText__2" self.setText(msg) if __name__ == "__main__": from PyQt4.QtGui import QApplication, QLabel, QMessageBox import sys import os print os.getpid() app = QApplication(sys.argv) text = QLabel(" QLocalServer tests") # text = Label(" QLocalServer tests") text.resize(600,400) s = Server() if (s.init("localserver-test")==False): QMessageBox.information(text,"info", "There is already exist one!") #// 初使化失败, 说明已经有一个在运行了 sys.exit(-1) # QObject.connect(s,SIGNAL("newMessage(PyQt_PyObject)"),text, SLOT("setText__2(PyQt_PyObject)")) # QObject.connect(s,SIGNAL("newMessage(QString)"),text, SLOT("setText__2(QString)")) QObject.connect(s,SIGNAL("newMessage(QString)"),text, SLOT("setText(QString)")) text.show() sys.exit(app.exec_())
def __init__(self, parent=None): QWidget.__init__(self, parent) self.clean_up_queue = [] self.summoner = SummonerData() self.summoner.getStaticData() ### Search Bar ### ################## #label self.search_label = QLabel(self) self.search_label.move(20, 15) self.search_label.resize(220, 25) self.search_label.setText('Enter summoner name(s):') self.search_label.setStyleSheet("QLabel {font:14pt}") #text field self.search_field = QLineEdit(self) self.search_field.move(260, 15) self.search_field.resize(250, 25) self.search_field.setPlaceholderText("ex: mcnuggets, teltor, ...") self.search_field.setFocusPolicy(Qt.ClickFocus) #search button self.search_button = QPushButton(self) self.search_button.move(520, 15) self.search_button.resize(150, 25) self.search_button.setText('Search Summoner') #region combobox self.region_list = QComboBox(self) self.region_list.move(680, 15) self.region_list.resize(75, 25) regions = ['NA', 'LAN', 'BR', 'LAS', 'EUW', 'EUNE', 'TR', 'RU', 'OCE'] self.region_list.addItems(regions) #error label self.error_label = QLabel(self) self.error_label.move(775, 15) self.error_label.resize(160, 25) self.error_label.setStyleSheet("QLabel {font:14pt}") ### Summoner Information ### ############################ #summoner Icon label self.icon_label = QLabel(self) self.icon_label.setScaledContents(True) self.icon_label.move(260, 50) self.icon_label.resize(110, 110) #name label self.name_label = QLabel(self) self.name_label.move(380, 50) self.name_label.resize(620, 50) self.name_label.setText('SUMMONER NAME') self.name_label.setStyleSheet("QLabel {font:32pt}") #rank label self.rank_label = QLabel(self) self.rank_label.move(380, 100) self.rank_label.resize(200, 60) self.rank_label.setText('summoner rank') self.rank_label.setStyleSheet("QLabel {font:18pt}") #miniseries labels self.series_labels = {} self.pixmap_win = QPixmap() self.pixmap_loss = QPixmap() self.pixmap_n = QPixmap() self.pixmap_win.load("./images/win.png") self.pixmap_loss.load("./images/loss.png") self.pixmap_n.load("./images/n.png") xPos = 600 for x in range(5): match_label = QLabel(self) match_label.move(xPos, 120) match_label.resize(35, 35) match_label.setScaledContents(True) match_label.hide() self.series_labels[x] = match_label xPos += 40 #mastery image labels print 'loading mastery images ...' self.ferocity_tree_images = self.getMasteryImages( self.summoner.ferocityMasteryTree()) self.cunning_tree_images = self.getMasteryImages( self.summoner.cunningMasteryTree()) self.resolve_tree_images = self.getMasteryImages( self.summoner.resolveMasteryTree()) print 'Done' #champion icon image labels print 'loading champion icon images ...' self.championIcons = self.getChampionIconImages( self.summoner.championList()) print 'Done' #overview widget self.overview_widget = QWidget() self.overview_menu = QTabWidget(self.overview_widget) self.overview_menu.resize(720, 270) #runes widget self.runes_widget = QWidget() self.runes_menu = QTabWidget(self.runes_widget) self.runes_menu.resize(720, 270) #masteries widget self.masteries_widget = QWidget() self.masteries_menu = QTabWidget(self.masteries_widget) self.masteries_menu.resize(720, 270) #summoner menu self.menu = QTabWidget(self) self.menu.move(260, 180) self.menu.resize(720, 300) self.menu.addTab(self.overview_widget, "Overview") self.menu.addTab(self.runes_widget, "Runes") self.menu.addTab(self.masteries_widget, "Masteries") self.menu.hide() #summoners buttons self.button_list = {} yPos = 150 for x in range(10): sum_button = QPushButton(self) sum_button.move(50, yPos) sum_button.resize(150, 25) sum_button.hide() self.button_list[x] = sum_button yPos += 25 ### Connecting Widgets ### ########################## self.connect(self.search_button, QtCore.SIGNAL("clicked()"), self.getData) self.connect(self.search_button, QtCore.SIGNAL("clicked()"), self.getRankedData) self.connect(self.button_list[0], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[0].text()))) self.connect(self.button_list[1], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[1].text()))) self.connect(self.button_list[2], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[2].text()))) self.connect(self.button_list[3], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[3].text()))) self.connect(self.button_list[4], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[4].text()))) self.connect(self.button_list[5], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[5].text()))) self.connect(self.button_list[6], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[6].text()))) self.connect(self.button_list[7], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[7].text()))) self.connect(self.button_list[8], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[8].text()))) self.connect(self.button_list[9], QtCore.SIGNAL("clicked()"), lambda: self.displayData(str(self.button_list[9].text()))) ### Window Configuration ### ############################ #window settings self.setGeometry(200, 150, 1000, 500) self.setMaximumSize(1000, 500) self.setWindowTitle('summoner App') self.show()
class MasteryWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.mastery_rank_labels = {} #mastery page name label self.page_name = QLabel(self) self.page_name.resize(500, 25) #ferocity tree label self.ferocity_tree = QLabel(self) self.ferocity_tree.move(7, 25) self.ferocity_tree.resize(230, 211) self.ferocity_tree.setStyleSheet( "QLabel {color:black; background-color:maroon; border-style: outset; border-width: 2px; border-color: black}" ) self.total_ferocity_points = QLabel(self.ferocity_tree) self.total_ferocity_points.move(175, 178) self.total_ferocity_points.resize(30, 30) self.total_ferocity_points.setAlignment(Qt.AlignCenter) self.total_ferocity_points.setStyleSheet( "QLabel {color:black; background-color:white; border-radius:10px; font: bold 14px}" ) #cunning tree label self.cunning_tree = QLabel(self) self.cunning_tree.move(242, 25) self.cunning_tree.resize(230, 211) self.cunning_tree.setStyleSheet( "QLabel {color:black; background-color:navy; border-style: outset; border-width: 2px; border-color: black}" ) self.total_cunning_points = QLabel(self.cunning_tree) self.total_cunning_points.move(175, 178) self.total_cunning_points.resize(30, 30) self.total_cunning_points.setAlignment(Qt.AlignCenter) self.total_cunning_points.setStyleSheet( "QLabel {color:black; background-color:white; border-radius:10px; font: bold 14px}" ) #resolve tree label self.resolve_tree = QLabel(self) self.resolve_tree.move(477, 25) self.resolve_tree.resize(230, 211) self.resolve_tree.setStyleSheet( "QLabel {color:black; background-color:green; border-style: outset; border-width: 2px; border-color: black}" ) self.total_resolve_points = QLabel(self.resolve_tree) self.total_resolve_points.move(175, 178) self.total_resolve_points.resize(30, 30) self.total_resolve_points.setAlignment(Qt.AlignCenter) self.total_resolve_points.setStyleSheet( "QLabel {color:black; background-color:white; border-radius:10px; font: bold 14px}" ) def setName(self, name): self.page_name.setText(" " + name) def setMasteryRank(self, mid, rank): self.mastery_rank_labels[mid].setText(rank) #self.mastery_rank_labels[str(mid)].setText(rank) def setTotalPoints(self): ferocity_points = 0 cunning_points = 0 resolve_points = 0 for x in self.mastery_rank_labels.keys(): if x > 6100 and x < 6200: #if int(x) > 4100 and int(x) < 4200: ferocity_points += int(self.mastery_rank_labels[x].text()) elif x > 6200 and x < 6300: #elif int(x) > 4200 and int(x) < 4300: resolve_points += int(self.mastery_rank_labels[x].text()) else: cunning_points += int(self.mastery_rank_labels[x].text()) self.total_ferocity_points.setText(str(ferocity_points)) self.total_cunning_points.setText(str(cunning_points)) self.total_resolve_points.setText(str(resolve_points)) def setMasteryLabels(self, ferocityList, cunningList, resolveList): self.setMasteryTree(self.ferocity_tree, ferocityList) self.setMasteryTree(self.cunning_tree, cunningList) self.setMasteryTree(self.resolve_tree, resolveList) def setMasteryTree(self, tree, imageList): yPos = 3 xPos = 7 column = 1 for element in imageList.keys(): if not isinstance(element, str): mastery = QLabel(tree) mastery.setScaledContents(True) mastery.move(xPos, yPos) mastery.resize(30, 30) mastery.setPixmap(imageList[element]) mastery_rank = QLabel(tree) mastery_rank.move(xPos + 31, yPos + 15) mastery_rank.resize(15, 15) mastery_rank.setAlignment(Qt.AlignCenter) mastery_rank.setText('0') mastery_rank.setStyleSheet( "QLabel {color:white; border-style: outset; border-width: 2px; border-color: black}" ) self.mastery_rank_labels[element] = mastery_rank if column < 3: xPos += 56 column += 1 else: column = 1 xPos = 7 yPos += 35
def __init__(self,model): super(QWidget,self).__init__() if not isinstance(model,Model): raise Exception('Constructor argument of type Model expected.') self.setWindowTitle('Strandbeest simulator') # lazily simulates on full movement cycle of the strandbeest def iterateStates(): ''' Iterates over the first full movement cycle of the Strandbeest. In order to determine when the movement repeats, a heuristic is used, that stops simulating once the state vector becomes similar enough to the initial state vector. This heuristic assumes that the movement of the Strandbeest is time independent. ''' x0 = model.state() yield x0 for _ in range(2): model.increment(0.01) xi = model.state() yield xi limit = norm(xi-x0) while True: model.increment(0.01) xi = model.state() yield xi if norm(xi-x0) < limit: # <- heuristic condition for a full simulation cycle break # record simulation results record = _Record() view = _View(model,record) def recordStates(states): ''' The _Canvas uses the states of the simulation to display movement curves of the nodes. For that purposes the simulated states are stored to the model in the record.states list. In order to notify the _View of newly simulated states, all callables in the record.changeListeners list are notified, with the new state vector as argument. ''' for x in states: record.states.append(x) record.velocities.append( model.v(x,t=None) ) record.times.append( model.t ) for listener in record.changeListeners: listener(x) yield x del record.changeListeners def recordSceenshots(statesLoop): ''' A little utility i created to be able to generate GIFs from the simulation. Saves screenshots from the current view of every 10th simulation step. ''' i,j = 0,0 for x in statesLoop: if i < 2*943 and 0 == i % 10: img = QPixmap.grabWidget(self) img = img.scaled(640,500,transformMode = Qt.SmoothTransformation) img.save('data/img%(j)d.jpg' % locals(),'jpg') j+=1 i += 1 yield x statesLoop = iterateStates() statesLoop = recordStates(statesLoop) statesLoop = itertools.cycle(statesLoop) # statesLoop = recordSceenshots(statesLoop) def tick(): ''' Advances the view by one tick (not neccessarily the simulation) ''' model.setState( next(statesLoop) ) # <- in the first cycle this statement is redundant tick() timer = QTimer() timer.timeout.connect(tick) speedLabel = QLabel('? * Realtime') speedLabel.resize(speedLabel.sizeHint()) speedLabel.setToolTip('Simulation speed [ticks/sec.].') speedSlider = QSlider(Qt.Horizontal) speedSlider.resize(speedSlider.sizeHint()) speedSlider.setMinimum(0) speedSlider.setMaximum(6) speedSlider.setTickPosition(QSlider.TicksBelow) def tpsChange(value): # <- called whenever ticks/sec. change ''' Changes the number of simulation ticks per second. ''' value = 2**(value-2) speedLabel.setText( '%(value)6.2f * Realtime' % locals() ) timer.setInterval(10/value) speedSlider.valueChanged[int].connect(tpsChange) speedSlider.setValue(4) def startStopClick(): startStopClick.running ^= True if startStopClick.running: timer.start() startStop.setText('Stop') else: timer.stop() startStop.setText('Start') startStop = QPushButton('Start/Stop') startStop.resize(startStop.sizeHint()) startStop.setToolTip('Start the simulation.') startStop.clicked.connect(startStopClick) startStopClick.running = True startStopClick() grid = QGridLayout(self) grid.addWidget(startStop,0,0) grid.addWidget(speedSlider,0,1) grid.addWidget(speedLabel,0,2) grid.addWidget(view,1,0,1,3)
class BillboardDisplay(QMainWindow): def __init__(self, parent=None, workdir=None, fontsize=42): super(BillboardDisplay, self).__init__(parent) self.workdir = workdir self.logger = logging.getLogger('display') self.logger.info('Working directory: {}'.format(self.workdir)) self.current_display = os.path.join(self.workdir, 'current.jpg') desktop = QDesktopWidget() self.display = QWidget(self) size = desktop.availableGeometry(desktop.primaryScreen()); self.display.resize(size.width(), size.height()) self.display.setWindowTitle("Billboard") self.image_label = QLabel(self.display) self.image_label.resize(size.width(), size.height()) self.text_label = QLabel(self.display) self.text_label.resize(size.width(), size.height()) self.text_label.setMargin(100) self.text_label.setStyleSheet(''' QLabel {{ font-size: {}pt; font-weight: bold; color: #eeeeee; text-align: center; }} '''.format(fontsize)) self.text_label.setWordWrap(True) self.text_label.setAlignment(Qt.AlignCenter) dse = QGraphicsDropShadowEffect() dse.setBlurRadius(0) dse.setXOffset(5) dse.setYOffset(5) dse.setColor(QColor(0, 0, 0, 255)) self.text_label.setGraphicsEffect(dse) QObject.connect(self, SIGNAL("updateimage"), self.display_image) QObject.connect(self, SIGNAL("updatecurrent"), self.take_screenshot) def update_image(self, imagepath): self.emit(SIGNAL("updateimage"), imagepath) def update_current(self): self.emit(SIGNAL("updatecurrent"), self.current_display) def display(self, imagepath, text): self.display_text(text) self.display_image(imagepath) self.showFullScreen() def display_image(self, imagepath): pix = QPixmap(imagepath) self.image_label.setPixmap(pix.scaled(self.display.size(), Qt.KeepAspectRatioByExpanding)) def display_text(self, text): self.text_label.setText('"{}"'.format(text)) def take_screenshot(self, path): pixmap = QPixmap(QPixmap.grabWidget(self.display)) pixmap.save(path) self.logger.debug('Saving {}'.format(path))
class AppMainWindow(Ui_mainWindow, QMainWindow): """ Main application window """ # internal decorator to perform common checks required # for many calls ############################# class CallChecker(object): def __init__(self): pass def setWindow(self, main_window): self.main_window = main_window def __call__(self, f): @functools.wraps(f) def wrapper(*args, **kw): self.main_window.setEnabled(False) try: logUICall.log('function call %s from module %s' % (f.__name__, f.__module__), logUICall.DEBUG) return f(*args, **kw) except SIDDUIException as uie: logUICall.log(uie, logUICall.WARNING) self.main_window.ui.statusbar.showMessage(get_ui_string('app.error.ui')) except SIDDException as se: logUICall.log(se, logUICall.WARNING) self.main_window.ui.statusbar.showMessage(get_ui_string('app.error.model')) except Exception as e: logUICall.log(e, logUICall.ERROR) self.main_window.ui.statusbar.showMessage(get_ui_string('app.error.unexpected')) finally: self.main_window.setEnabled(True) return wrapper apiCallChecker = CallChecker() # CONSTANTS ############################# UI_WINDOW_GEOM = 'app_main/geometry' UI_WINDOW_STATE = 'app_main/windowState' TAB_DATA, TAB_MS, TAB_MOD, TAB_RESULT = range(4) # constructor / destructor ############################# def __init__(self, qtapp, app_config): """ constructor - initialize UI elements - connect UI elements to callback """ # create UI super(AppMainWindow, self).__init__() AppMainWindow.apiCallChecker.setWindow(self) self.qtapp = qtapp self.app_config = app_config self.taxonomy = get_taxonomy(app_config.get('options', 'taxonomy', 'gem')) self.ui = Ui_mainWindow() self.ui.setupUi(self) self.settings = QSettings(SIDD_COMPANY, '%s %s' %(SIDD_APP_NAME, SIDD_VERSION)); self.restoreGeometry(self.settings.value(self.UI_WINDOW_GEOM).toByteArray()); self.restoreState(self.settings.value(self.UI_WINDOW_STATE).toByteArray()); self.lb_map_location = QLabel(self) self.lb_map_location.resize(self.ui.statusbar.width()/3, self.ui.statusbar.height()) self.ui.statusbar.addPermanentWidget(self.lb_map_location) self.msdb_dao = MSDatabaseDAO(FILE_MS_DB) self.tab_datainput = WidgetDataInput(self) self.ui.mainTabs.addTab(self.tab_datainput, get_ui_string("app.window.tab.input")) self.tab_ms = WidgetMappingSchemes(self) self.ui.mainTabs.addTab(self.tab_ms, get_ui_string("app.window.tab.ms")) self.tab_mod = WidgetSecondaryModifier(self) self.ui.mainTabs.addTab(self.tab_mod, get_ui_string("app.window.tab.mod")) self.tab_result = WidgetResult(self) self.ui.mainTabs.addTab(self.tab_result, get_ui_string("app.window.tab.result")) self.previewInput = True self.about = DialogAbout(self) self.about.setModal(True) self.dlgAttrRange = DialogAttrRanges() self.dlgAttrRange.setModal(True) self.progress = DialogApply(self) self.progress.setModal(True) self.proc_options = DialogProcessingOptions(self) self.proc_options.setModal(True) # connect menu action to slots (ui events) self.ui.mainTabs.currentChanged.connect(self.tabChanged) self.ui.actionProject_Blank.triggered.connect(self.createBlank) self.ui.actionUsing_Data_Wizard.triggered.connect(self.createWizard) self.ui.actionOpen_Existing.triggered.connect(self.loadProj) self.ui.actionSave.triggered.connect(self.saveProj) self.ui.actionSave_as.triggered.connect(self.saveProjAs) self.ui.actionExit.triggered.connect(self.close) self.ui.actionData_Input.triggered.connect(self.changeTab) self.ui.actionMapping_Schemes.triggered.connect(self.changeTab) self.ui.actionResult.triggered.connect(self.changeTab) self.ui.actionProcessing_Options.triggered.connect(self.setProcessingOptions) self.ui.actionAbout.triggered.connect(self.showAbout) # set project to None and adjust ui as needed self.closeProject() self.ui.statusbar.showMessage(get_ui_string("app.status.ready")) # perform clean up from previous runs try: delete_folders_in_dir(get_temp_dir(), "tmp*") except: # cleanup is not-critical. no action taken even if fails pass # hide features if not app_config.get('options', 'parse_modifier', True, bool): self.tab_mod.setVisible(False) self.ui.mainTabs.removeTab(self.TAB_MOD) self.TAB_MOD = self.TAB_MS self.TAB_RESULT -= 1 # hide view menu self.ui.menuView.menuAction().setVisible(False) # hide data wizard self.ui.actionUsing_Data_Wizard.setVisible(False) # event handlers ############################# @pyqtSlot(QCloseEvent) def resizeEvent(self, event): """ handle window resize """ self.ui.mainTabs.resize(self.width(), self.height()-40) @pyqtSlot(QCloseEvent) def closeEvent(self, event): self.closeProject() self.settings.setValue(self.UI_WINDOW_GEOM, self.saveGeometry()); self.settings.setValue(self.UI_WINDOW_STATE, self.saveState()); self.msdb_dao.close() super(AppMainWindow, self).closeEvent(event) @logUICall @pyqtSlot() def createBlank(self): """ create a new project """ # create new project file project = Project(self.app_config, self.taxonomy) # open project and sync UI self.setProject(project, skipVerify=True) self.ui.statusbar.showMessage(get_ui_string("app.status.project.created")) @logUICall @pyqtSlot() def createWizard(self): try: # should not update preview while using wizard self.setVisible(False) self.previewInput = False wizard = WidgetDataWizard(self, Project(self.app_config, self.taxonomy)) if wizard.exec_() == QDialog.Accepted: # setProject makes call to GIS component that requires visibility self.setVisible(True) self.previewInput = True self.setProject(wizard.project) self.ui.statusbar.showMessage(get_ui_string("app.status.project.created")) # else # do nothing? except: pass finally: # return to normal window # these calls are reached # 1. in case any exception occurs, # 2. wizard finished or cancelled self.setVisible(True) self.previewInput = True @logUICall @pyqtSlot() def loadProj(self): """ open file dialog to load an existing application """ self.getOpenFileName(self, get_ui_string("app.window.msg.project.open"), get_ui_string("app.extension.db"), self.openProjectFile) self.ui.statusbar.showMessage(get_ui_string("app.status.project.loaded")) @logUICall @pyqtSlot() def saveProj(self): """ save active project """ if self.project is None: return try: self.project.sync(SyncModes.Write) self.ui.statusbar.showMessage(get_ui_string("app.status.project.saved")) except SIDDProjectException as se: if se.error == ProjectErrors.FileNotSet: self.saveProjAs() @logUICall @pyqtSlot() def saveProjAs(self): if self.project is None: return filename = QFileDialog.getSaveFileName(self, get_ui_string("app.window.msg.project.create"), get_app_dir(), get_ui_string("app.extension.db")) # no need to check for file overwrite, because QFileDialog return always confirmed overwrite if not filename.isNull(): filename = str(filename) self.project.set_project_path(filename) self.project.sync(SyncModes.Write) self.saveLastOpenDir(filename[0:filename.rfind("/")]) self.ui.statusbar.showMessage(get_ui_string("app.status.project.saved")) @logUICall @pyqtSlot() def setProcessingOptions(self): if self.project is None: return # set options to be those defined in project self.proc_options.resetOptions() for attribute in dir(self.proc_options): try: proc_attribute = self.project.operator_options['proc.%s'%attribute] setattr(self.proc_options, attribute, proc_attribute) except: # for empty project, this is the first time proc.options is set # just use default from proc_option dialogbox pass if self.proc_options.exec_() == QDialog.Accepted: for attribute in dir(self.proc_options): self.project.operator_options['proc.%s'%attribute] = getattr(self.proc_options, attribute) # alert user answer = QMessageBox.question(self, get_ui_string("app.confirm.title"), get_ui_string("app.confirm.build.exposure"), buttons = QMessageBox.No | QMessageBox.Yes, defaultButton=QMessageBox.No) if answer == QMessageBox.No: return self.buildExposure() @logUICall @pyqtSlot() def showAbout(self): """ event handler for menu item show about box """ self.about.setVisible(True) @logUICall @pyqtSlot() def changeTab(self): """ event handler for menu item in menu - switch view to tab according to menu item pushed """ sender = self.sender() if sender == self.ui.actionData_Input: self.showTab(self.TAB_DATA) elif sender == self.ui.actionMapping_Schemes: self.showTab(self.TAB_MS) elif sender == self.ui.actionResult: self.showTab(self.TAB_RESULT) else: logUICall.log('\tdo nothing. should not even be here', logUICall.WARNING) @logUICall @pyqtSlot(int) def tabChanged(self, index): if index == self.TAB_RESULT: self.lb_map_location.setVisible(True) else: self.lb_map_location.setVisible(False) # public methods ############################# @apiCallChecker def openProjectFile(self, path_to_file): """ load project from given path shows error if path does not exist """ # NOTE: set_project_path will create new project if path_to_file # does not exist, os.path.exists check is not optional if os.path.exists(path_to_file): # read file to create project project = Project(self.app_config, self.taxonomy) project.set_project_path(path_to_file) project.sync(SyncModes.Read) # open project and sync UI self.setProject(project) @apiCallChecker def setProject(self, project, skipVerify=False): """ open a project and sync UI accordingly""" # close and reset UI self.closeProject() self.project = project # sync ui self.tab_datainput.setProject(project) # set processing options for attribute in dir(self.proc_options): if self.project.operator_options.has_key('proc.%s'%attribute): setattr(self.proc_options, attribute, self.project.operator_options['proc.%s'%attribute]) if not skipVerify: # verify to make sure input file are still in same place self.verifyInputs() if self.project.ms is not None: self.visualizeMappingScheme(self.project.ms) self.ui.mainTabs.setTabEnabled(self.TAB_MS, True) self.ui.mainTabs.setTabEnabled(self.TAB_MOD, True) self.ui.mainTabs.setTabEnabled(self.TAB_DATA, True) self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, True) self.ui.actionSave.setEnabled(True) self.ui.actionSave_as.setEnabled(True) self.tab_result.set_project(project) @apiCallChecker def closeProject(self): """ close opened project and update UI elements accordingly """ # adjust UI in application window self.tab_result.closeAll() # this call must happen first. # otherwise, it locks temporary GIS files self.ui.mainTabs.setTabEnabled(self.TAB_DATA, False) self.ui.mainTabs.setTabEnabled(self.TAB_MS, False) self.ui.mainTabs.setTabEnabled(self.TAB_MOD, False) self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, False) self.showTab(self.TAB_DATA) # disable menu/menu items self.ui.actionSave.setEnabled(False) self.ui.actionSave_as.setEnabled(False) self.ui.actionMapping_Schemes.setEnabled(False) self.ui.actionResult.setEnabled(False) self.ui.actionProcessing_Options.setEnabled(False) if getattr(self, 'project', None) is not None: # save existing project is needed if self.project.require_save: ans = QMessageBox.question(self, get_ui_string("app.window.msg.project.not_saved"), get_ui_string("app.window.msg.project.save_or_not"), buttons=QMessageBox.Yes|QMessageBox.No, defaultButton=QMessageBox.Yes) if ans == QMessageBox.Yes: self.saveProj() # adjust UI in tabs self.tab_datainput.closeProject() self.tab_ms.clearMappingScheme() self.tab_mod.closeMappingScheme() self.project.clean_up() del self.project self.project = None @apiCallChecker def verifyInputs(self): """ perform checks on current dataset provided and update UI accordingly """ # remove result self.tab_result.closeResult() # verify current dataset self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.verify_data) self.tab_datainput.showVerificationResults() # always allow mapping scheme self.ui.mainTabs.setTabEnabled(self.TAB_MS, True) self.ui.mainTabs.setTabEnabled(self.TAB_MOD, True) self.ui.actionMapping_Schemes.setEnabled(True) self.ui.actionResult.setEnabled(True) self.ui.actionProcessing_Options.setEnabled(True) self.ui.statusbar.showMessage(get_ui_string("app.status.input.verified")) @apiCallChecker def buildMappingScheme(self): """ build mapping scheme with given data """ self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) # invoke asynchronously try: invoke_async(get_ui_string("app.status.processing"), self.project.build_ms) except SIDDException as err: # different error message used in this case raise SIDDUIException(get_ui_string('project.error.sampling', str(err))) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.created")) @apiCallChecker def createEmptyMS(self): """ build an empty mapping scheme tree for user to manipulate manually """ self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.create_empty_ms) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.created")) @apiCallChecker def appendMSBranch(self, node, branch): """ append a branch (from library) to a node in a mapping scheme tree """ self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) self.project.ms.append_branch(node, branch) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.modified")) @apiCallChecker def deleteMSBranch(self, node): """ delete selected node and children from mapping scheme tree """ self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) self.project.ms.delete_branch(node) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.modified")) @apiCallChecker def exportMS(self, path, format): """ export mapping scheme leaves as CSV """ self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.export_ms, path, format) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.exported")) @apiCallChecker def loadMS(self, path): self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) # invoke asynchronously invoke_async(get_ui_string("app.status.processing"), self.project.load_ms, path) self.visualizeMappingScheme(self.project.ms) self.ui.statusbar.showMessage(get_ui_string("app.status.ms.created")) @apiCallChecker def exportResults(self, export_format, export_path): """ export mapping scheme leaves as CSV """ self.ui.statusbar.showMessage(get_ui_string("app.status.exposure.exported")) # invoke asynchronously self.project.set_export(export_format, export_path) invoke_async(get_ui_string("app.status.processing"), self.project.export_data) self.ui.statusbar.showMessage(get_ui_string("app.status.exposure.exported")) @apiCallChecker def buildExposure(self): """ build exposure """ self.ui.statusbar.showMessage(get_ui_string("app.status.ms.processing")) # verify current dataset to make sure can process exposure self.project.verify_data() # can not proceed if project is not ready for exposure if self.project.status != ProjectStatus.ReadyForExposure: logUICall.log(get_ui_string("project.error.NotEnoughData"), logUICall.WARNING) # show result self.tab_datainput.showVerificationResults() self.ui.mainTabs.setCurrentIndex(self.TAB_DATA) return # close current results self.tab_result.closeResult() self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, True) # reset progress dialog self.progress.setVisible(True) self.progress.ui.pb_progress.setRange(0, self.project.build_exposure_total_steps()) self.progress.ui.txt_progress.clear() self.progress.ui.txt_progress.appendPlainText(get_ui_string("app.status.processing")) self.qtapp.processEvents() cancelled = False error_occured = False error_message = "" curStep = 0 try: for step in self.project.build_exposure_steps(): if cancelled or error_occured: break # use introspection to get operator class class_name = str(step.__class__) # result of above call has format # <class '...'> where ... is the class name of interest class_name = class_name[class_name.find("'")+1:class_name.rfind("'")] # update UI logAPICall.log('\t %s' % step.name, logAPICall.DEBUG) self.progress.ui.txt_progress.appendPlainText(get_ui_string('message.%s'% class_name)) self.progress.ui.pb_progress.setValue(curStep) self.qtapp.processEvents() sleep(0.5) # perform operation step.do_operation() if not self.progress.isVisible(): cancelled = True # operation successful curStep+=1 except Exception as err: # exception are thrown if data is not ready for exposure error_message = err.message error_occured = True self.progress.setVisible(False) if error_occured: # processing cancelled logUICall.log(error_message, logUICall.WARNING) self.ui.statusbar.showMessage(get_ui_string("app.status.cancelled")) elif cancelled: # processing cancelled logUICall.log(get_ui_string("app.status.cancelled"), logUICall.WARNING) self.ui.statusbar.showMessage(get_ui_string("app.status.cancelled")) else: # processing completed self.project.verify_result() self.progress.setVisible(False) # show result self.tab_result.refreshResult() self.ui.mainTabs.setTabEnabled(self.TAB_RESULT, True) self.ui.mainTabs.setCurrentIndex(self.TAB_RESULT) self.ui.statusbar.showMessage(get_ui_string("app.status.exposure.created")) def showTab(self, index): """ switch view to tab with given index. do nothing if index is not valid """ if index >=self.TAB_DATA and index <=self.TAB_RESULT: self.ui.mainTabs.setCurrentIndex(index) def refreshPreview(self): """ refresh all layers shown in Preview tab """ if self.previewInput: self.tab_result.refreshView() def visualizeMappingScheme(self, ms): """ display the given mapping scheme in Mapping scheme and Modifier tabs""" self.tab_ms.showMappingScheme(ms) self.tab_mod.showMappingScheme(ms) def updateMapLocation(self, x, y): self.lb_map_location.setText("Longitude %.4f latitude %4f" % (x, y)) # utility methods # no error checking is performed in these functions # caller must catch possible exception ############################### def setRange(self, ranges, attribute): if ranges.has_key(attribute): range = ranges[attribute] self.dlgAttrRange.set_values(attribute, range['min_values'], range['max_values']) else: self.dlgAttrRange.set_values(attribute, [], []) range_updated = self.dlgAttrRange.exec_() == QDialog.Accepted if range_updated: ranges[attribute] = {'min_values':self.dlgAttrRange.min_values, 'max_values':self.dlgAttrRange.max_values} return range_updated def getOpenFileName(self, parent, title, extension, callback): """ show open file dialog box to get a filename """ filename = QFileDialog.getOpenFileName(parent, title, self.getLastOpenDir(), extension) if not filename.isNull(): filename = str(filename) if os.path.exists(filename): # store directory to file, so next Open will be in same dir self.saveLastOpenDir(filename[0:filename.rfind("/")]) callback(filename) # no error catching to make sure callback is actually a function def saveLastOpenDir(self, dir_path): """ store path so it can be retrieved by other parts of the application """ self.settings.setValue('LAST_OPEN_DIR', dir_path) def getLastOpenDir(self): """ retrieve remembered path """ last_dir = self.settings.value('LAST_OPEN_DIR').toString() if last_dir is None: return get_app_dir() else: return str(last_dir)
#!/usr/bin/env dls-python2.6 '''minimal Qt example''' if __name__ == '__main__': import require import cothread from cothread.catools import * from PyQt4.QtGui import QLabel cothread.iqt() # make a label widget (None is the parent, this is top-level widget) label = QLabel('Hello World', None) label.resize(200, 50) # must show top-level widgets manually label.show() # animate label def signal(value): label.setText('DCCT %f %s' % (value, value.units)) camonitor('SR21C-DI-DCCT-01:SIGNAL', signal, format = FORMAT_CTRL) if __name__ == '__main__': cothread.WaitForQuit()
class PhotoViewer(QScrollArea): """ Widget for viewing images by incorporating basic navigation options. """ def __init__(self, parent=None, photo_path=""): QScrollArea.__init__(self, parent) self.setBackgroundRole(QPalette.Dark) self._printer = QPrinter() self._lbl_photo = QLabel() self._lbl_photo.setBackgroundRole(QPalette.Base) self._lbl_photo.setSizePolicy(QSizePolicy.Ignored,QSizePolicy.Ignored) self._lbl_photo.setScaledContents(True) self.setWidget(self._lbl_photo) self._photo_path = photo_path self._ph_image = None self._scale_factor = 1.0 self._aspect_ratio = -1 self._create_actions() if self._photo_path: self.load_document(self._photo_path) def _create_actions(self): """ Create actions for basic image navigation. """ self._zoom_in_act = QAction( QApplication.translate("PhotoViewer","Zoom &In (25%)"), self) self._zoom_in_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl++")) self._zoom_in_act.setEnabled(False) self._zoom_in_act.triggered.connect(self.zoom_in) self._zoom_out_act = QAction( QApplication.translate("PhotoViewer","Zoom &Out (25%)"), self) self._zoom_out_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl+-")) self._zoom_out_act.setEnabled(False) self._zoom_out_act.triggered.connect(self.zoom_out) self._normal_size_act = QAction( QApplication.translate("PhotoViewer","&Normal Size"), self) self._normal_size_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl+S")) self._normal_size_act.setEnabled(False) self._normal_size_act.triggered.connect(self.normal_size) self._fit_to_window_act = QAction( QApplication.translate("PhotoViewer","&Fit to Window"), self) self._fit_to_window_act.setShortcut( QApplication.translate("PhotoViewer","Ctrl+F")) self._fit_to_window_act.setEnabled(False) self._fit_to_window_act.setCheckable(True) self._fit_to_window_act.triggered.connect(self.fit_to_window) self._print_act = QAction( QApplication.translate("PhotoViewer","&Print"), self) self._print_act .setShortcut( QApplication.translate("PhotoViewer","Ctrl+P")) self._print_act .setEnabled(False) self._print_act .triggered.connect(self.print_photo) def zoom_in(self): self.scale_photo(1.25) def zoom_out(self): self.scale_photo(0.8) def normal_size(self): self._lbl_photo.adjustSize() self._scale_factor = 1.0 def fit_to_window(self): fit_to_win = self._fit_to_window_act.isChecked() self.setWidgetResizable(fit_to_win) if not fit_to_win: self.normal_size() self.update_actions() def print_photo(self): print_dialog = QPrintDialog(self._printer,self) if print_dialog.exec_() == QDialog.Accepted: painter = QPainter(self._printer) rect = painter.viewport() size = self._lbl_photo.pixmap().size() size.scale(rect.size(), Qt.KeepAspectRatio) painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(self._lbl_photo.pixmap().rect()) painter.drawPixmap(0, 0, self._lbl_photo.pixmap()) def wheelEvent(self, event): """ Zoom the image based on the mouse wheel rotation action. :param event: Event containing the wheel rotation info. :type event: QWheelEvent """ degrees = event.delta() / 8 num_steps = degrees / 15 if num_steps < 0: abs_num_steps = abs(num_steps) zoom_factor = 1 + (abs_num_steps * 0.25) else: zoom_factor = 1 - (num_steps * 0.2) self.scale_photo(zoom_factor) def heightForWidth(self, width): if self._aspect_ratio != -1: return width / self._aspect_ratio else: return -1 def resizeEvent(self, event): """ Event for resizing the widget based on the pixmap's aspect ratio. :param event: Contains event parameters for the resize event. :type event: QResizeEvent """ super(PhotoViewer, self).resizeEvent(event) def update_actions(self): self._zoom_out_act.setEnabled(not self._fit_to_window_act.isChecked()) self._zoom_in_act.setEnabled(not self._fit_to_window_act.isChecked()) self._normal_size_act.setEnabled(not self._fit_to_window_act.isChecked()) def scale_photo(self,factor): """ :param factor: Value by which the image will be increased/decreased in the view. :type factor: float """ if not self._lbl_photo.pixmap().isNull(): self._scale_factor *= factor self._lbl_photo.resize(self._scale_factor * self._lbl_photo.pixmap().size()) self._adjust_scroll_bar(self.horizontalScrollBar(), factor) self._adjust_scroll_bar(self.verticalScrollBar(), factor) self._zoom_in_act.setEnabled(self._scale_factor < 3.0) self._zoom_out_act.setEnabled(self._scale_factor > 0.333) def _adjust_scroll_bar(self, scroll_bar, factor): scroll_bar.setValue(int(factor * scroll_bar.value() + ((factor - 1) * scroll_bar.pageStep()/2))) def load_document(self, photo_path): if photo_path: self._ph_image = QImage(photo_path) if self._ph_image.isNull(): return False self._photo_path = photo_path ph_pixmap = QPixmap.fromImage(self._ph_image) self._lbl_photo.setPixmap(ph_pixmap) self._scale_factor = 1.0 self._aspect_ratio = ph_pixmap.width() / ph_pixmap.height() self._fit_to_window_act.setEnabled(True) self._print_act.setEnabled(True) self._fit_to_window_act.trigger() self.update_actions() return ph_pixmap return True def photo_location(self): """ :returns: Absolute path of the photo in the central document repository. """ return self._photo_path def set_actions(self,menu): """ Add custom actions to the sub-window menu """ menu.addSeparator() menu.addAction(self._zoom_in_act) menu.addAction(self._zoom_out_act) menu.addAction(self._normal_size_act) menu.addAction(self._fit_to_window_act) menu.addSeparator() menu.addAction(self._print_act)
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, AUTO): ' Initialize QWidget inside MyMainWindow ' super(MyMainWindow, self).__init__() QWidget.__init__(self) self.auto = AUTO self.statusBar().showMessage(' {}'.format(__doc__)) self.setStyleSheet('QStatusBar{color:grey;}') self.setWindowTitle(__doc__) self.setWindowIcon(QIcon.fromTheme("face-monkey")) self.setFont(QFont('Ubuntu Light', 10)) self.setMaximumSize(QDesktopWidget().screenGeometry().width(), QDesktopWidget().screenGeometry().height()) self.base = path.abspath(path.join(getcwd(), str(datetime.now().year))) # directory auto completer self.completer = QCompleter(self) self.dirs = QDirModel(self) self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot) self.completer.setModel(self.dirs) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(QCompleter.PopupCompletion) # process self.process1 = None self.process2 = None self.cmd1 = 'nice -n {n} arecord{v} -f {f} -c {c} -r {b} -t raw' self.cmd2 = 'oggenc - -r -C {c} -R {b} -q {q} {d}{t}{a} -o {o}' self.process3 = QProcess(self) #self.process3.finished.connect(self.on_process3_finished) #self.process3.error.connect(self.on_process3_error) self.cmd3 = ('nice -n 20 ' + 'sox "{o}" -n spectrogram -x {x} -y {y} -z 99 -t "{o}" -o "{o}.png"') self.actual_file = '' # re starting timers, one stops, one starts self.timerFirst = QTimer(self) self.timerFirst.timeout.connect(self.end) self.timerSecond = QTimer(self) self.timerSecond.timeout.connect(self.run) # Proxy support, by reading http_proxy os env variable proxy_url = QUrl(environ.get('http_proxy', '')) QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy if str(proxy_url.scheme()).startswith('http') else QNetworkProxy.Socks5Proxy, proxy_url.host(), proxy_url.port(), proxy_url.userName(), proxy_url.password())) \ if 'http_proxy' in environ else None print((' INFO: Proxy Auto-Config as ' + str(proxy_url))) # basic widgets layouts and set up self.mainwidget = QTabWidget() self.mainwidget.setToolTip(__doc__) self.mainwidget.setMovable(True) self.mainwidget.setTabShape(QTabWidget.Triangular) self.mainwidget.setContextMenuPolicy(Qt.CustomContextMenu) self.mainwidget.setStyleSheet('QTabBar{color:white;font-weight:bold;}') self.mainwidget.setTabBar(TabBar(self)) self.mainwidget.setTabsClosable(False) self.setCentralWidget(self.mainwidget) self.dock1 = QDockWidget() self.dock2 = QDockWidget() self.dock3 = QDockWidget() self.dock4 = QDockWidget() self.dock5 = QDockWidget() for a in (self.dock1, self.dock2, self.dock3, self.dock4, self.dock5): a.setWindowModality(Qt.NonModal) # a.setWindowOpacity(0.9) a.setWindowTitle(__doc__ if a.windowTitle() == '' else a.windowTitle()) a.setStyleSheet('QDockWidget::title{text-align:center;}') self.mainwidget.addTab(a, QIcon.fromTheme("face-smile"), 'Double Click Me') # Paleta de colores para pintar transparente self.palette().setBrush(QPalette.Base, Qt.transparent) self.setPalette(self.palette()) self.setAttribute(Qt.WA_OpaquePaintEvent, False) # toolbar and basic actions self.toolbar = QToolBar(self) self.toolbar.setIconSize(QSize(24, 24)) # spacer widget for left self.left_spacer = QWidget(self) self.left_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # spacer widget for right self.right_spacer = QWidget(self) self.right_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) qaqq = QAction(QIcon.fromTheme("application-exit"), 'Quit', self) qaqq.setShortcut('Ctrl+Q') qaqq.triggered.connect(exit) qamin = QAction(QIcon.fromTheme("go-down"), 'Minimize', self) qamin.triggered.connect(lambda: self.showMinimized()) qamax = QAction(QIcon.fromTheme("go-up"), 'Maximize', self) qanor = QAction(QIcon.fromTheme("view-fullscreen"), 'AutoCenter AutoResize', self) qanor.triggered.connect(self.center) qatim = QAction(QIcon.fromTheme("mail-signed-verified"), 'View Date and Time', self) qatim.triggered.connect(self.timedate) qabug = QAction(QIcon.fromTheme("help-about"), 'Report a Problem', self) qabug.triggered.connect(lambda: qabug.setDisabled(True) if not call( 'xdg-open mailto:' + '*****@*****.**'.decode('rot13'), shell=True) else ' ERROR ') qamax.triggered.connect(lambda: self.showMaximized()) qaqt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self) qaqt.triggered.connect(lambda: QMessageBox.aboutQt(self)) qakde = QAction(QIcon.fromTheme("help-about"), 'About KDE', self) if KDE: qakde.triggered.connect(KHelpMenu(self, "", False).aboutKDE) qaslf = QAction(QIcon.fromTheme("help-about"), 'About Self', self) if KDE: qaslf.triggered.connect( KAboutApplicationDialog(aboutData, self).exec_) else: qaslf.triggered.connect(lambda: QMessageBox.about(self.mainwidget, __doc__, ''.join((__doc__, linesep, 'version ', __version__, ', (', __license__, '), by ', __author__, ', ( ', __email__, ' )', linesep )))) qafnt = QAction(QIcon.fromTheme("tools-check-spelling"), 'Set GUI Font', self) if KDE: font = QFont() qafnt.triggered.connect(lambda: self.setStyleSheet(''.join(( '*{font-family:', str(font.toString()), '}')) if KFontDialog.getFont(font)[0] == QDialog.Accepted else '')) else: qafnt.triggered.connect(lambda: self.setStyleSheet(''.join(('*{font-family:', str(QFontDialog.getFont()[0].toString()), '}')))) qasrc = QAction(QIcon.fromTheme("applications-development"), 'View Source Code', self) qasrc.triggered.connect(lambda: call('xdg-open {}'.format(__file__), shell=True)) qakb = QAction(QIcon.fromTheme("input-keyboard"), 'Keyboard Shortcuts', self) qakb.triggered.connect(lambda: QMessageBox.information(self.mainwidget, 'Keyboard Shortcuts', ' Ctrl+Q = Quit ')) qapic = QAction(QIcon.fromTheme("camera-photo"), 'Take a Screenshot', self) qapic.triggered.connect(lambda: QPixmap.grabWindow( QApplication.desktop().winId()).save(QFileDialog.getSaveFileName( self.mainwidget, " Save Screenshot As ...", path.expanduser("~"), ';;(*.png) PNG', 'png'))) qatb = QAction(QIcon.fromTheme("go-top"), 'Toggle ToolBar', self) qatb.triggered.connect(lambda: self.toolbar.hide() if self.toolbar.isVisible() is True else self.toolbar.show()) qati = QAction(QIcon.fromTheme("zoom-in"), 'Switch ToolBar Icon Size', self) qati.triggered.connect(lambda: self.toolbar.setIconSize(self.toolbar.iconSize() * 4) if self.toolbar.iconSize().width() * 4 == 24 else self.toolbar.setIconSize(self.toolbar.iconSize() / 4)) qasb = QAction(QIcon.fromTheme("preferences-other"), 'Toggle Tabs Bar', self) qasb.triggered.connect(lambda: self.mainwidget.tabBar().hide() if self.mainwidget.tabBar().isVisible() is True else self.mainwidget.tabBar().show()) qadoc = QAction(QIcon.fromTheme("help-browser"), 'On-line Docs', self) qadoc.triggered.connect(lambda: open_new_tab(str(__url__).strip())) qapy = QAction(QIcon.fromTheme("help-about"), 'About Python', self) qapy.triggered.connect(lambda: open_new_tab('http://python.org/about')) qali = QAction(QIcon.fromTheme("help-browser"), 'Read Licence', self) qali.triggered.connect(lambda: open_new_tab(__full_licence__)) qacol = QAction(QIcon.fromTheme("preferences-system"), 'Set GUI Colors', self) if KDE: color = QColor() qacol.triggered.connect(lambda: self.setStyleSheet(''.join(('* { background-color: ', str(color.name()), '}'))) if KColorDialog.getColor(color, self) else '') else: qacol.triggered.connect(lambda: self.setStyleSheet(''.join(( ' * { background-color: ', str(QColorDialog.getColor().name()), ' } ')))) qatit = QAction(QIcon.fromTheme("preferences-system"), 'Set the App Window Title', self) qatit.triggered.connect(self.seTitle) self.toolbar.addWidget(self.left_spacer) self.toolbar.addSeparator() self.toolbar.addActions((qaqq, qamin, qanor, qamax, qasrc, qakb, qacol, qatim, qatb, qafnt, qati, qasb, qatit, qapic, qadoc, qali, qaslf, qaqt, qakde, qapy, qabug)) self.addToolBar(Qt.TopToolBarArea, self.toolbar) self.toolbar.addSeparator() self.toolbar.addWidget(self.right_spacer) # define the menu menu = self.menuBar() # File menu items menu.addMenu('&File').addActions((qaqq, )) menu.addMenu('&Window').addActions((qamax, qanor, qamin)) # Settings menu menu.addMenu('&Settings').addActions((qasrc, qacol, qafnt, qatim, qatb, qati, qasb, qapic)) # Help menu items menu.addMenu('&Help').addActions((qadoc, qakb, qabug, qali, qaqt, qakde, qapy, qaslf)) # Tray Icon tray = QSystemTrayIcon(QIcon.fromTheme("face-devilish"), self) tray.setToolTip(__doc__) traymenu = QMenu() traymenu.addActions((qamax, qanor, qamin, qaqq)) tray.setContextMenu(traymenu) tray.show() def contextMenuRequested(point): ' quick and dirty custom context menu ' menu = QMenu() menu.addActions((qaqq, qamin, qanor, qamax, qasrc, qakb, qacol, qafnt, qati, qasb, qatb, qatim, qatit, qapic, qadoc, qali, qaslf, qaqt, qakde, qapy, qabug)) menu.exec_(self.mapToGlobal(point)) self.mainwidget.customContextMenuRequested.connect(contextMenuRequested) def must_be_checked(widget_list): ' widget tuple passed as argument should be checked as ON ' for each_widget in widget_list: try: each_widget.setChecked(True) except: pass def must_have_tooltip(widget_list): ' widget tuple passed as argument should have tooltips ' for each_widget in widget_list: try: each_widget.setToolTip(each_widget.text()) except: each_widget.setToolTip(each_widget.currentText()) finally: each_widget.setCursor(QCursor(Qt.PointingHandCursor)) def must_autofillbackground(widget_list): ' widget tuple passed as argument should have filled background ' for each_widget in widget_list: try: each_widget.setAutoFillBackground(True) except: pass def must_glow(widget_list): ' apply an glow effect to the widget ' for glow, each_widget in enumerate(widget_list): try: if each_widget.graphicsEffect() is None: glow = QGraphicsDropShadowEffect(self) glow.setOffset(0) glow.setBlurRadius(99) glow.setColor(QColor(99, 255, 255)) each_widget.setGraphicsEffect(glow) # glow.setEnabled(False) try: each_widget.clicked.connect(lambda: each_widget.graphicsEffect().setEnabled(True) if each_widget.graphicsEffect().isEnabled() is False else each_widget.graphicsEffect().setEnabled(False)) except: each_widget.sliderPressed.connect(lambda: each_widget.graphicsEffect().setEnabled(True) if each_widget.graphicsEffect().isEnabled() is False else each_widget.graphicsEffect().setEnabled(False)) except: pass ####################################################################### # dock 1 QLabel('<h1 style="color:white;"> Record !</h1>', self.dock1).resize( self.dock3.size().width() / 4, 25) self.group1 = QGroupBox() self.group1.setTitle(__doc__) self.spec = QPushButton(self) self.spec.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.spec.setMinimumSize(self.spec.size().width(), 250) self.spec.setFlat(True) self.spec.clicked.connect(self.spectro) self.clock = QLCDNumber() self.clock.setSegmentStyle(QLCDNumber.Flat) self.clock.setMinimumSize(self.clock.size().width(), 50) self.clock.setNumDigits(25) self.timer1 = QTimer(self) self.timer1.timeout.connect(lambda: self.clock.display( datetime.now().strftime("%d-%m-%Y %H:%M:%S %p"))) self.timer1.start(1000) self.clock.setToolTip(datetime.now().strftime("%c %x")) self.clock.setCursor(QCursor(Qt.CrossCursor)) self.diskBar = QProgressBar() self.diskBar.setMinimum(0) self.diskBar.setMaximum(statvfs(HOME).f_blocks * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) self.diskBar.setValue(statvfs(HOME).f_bfree * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) self.diskBar.setToolTip(str(statvfs(HOME).f_bfree * statvfs(HOME).f_frsize / 1024 / 1024 / 1024) + ' Gigabytes free') self.feedback = QPlainTextEdit(''.join(('<center><h3>', __doc__, ', version', __version__, __license__, ' <br> by ', __author__, ' <i>(Dev)</i>, Radio Comunitaria FM Reconquista <i>(Q.A.)</i><br>', 'FMReconquista.org.ar & GitHub.com/JuanCarlosPaco/Cinta-Testigo'))) self.rec = QPushButton(QIcon.fromTheme("media-record"), 'Record') self.rec.setMinimumSize(self.rec.size().width(), 50) self.rec.clicked.connect(self.go) # self.run self.stop = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop') self.stop.clicked.connect(self.end) self.kill = QPushButton(QIcon.fromTheme("process-stop"), 'Kill') self.kill.clicked.connect(self.killer) vboxg1 = QVBoxLayout(self.group1) for each_widget in ( QLabel('<b style="color:white;"> Spectro'), self.spec, QLabel('<b style="color:white;"> Time '), self.clock, QLabel('<b style="color:white;"> Disk '), self.diskBar, QLabel('<b style="color:white;"> STDOUT + STDIN '), self.feedback, QLabel('<b style="color:white;"> Record '), self.rec, self.stop, self.kill): vboxg1.addWidget(each_widget) self.group2 = QGroupBox() self.group2.setTitle(__doc__) self.slider = QSlider(self) self.slid_l = QLabel(self.slider) self.slider.setCursor(QCursor(Qt.OpenHandCursor)) self.slider.sliderPressed.connect(lambda: self.slider.setCursor(QCursor(Qt.ClosedHandCursor))) self.slider.sliderReleased.connect(lambda: self.slider.setCursor(QCursor(Qt.OpenHandCursor))) self.slider.valueChanged.connect(lambda: self.slider.setToolTip(str(self.slider.value()))) self.slider.valueChanged.connect(lambda: self.slid_l.setText( '<h2 style="color:white;">{}'.format(self.slider.value()))) self.slider.setMinimum(10) self.slider.setMaximum(99) self.slider.setValue(30) self.slider.setOrientation(Qt.Vertical) self.slider.setTickPosition(QSlider.TicksBothSides) self.slider.setTickInterval(2) self.slider.setSingleStep(10) self.slider.setPageStep(10) vboxg2 = QVBoxLayout(self.group2) for each_widget in ( QLabel('<b style="color:white;">MINUTES of recording'), self.slider, QLabel('<b style="color:white;"> Default: 30 Min')): vboxg2.addWidget(each_widget) group3 = QGroupBox() group3.setTitle(__doc__) try: self.label2 = QLabel(getoutput('sox --version', shell=True)) self.label4 = QLabel(getoutput('arecord --version', shell=1)[:25]) self.label6 = QLabel(str(getoutput('oggenc --version', shell=True))) except: print(''' ERROR: No SOX, OGGenc avaliable ! ( sudo apt-get install vorbis-tools sox alsa-utils ) ''') exit() self.button5 = QPushButton(QIcon.fromTheme("audio-x-generic"), 'OGG --> ZIP') self.button5.clicked.connect(lambda: make_archive( str(QFileDialog.getSaveFileName(self, "Save OGG to ZIP file As...", getcwd(), ';;(*.zip)', 'zip')).replace('.zip', ''), "zip", path.abspath(path.join(getcwd(), str(datetime.now().year))))) self.button1 = QPushButton(QIcon.fromTheme("folder-open"), 'Files') self.button1.clicked.connect(lambda: call('xdg-open ' + getcwd(), shell=True)) self.button0 = QPushButton( QIcon.fromTheme("preferences-desktop-screensaver"), 'LCD OFF') self.button0.clicked.connect(lambda: call('sleep 3 ; xset dpms force off', shell=True)) vboxg3 = QVBoxLayout(group3) for each_widget in ( QLabel('<b style="color:white;"> OGG Output Codec '), self.label6, QLabel('<b style="color:white;"> Raw Record Backend '), self.label4, QLabel('<b style="color:white;"> Helper Libs '), self.label2, QLabel('<b style="color:white;"> OGG ZIP '), self.button5, QLabel('<b style="color:white;"> Files '), self.button1, QLabel('<b style="color:white;"> LCD '), self.button0): vboxg3.addWidget(each_widget) container = QWidget() hbox = QHBoxLayout(container) for each_widget in (self.group2, self.group1, group3): hbox.addWidget(each_widget) self.dock1.setWidget(container) # dock 2 QLabel('<h1 style="color:white;"> Hardware !</h1>', self.dock2).resize( self.dock2.size().width() / 4, 25) try: audioDriverStr = {Solid.AudioInterface.Alsa: "ALSA", Solid.AudioInterface.OpenSoundSystem: "Open Sound", Solid.AudioInterface.UnknownAudioDriver: "Unknown?"} audioInterfaceTypeStr = { Solid.AudioInterface.AudioControl: "Control", Solid.AudioInterface.UnknownAudioInterfaceType: "Unknown?", Solid.AudioInterface.AudioInput: "In", Solid.AudioInterface.AudioOutput: "Out"} soundcardTypeStr = { Solid.AudioInterface.InternalSoundcard: "Internal", Solid.AudioInterface.UsbSoundcard: "USB3", Solid.AudioInterface.FirewireSoundcard: "FireWire", Solid.AudioInterface.Headset: "Headsets", Solid.AudioInterface.Modem: "Modem"} display = QTreeWidget() display.setAlternatingRowColors(True) display.setHeaderLabels(["Items", "ID", "Drivers", "I / O", "Type"]) display.setColumnWidth(0, 350) display.setColumnWidth(1, 350) display.setColumnWidth(3, 75) # retrieve a list of Solid.Device for this machine deviceList = Solid.Device.allDevices() # filter the list of all devices and display matching results # note that we never create a Solid.AudioInterface object, but # receive one from the 'asDeviceInterface' call for device in deviceList: if device.isDeviceInterface( Solid.DeviceInterface.AudioInterface): audio = device.asDeviceInterface( Solid.DeviceInterface.AudioInterface) devtype = audio.deviceType() devstr = [] for key in audioInterfaceTypeStr: flag = key & devtype if flag: devstr.append(audioInterfaceTypeStr[key]) QTreeWidgetItem(display, [device.product(), audio.name(), audioDriverStr[audio.driver()], "/".join(devstr), soundcardTypeStr[audio.soundcardType()]]) self.dock2.setWidget(display) except: self.dock2.setWidget(QLabel(""" <center style='color:white;'> <h1>:(<br>ERROR: Please, install PyKDE !</h1><br> <br><i> (Sorry, can not use non-Qt Libs). Thanks </i><center>""")) ## dock 3 QLabel('<h1 style="color:white;"> Previews !</h1>', self.dock3).resize( self.dock3.size().width() / 4, 25) self.fileView = QColumnView() self.fileView.updatePreviewWidget.connect(self.play) self.fileView.setToolTip(' Browse and Preview Files ') self.media = None self.model = QDirModel() self.fileView.setModel(self.model) self.dock3.setWidget(self.fileView) # dock4 QLabel('<h1 style="color:white;"> Setup !</h1>', self.dock4).resize( self.dock4.size().width() / 4, 25) self.group4 = QGroupBox() self.group4.setTitle(__doc__) self.combo0 = QComboBox() self.combo0.addItems(['S16_LE', 'S32_LE', 'S16_BE', 'U16_LE', 'U16_BE', 'S24_LE', 'S24_BE', 'U24_LE', 'U24_BE', 'S32_BE', 'U32_LE', 'U32_BE']) self.combo1 = QComboBox() self.combo1.addItems(['1', '-1', '0', '2', '3', '4', '5', '6', '7', '8', '9', '10']) self.combo2 = QComboBox() self.combo2.addItems(['128', '256', '512', '1024', '64', '32', '16']) self.combo3 = QComboBox(self) self.combo3.addItems(['MONO', 'STEREO', 'Surround']) self.combo4 = QComboBox() self.combo4.addItems(['44100', '96000', '48000', '32000', '22050', '16000', '11025', '8000']) self.combo5 = QComboBox(self) self.combo5.addItems(['20', '19', '18', '17', '16', '15', '14', '13', '12', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0']) self.nepochoose = QCheckBox('Auto-Tag Files using Nepomuk Semantic') self.chckbx0 = QCheckBox('Disable Software based Volume Control') self.chckbx1 = QCheckBox('Output Sound Stereo-to-Mono Downmix') self.chckbx2 = QCheckBox('Add Date and Time MetaData to Sound files') self.chckbx3 = QCheckBox('Add Yourself as the Author Artist of Sound') vboxg4 = QVBoxLayout(self.group4) for each_widget in ( QLabel('<b style="color:white;"> Sound OGG Quality'), self.combo1, QLabel('<b style="color:white;"> Sound Record Format'), self.combo0, QLabel('<b style="color:white;"> Sound KBps '), self.combo2, QLabel('<b style="color:white;"> Sound Channels '), self.combo3, QLabel('<b style="color:white;"> Sound Sample Rate '), self.combo4, QLabel('<b style="color:white;"> Sound Volume'), self.chckbx0, QLabel('<b style="color:white;"> Sound Mix'), self.chckbx1, QLabel('<b style="color:white;"> Sound Meta'), self.chckbx2, QLabel('<b style="color:white;"> Sound Authorship'), self.chckbx3, QLabel('<b style="color:white;"> CPUs Priority'), self.combo5, QLabel('<b style="color:white;">Nepomuk Semantic User Experience'), self.nepochoose): vboxg4.addWidget(each_widget) self.dock4.setWidget(self.group4) # dock 5 QLabel('<h1 style="color:white;"> Voice Changer ! </h1>', self.dock5 ).resize(self.dock5.size().width() / 3, 25) self.group5 = QGroupBox() self.group5.setTitle(__doc__) self.dial = QDial() self.dial.setCursor(QCursor(Qt.OpenHandCursor)) self.di_l = QLabel(self.dial) self.di_l.resize(self.dial.size() / 8) self.dial.sliderPressed.connect(lambda: self.dial.setCursor(QCursor(Qt.ClosedHandCursor))) self.dial.sliderReleased.connect(lambda: self.dial.setCursor(QCursor(Qt.OpenHandCursor))) self.dial.valueChanged.connect(lambda: self.dial.setToolTip(str(self.dial.value()))) self.dial.valueChanged.connect(lambda: self.di_l.setText( '<h1 style="color:white;">{}'.format(self.dial.value()))) self.dial.setValue(0) self.dial.setMinimum(-999) self.dial.setMaximum(999) self.dial.setSingleStep(100) self.dial.setPageStep(100) self.dial.setWrapping(False) self.dial.setNotchesVisible(True) self.defo = QPushButton(QIcon.fromTheme("media-playback-start"), 'Run') self.defo.setMinimumSize(self.defo.size().width(), 50) self.defo.clicked.connect(lambda: self.process3.start( 'play -q -V0 "|rec -q -V0 -n -d -R riaa pitch {} "' .format(self.dial.value()) if int(self.dial.value()) != 0 else 'play -q -V0 "|rec -q -V0 --multi-threaded -n -d -R bend {} "' .format(' 3,2500,3 3,-2500,3 ' * 999))) self.qq = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop') self.qq.clicked.connect(self.process3.kill) self.die = QPushButton(QIcon.fromTheme("process-stop"), 'Kill') self.die.clicked.connect(lambda: call('killall rec', shell=True)) vboxg5 = QVBoxLayout(self.group5) for each_widget in (self.dial, self.defo, self.qq, self.die): vboxg5.addWidget(each_widget) self.dock5.setWidget(self.group5) # configure some widget settings must_be_checked((self.nepochoose, self.chckbx1, self.chckbx2, self.chckbx3)) must_have_tooltip((self.label2, self.label4, self.label6, self.combo0, self.nepochoose, self.combo1, self.combo2, self.combo3, self.combo4, self.combo5, self.chckbx0, self.chckbx1, self.chckbx2, self.chckbx3, self.rec, self.stop, self.defo, self.qq, self.die, self.kill, self.button0, self.button1, self.button5)) must_autofillbackground((self.clock, self.label2, self.label4, self.label6, self.nepochoose, self.chckbx0, self.chckbx1, self.chckbx2, self.chckbx3)) must_glow((self.rec, self.dial, self.combo1)) self.nepomuk_get('testigo') if self.auto is True: self.go() def play(self, index): ' play with delay ' if not self.media: self.media = Phonon.MediaObject(self) audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self) Phonon.createPath(self.media, audioOutput) self.media.setCurrentSource(Phonon.MediaSource( self.model.filePath(index))) self.media.play() def end(self): ' kill it with fire ' print((' INFO: Stoping Processes at {}'.format(str(datetime.now())))) self.process1.terminate() self.process2.terminate() self.feedback.setText(''' <h5>Errors for RECORDER QProcess 1:</h5>{}<hr> <h5>Errors for ENCODER QProcess 2:</h5>{}<hr> <h5>Output for RECORDER QProcess 1:</h5>{}<hr> <h5>Output for ENCODER QProcess 2:</h5>{}<hr> '''.format(self.process1.readAllStandardError(), self.process2.readAllStandardError(), self.process1.readAllStandardOutput(), self.process2.readAllStandardOutput(), )) def killer(self): ' kill -9 ' QMessageBox.information(self.mainwidget, __doc__, ' KILL -9 was sent to the multi-process backend ! ') self.process1.kill() self.process2.kill() def go(self): ' run timeout re-starting timers ' self.timerFirst.start(int(self.slider.value()) * 60 * 1000 + 2000) self.timerSecond.start(int(self.slider.value()) * 60 * 1000 + 2010) self.run() def run(self): ' run forest run ' print((' INFO: Working at {}'.format(str(datetime.now())))) chnl = 1 if self.combo3.currentText() == 'MONO' else 2 print((' INFO: Using {} Channels . . . '.format(chnl))) btrt = int(self.combo4.currentText()) print((' INFO: Using {} Hz per Second . . . '.format(btrt))) threshold = int(self.dial.value()) print((' INFO: Using Thresold of {} . . . '.format(threshold))) print((' INFO: Using Recording time of {}'.format(self.slider.value()))) frmt = str(self.combo0.currentText()).strip() print((' INFO: Using Recording quality of {} ...'.format(frmt))) qlt = str(self.combo1.currentText()).strip() print((' INFO: Using Recording quality of {} ...'.format(qlt))) prio = str(self.combo5.currentText()).strip() print((' INFO: Using CPU Priority of {} ...'.format(prio))) downmix = '--downmix ' if self.chckbx1.isChecked() is True else '' print((' INFO: Using Downmix is {} ...'.format(downmix))) aut = '-a ' + getuser() if self.chckbx3.isChecked() is True else '' print((' INFO: The Author Artist of this sound is: {}'.format(aut))) T = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") tim = '--date {} '.format(T) if self.chckbx2.isChecked() is True else '' print((' INFO: The Date and Time of this sound is: {}'.format(tim))) vol = ' --disable-softvol' if self.chckbx0.isChecked() is True else '' print((' INFO: Software based Volume Control is: {}'.format(vol))) # make base directory try: mkdir(self.base) print((' INFO: Base Directory path created {}'.format(self.base))) except OSError: print((' INFO: Base Directory already exist {}'.format(self.base))) except: print((' ERROR: Can not create Directory ?, {}'.format(self.base))) # make directory tree try: for dr in range(1, 13): mkdir(path.abspath(path.join(self.base, str(dr)))) print((' INFO:Directory created {}/{}'.format(self.base, dr))) except OSError: print((' INFO: Directory already exist {}/1,12'.format(self.base))) except: print((' ERROR: Cant create Directory?, {}/1,12'.format(self.base))) # make new filename flnm = path.abspath(path.join(self.base, str(datetime.now().month), datetime.now().strftime("%Y-%m-%d_%H:%M:%S.ogg"))) self.actual_file = flnm print((' INFO: Recording on the file {}'.format(flnm))) # make custom commands cmd1 = self.cmd1.format(n=prio, f=frmt, c=chnl, b=btrt, v=vol) cmd2 = self.cmd2.format(c=chnl, b=btrt, q=qlt, d=downmix, o=flnm, a=aut, t=tim) print((cmd1, cmd2)) # multiprocess recording loop pipe self.process1 = QProcess(self) self.process2 = QProcess(self) self.process1.setStandardOutputProcess(self.process2) self.process1.start(cmd1) if not self.process1.waitForStarted(): print((" ERROR: RECORDER QProcess 1 Failed: \n {} ".format(cmd1))) self.process2.start(cmd2) if not self.process2.waitForStarted(): print((" ERROR: ENCODER QProcess 2 Failed: \n {} ".format(cmd2))) self.nepomuk_set(flnm, 'testigo', 'testigo', 'AutoTag by Cinta-Testigo') def spectro(self): ' spectrometer ' wid = self.spec.size().width() hei = self.spec.size().height() command = self.cmd3.format(o=self.actual_file, x=wid, y=hei) print(' INFO: Spectrometer is deleting OLD .ogg.png Files on target ') call('rm --verbose --force {}/*/*.ogg.png'.format(self.base), shell=1) print(' INFO: Spectrometer finished Deleting Files, Starting Render ') call(command, shell=True) print((''' INFO: Spectrometer finished Rendering Sound using: {}{} OutPut: {}'''.format(command, linesep, self.actual_file))) self.spec.setIcon(QIcon('{o}.png'.format(o=self.actual_file))) self.spec.setIconSize(QSize(wid, hei)) self.spec.resize(wid, hei) ########################################################################### def paintEvent(self, event): 'Paint semi-transparent background, animated pattern, background text' QWidget.paintEvent(self, event) # make a painter p = QPainter(self) p.setRenderHint(QPainter.TextAntialiasing) p.setRenderHint(QPainter.HighQualityAntialiasing) # fill a rectangle with transparent painting p.fillRect(event.rect(), Qt.transparent) # animated random dots background pattern for i in range(4096): x = randint(9, self.size().width() - 9) y = randint(9, self.size().height() - 9) p.setPen(QPen(QColor(randint(200, 255), randint(200, 255), 255), 1)) p.drawPoint(x, y) # set pen to use white color p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1)) # Rotate painter 45 Degree p.rotate(35) # Set painter Font for text p.setFont(QFont('Ubuntu', 300)) # draw the background text, with antialiasing p.drawText(99, 199, "Radio") # Rotate -45 the QPen back ! p.rotate(-35) # set the pen to no pen p.setPen(Qt.NoPen) # Background Color p.setBrush(QColor(0, 0, 0)) # Background Opacity p.setOpacity(0.75) # Background Rounded Borders p.drawRoundedRect(self.rect(), 50, 50) # finalize the painter p.end() def seTitle(self): ' set the title of the main window ' dialog = QDialog(self) textEditInput = QLineEdit(' Type Title Here ') ok = QPushButton(' O K ') ok.clicked.connect(lambda: self.setWindowTitle(textEditInput.text())) ly = QVBoxLayout() [ly.addWidget(wdgt) for wdgt in (QLabel('Title:'), textEditInput, ok)] dialog.setLayout(ly) dialog.exec_() def timedate(self): ' get the time and date ' dialog = QDialog(self) clock = QLCDNumber() clock.setNumDigits(24) timer = QTimer() timer.timeout.connect(lambda: clock.display( datetime.now().strftime("%d-%m-%Y %H:%M:%S %p"))) timer.start(1000) clock.setToolTip(datetime.now().strftime("%c %x")) ok = QPushButton(' O K ') ok.clicked.connect(dialog.close) ly = QVBoxLayout() [ly.addWidget(wdgt) for wdgt in (QCalendarWidget(), clock, ok)] dialog.setLayout(ly) dialog.exec_() def closeEvent(self, event): ' Ask to Quit ' if QMessageBox.question(self, ' Close ', ' Quit ? ', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes: event.accept() else: event.ignore() def center(self): ' Center and resize the window ' self.showNormal() self.resize(QDesktopWidget().screenGeometry().width() // 1.25, QDesktopWidget().screenGeometry().height() // 1.25) qr = self.frameGeometry() qr.moveCenter(QDesktopWidget().availableGeometry().center()) self.move(qr.topLeft()) def nepomuk_set(self, file_tag=None, __tag='', _label='', _description=''): ' Quick and Easy Nepomuk Taggify for Files ' print((''' INFO: Semantic Desktop Experience is Tagging Files : {}, {}, {}, {})'''.format(file_tag, __tag, _label, _description))) if Nepomuk.ResourceManager.instance().init() is 0: fle = Nepomuk.Resource(KUrl(QFileInfo(file_tag).absoluteFilePath())) _tag = Nepomuk.Tag(__tag) _tag.setLabel(_label) fle.addTag(_tag) fle.setDescription(_description) print(([str(a.label()) for a in fle.tags()], fle.description())) return ([str(a.label()) for a in fle.tags()], fle.description()) else: print(" ERROR: FAIL: Nepomuk is not running ! ") def nepomuk_get(self, query_to_search): ' Quick and Easy Nepomuk Query for Files ' print((''' INFO: Semantic Desktop Experience is Quering Files : {} '''.format(query_to_search))) results = [] nepo = Nepomuk.Query.QueryServiceClient() nepo.desktopQuery("hasTag:{}".format(query_to_search)) def _query(data): ''' ('filename.ext', 'file description', ['list', 'of', 'tags']) ''' results.append(([str(a.resource().genericLabel()) for a in data][0], [str(a.resource().description()) for a in data][0], [str(a.label()) for a in iter([a.resource().tags() for a in data][0] )])) nepo.newEntries.connect(_query) def _end(): ''' [ ('filename.ext', 'file description', ['list', 'of', 'tags']), ('filename.ext', 'file description', ['list', 'of', 'tags']), ('filename.ext', 'file description', ['list', 'of', 'tags']) ] ''' nepo.newEntries.disconnect print(results) return results nepo.finishedListing.connect(_end)
class CImprovedButton(QToolButton): def __init__(self, parent=None): QToolButton.__init__(self, parent) #TESTO ALTERNATIVO #Spesso se il pulsante ha icona troppo grossa e quando per ragioni di spazio o altro non si può spostare #o ridimensionare il pulsante stesso, la label ha posizioni assurde e schifose. Aggiungerne una "+ controllabile" #è l'unico modo.. self.__fixed_label = QLabel("alternative label", self) self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.__fixed_label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__font = QtGui.QFont("Arial", 10) self.__fixed_label.setFont(self.__font) self.__fixed_label.show() #INDICATORE STILE iOS self.__indicator = QLabel("0", self) self.__indicator.setStyleSheet( "border-image: url(':/images/backgrounds/indicator.png'); padding-right:1px; color: white;" ) self.__indicator.geometry().setWidth(25) self.__indicator.geometry().setHeight(20) self.__indicator.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__indicator.setVisible(False) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) #default top-right corner #Quando il pulsante viene ridimensionato (designer o meno) devo anche sistemare la label di conseguenza self.resizeEvent = self.__onResize self.__indicator.resizeEvent = self.__on_indicator_Resize self.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.clicked.connect(self.stopAllAnimations) #BLINK self.__blink_timer = QTimer(parent) self.__blink_timer.timeout.connect(self.__on_blink_timer) self.__blink_timer_interval = 1000 #FADING self.__opacity_effect = QGraphicsOpacityEffect() self.__fading_timer = QTimer(parent) self.__fading_timer.timeout.connect(self.__on_fading_timer) self.__FADE_TYPE = Enum("IN", "OUT") self.__fade_time = 20 self.__opacity = 1.0 self.__opacity_fading_coefficient = 0.02 self.__selected_fade_type = self.__FADE_TYPE.IN # ANIMAZIONI GROW self.__animationGrow = QPropertyAnimation(self, "iconSize", self) self.__animationGrow.setDuration(1000) self.__animationGrow.setEasingCurve(QEasingCurve.Linear) self.__animationGrow.finished.connect(self.__on_growed) self.__animationShrink = QPropertyAnimation(self, "iconSize", self) self.__animationShrink.setDuration(1000) self.__animationShrink.setEasingCurve(QEasingCurve.Linear) self.__animationShrink.finished.connect(self.__on_shrinked) self.__defaultIconDimension = 60 self.__iconGrowsBy = 40 self.__growing = False # ANIMAZIONI BOUNCE self.__animationUp = QPropertyAnimation(self, "pos", self) self.__animationUp.setDuration(200) self.__animationUp.setEasingCurve(QEasingCurve.Linear) self.__animationUp.finished.connect(self.__on_top_reached) self.__animationBounce = QPropertyAnimation(self, "pos", self) self.__animationBounce.setDuration(1000) self.__animationBounce.setEasingCurve(QEasingCurve.OutBounce) self.__animationBounce.finished.connect(self.__on_bounce_finished) self.__bouncing = False self.__startPos = QPoint(self.pos().x(), self.pos().y()) #PIXMAP & MASCHERA self.__pmap = QPixmap(self.size()) self.__pmap_fname = "" self.__show_mask_preview = False def setDefaultIconSize(self, value): """ Sets default icon size when growing stops. @param value: size (both width and height) @type value: int """ self.__defaultIconDimension = value def getDefaultIconSize(self): return self.__defaultIconDimension defaultIconSize = QtCore.pyqtProperty("int", getDefaultIconSize, setDefaultIconSize) def setFixetTextVisibility(self, bool): """ Sets if fixed text is visible or not. @param bool: visible or not @type bool: bool """ self.__fixed_label.setVisible(bool) def getFixetTextVisibility(self): return self.__fixed_label.isVisible() fixetTextVisibility = QtCore.pyqtProperty("bool", fget=getFixetTextVisibility, fset=setFixetTextVisibility) def setFixedText(self, txt): """ Sets text on the button. @param txt: text @type txt: string """ self.__fixed_label.setText(txt) def getFixedText(self): return self.__fixed_label.text() fixedText = QtCore.pyqtProperty("QString", getFixedText, setFixedText) def setFixedTextPos(self, qpoint): """ Sets text position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__fixed_label.move(qpoint) def getFixedTextPos(self): return self.__fixed_label.pos() fixedTextPos = QtCore.pyqtProperty("QPoint", getFixedTextPos, setFixedTextPos) def setFixedTextFont(self, font): """ Sets text font. @param font: Font for fixed text. @type font: QFont """ self.__font = font self.__fixed_label.setFont(self.__font) def getFixedTextFont(self): return self.__font fixedTextFont = QtCore.pyqtProperty("QFont", getFixedTextFont, setFixedTextFont) #FUNZIONI INDICATORE def setIndicatorVisibility(self, bool): """ Sets if indicator is visible or not. @param bool: visible or not @type bool: bool """ self.__indicator.setVisible(bool) def getIndicatorVisibility(self): return self.__indicator.isVisible() indicatorVisibility = QtCore.pyqtProperty("bool", fget=getIndicatorVisibility, fset=setIndicatorVisibility) def setIndicatorPos(self, qpoint): """ Sets indicator position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__indicator.move(qpoint) def getIndicatorPos(self): return self.__indicator.pos() indicatorPos = QtCore.pyqtProperty("QPoint", getIndicatorPos, setIndicatorPos) def setIndicatorSize(self, size): """ Sets indicator size. @param size: Size @type size: QSize """ self.__indicator.resize(size) def getIndicatorSize(self): return self.__indicator.size() indicatorSize = QtCore.pyqtProperty("QSize", getIndicatorSize, setIndicatorSize) def setIndicatorFont(self, font): """ Sets indicator text font. @param font: Font for indicator text. @type font: QFont """ self.__indicator.setFont(font) def getIndicatorFont(self): return self.__indicator.font() indicatorFont = QtCore.pyqtProperty("QFont", getIndicatorFont, setIndicatorFont) ## FUNZIONI PER BLINK def __on_blink_timer(self): self.setVisible(not (self.isVisible())) def setBlinking(self, blink): """ Sets if the button have to blink or not. @param blink: blinking or not @type blink: bool """ if blink: self.__blink_timer.setInterval(self.__blink_timer_interval) self.__blink_timer.start() else: self.__blink_timer.stop() self.setVisible(True) def setBlinkInterval(self, value): """ Sets blink interval. @param blink: blink interval (msec) @type blink: int """ self.__blink_timer_interval = value def getBlinkInterval(self): return self.__blink_timer_interval blinkInterval = QtCore.pyqtProperty("int", getBlinkInterval, setBlinkInterval) ##FUNZIONI PER FADING def fadeIn(self): """ Button fades in from completely invisible to completely visible. """ self.__opacity = 0.0 self.__selected_fade_type = self.__FADE_TYPE.IN self.__fading_timer.start(self.__fade_time) def fadeOut(self): """ Button fades out from completely visible to completely invisible. """ self.__selected_fade_type = self.__FADE_TYPE.OUT self.__fading_timer.start(self.__fade_time) def setFadeTime(self, value): """ Sets fading time. Everytime interval is reached, alpha is increased (or decreased) by __opacity_fading_coefficient. @param value: fade time (msec) @type value: int """ self.__fade_time = value def getFadeTime(self): return self.__fade_time fadeInterval = QtCore.pyqtProperty("int", getFadeTime, setFadeTime) def setFadeCoefficient(self, value): """ Sets fading coefficient. Alpha is increased (or decreased) by this value. @param value: coefficient (min 0.0 - max 1.0) @type value: float """ self.__opacity_fading_coefficient = value def getFadeCoefficient(self): return self.__opacity_fading_coefficient fadeCoefficient = QtCore.pyqtProperty("double", getFadeCoefficient, setFadeCoefficient) def __on_fading_timer(self): if self.__selected_fade_type == self.__FADE_TYPE.OUT: if self.__opacity > 0: self.__opacity -= self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() if self.__selected_fade_type == self.__FADE_TYPE.IN: if self.__opacity <= 1.0: self.__opacity += self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() # FUNZIONI PER GROW\SHRINK def __on_growed(self): self.__animationShrink.setStartValue( QSize(self.iconSize().width(), self.iconSize().height())) self.__animationShrink.setEndValue( QSize(self.iconSize().width() - self.__iconGrowsBy, self.iconSize().height() - self.__iconGrowsBy)) self.__animationShrink.start() def __on_shrinked(self): self.__animationGrow.setStartValue( QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() def startGrow(self): """ Button ICON starts to grow and shrink to standard value when maximum size (configured) is reached """ if self.__growing: return self.__animationGrow.setStartValue( QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() self.__growing = True def stopGrow(self): if self.__animationGrow.startValue().toSize() != QSize( 0, 0) and self.__animationShrink.startValue().toSize() != QPoint( 0, 0): self.__animationGrow.stop() self.__animationShrink.stop() self.setIconSize( QSize(self.__defaultIconDimension, self.__defaultIconDimension)) self.__growing = False #FUNZIONI PER BOUNCE def startBounce(self): """ Button starts to bounce requiring attention. """ if self.__bouncing: return self.__startPos = QPoint(self.pos().x(), self.pos().y()) self.__animationUp.setStartValue( QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationUp.setEndValue( QPoint(self.__startPos.x(), self.__startPos.y() - self.geometry().height())) self.__animationUp.start() self.__bouncing = True def stopBounce(self): if self.__animationUp.startValue().toPoint() != QPoint( 0, 0) and self.__animationBounce.startValue().toPoint() != QPoint( 0, 0): self.__animationBounce.stop() self.__animationUp.stop() self.setGeometry(self.__startPos.x(), self.__startPos.y(), self.geometry().width(), self.geometry().height()) self.__bouncing = False def __on_top_reached(self): self.__animationBounce.setStartValue( QPoint(self.pos().x(), self.pos().y())) self.__animationBounce.setEndValue( QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationBounce.start() def __on_bounce_finished(self): self.__animationUp.start() def stopAllAnimations(self): self.stopBounce() self.stopGrow() #FUNZIONI PER PIXMAP & MASCHERA def setPixmapFile(self, image_file): self.__pmap = image_file self.__pmap.scaled(self.size()) #NB: Il pixmap deve essere BIANCO e NERO. Con heuristicMask il primo pixel in alto a sinistra (0,0) viene #usato per decidere il colore trasparente, tutto il resto è visibile. def getPixmapFile(self): return self.__pmap pixmapFile = QtCore.pyqtProperty("QPixmap", getPixmapFile, setPixmapFile) def applyMask(self, bool): self.__show_mask_preview = bool if bool: self.setMask( QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) else: self.setMask(QBitmap()) def getMask(self): return self.__show_mask_preview appliedMask = QtCore.pyqtProperty("bool", fget=getMask, fset=applyMask) def __onResize(self, event): self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) self.__pmap.scaled(self.size()) if self.__show_mask_preview: self.setMask( QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) def __on_indicator_Resize(self, event): self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0))
class MainWidget(QWidget, Ui_MainWidget): def __init__(self, parent=None, silence = False): QWidget.__init__(self, parent) self.setupUi(self) self.parent = parent self._selectedGroups = [] self.state = StateManager(self) self.lastState = self.state.state self.state.silence = silence if not silence: self.searchButton.setIcon(KIcon("edit-find")) self.statusUpdater = StatusUpdater() self.basket = BasketDialog(self.state) self.searchUsed = False self.initializeInfoBox() self.initialize() self.updateSettings() self.actionButton.setIcon(self.state.getActionIcon()) self.connectMainSignals() self.operation = OperationManager(self.state) self.progressDialog = ProgressDialog(self.state) self.summaryDialog = SummaryDialog() self.connectOperationSignals() def initializeInfoBox(self): # An info label to show a proper information, # if there is no updates available. self.info = QLabel(self) self.info.setText(i18n("All Packages are up to date")) self.info.setAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.info.setStyleSheet("background-color:rgba(0,0,0,220); \ color:white; \ border: 1px solid white; \ border-top-left-radius: 10px; \ border-top-right-radius: 10px; \ ") self.info.resize(self.size()) self.info.hide() #def resizeEvent(self, event): # info label should be resized automatically, # if the mainwindow resized. #width = self.width() #height = 40 #self.info.resize(QSize(width, height)) #self.info.move(0,self.height()-height)#self.width() / 2 - 170, self.height() / 2 - 40) def connectMainSignals(self): self.connect(self.actionButton, SIGNAL("clicked()"), self.showBasket) self.connect(self.searchButton, SIGNAL("clicked()"), self.searchActivated) self.connect(self.searchLine, SIGNAL("textEdited(const QString&)"), self.searchLineChanged) self.connect(self.searchLine, SIGNAL("returnPressed()"), self.searchActivated) self.connect(self.searchLine, SIGNAL("clearButtonClicked()"), self.groupFilter) # self.connect(self.typeCombo, SIGNAL("activated(int)"), self.typeFilter) self.connect(self.groupList, SIGNAL("groupChanged()"), self.groupFilter) self.connect(self.groupList, SIGNAL("groupChanged()"), lambda:self.searchButton.setEnabled(False)) self.connect(self.selectAll, SIGNAL("clicked(bool)"), self.toggleSelectAll) self.connect(self.statusUpdater, SIGNAL("selectedInfoChanged(int, QString, int, QString)"), self.emitStatusBarInfo) self.connect(self.statusUpdater, SIGNAL("selectedInfoChanged(QString)"), lambda message: self.emit(SIGNAL("selectionStatusChanged(QString)"), message)) self.connect(self.statusUpdater, SIGNAL("finished()"), self.statusUpdated) def connectOperationSignals(self): self.connect(self.operation, SIGNAL("exception(QString)"), self.exceptionCaught) self.connect(self.operation, SIGNAL("finished(QString)"), self.actionFinished) self.connect(self.operation, SIGNAL("started(QString)"), self.actionStarted) self.connect(self.operation, SIGNAL("started(QString)"), self.progressDialog.updateActionLabel) self.connect(self.operation, SIGNAL("operationCancelled()"), self.actionCancelled) self.connect(self.operation, SIGNAL("progress(int)"), self.progressDialog.updateProgress) self.connect(self.operation, SIGNAL("operationChanged(QString,QString)"), self.progressDialog.updateOperation) self.connect(self.operation, SIGNAL("packageChanged(int, int, QString)"), self.progressDialog.updateStatus) self.connect(self.operation, SIGNAL("elapsedTime(QString)"), self.progressDialog.updateRemainingTime) self.connect(self.operation, SIGNAL("downloadInfoChanged(QString, QString, QString)"), self.progressDialog.updateCompletedInfo) def initialize(self): waitCursor() self._last_packages = None self.state.reset() self.initializeUpdateTypeList() self.initializePackageList() self.initializeGroupList() self.initializeStatusUpdater() self.statusChanged() self._selectedGroups = [] self.selectAll.setChecked(False) restoreCursor() QTimer.singleShot(1, self.initializeBasket) def initializeUpdateTypeList(self): self.typeCombo.clear() UPDATE_TYPES = [['normal', i18n('All Updates'), 'system-software-update'], ['security', i18n('Security Updates'), 'security-medium'], ['critical', i18n('Critical Updates'), 'security-low']] for type in UPDATE_TYPES: self.typeCombo.addItem(KIcon(type[2], KIconLoader.SizeSmallMedium), type[1], QVariant(type[0])) def initializeStatusUpdater(self): self.statusUpdater.setModel(self.packageList.model().sourceModel()) def initializeBasket(self): waitCursor() self.basket.setModel(self.packageList.model().sourceModel()) restoreCursor() def initializePackageList(self): model = PackageModel(self) proxy = PackageProxy(self) proxy.setSourceModel(model) self.packageList.setModel(proxy) self.packageList.setItemDelegate(PackageDelegate(self)) self.packageList.setColumnWidth(0, 32) self.packageList.setPackages(self.state.packages()) self.connect(self.packageList.model(), SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.statusChanged) def updateSettings(self): self.packageList.showComponents = config.PMConfig().showComponents() self.packageList.setFocus() def searchLineChanged(self, text): self.searchButton.setEnabled(bool(text)) if text == '' and self.searchUsed: self.searchActivated() def statusUpdated(self): if self.statusUpdater.needsUpdate: self.statusUpdater.needsUpdate = False self.statusChanged() def statusChanged(self): self.setActionEnabled() if self.statusUpdater.isRunning(): self.statusUpdater.needsUpdate = True else: self.emit(SIGNAL("updatingStatus()")) self.statusUpdater.start() def initializeGroupList(self): self.groupList.clear() self.groupList.setAlternatingRowColors(True) self.groupList.setIconSize(QSize(KIconLoader.SizeLarge, KIconLoader.SizeLarge)) self.groupList.setState(self.state) self.groupList.addGroups(self.state.groups()) if self.state.state == self.state.UPGRADE: self.typeCombo.show() else: self.typeCombo.hide() self.state._typeFilter = 'normal' self.groupFilter() # Show the info label if there are updates available # otherwise hide it. """ if self.state.inUpgrade() and self.groupList.count() == 0: self.info.show() else: self.info.hide() """ def packageFilter(self, text): self.packageList.model().setFilterRole(Qt.DisplayRole) self.packageList.model().setFilterRegExp(QRegExp(unicode(text), Qt.CaseInsensitive, QRegExp.FixedString)) def typeFilter(self, index): if self.state.state == self.state.UPGRADE: filter = self.typeCombo.itemData(index).toString() if not self.state._typeFilter == filter: self.state._typeFilter = filter self.initializeGroupList() def groupFilter(self): self.packageList.resetMoreInfoRow() packages = self.state.groupPackages(self.groupList.currentGroup()) self.packageList.model().setFilterRole(GroupRole) waitCursor() self.packageList.model().setFilterPackages(packages) self.packageList.scrollToTop() self.selectAll.setChecked(self.groupList.currentGroup() in self._selectedGroups) restoreCursor() def searchActivated(self): self.packageList.resetMoreInfoRow() waitCursor() searchText = str(self.searchLine.text()).split() if searchText: sourceModel = self.packageList.model().sourceModel() self.state.cached_packages = sourceModel.search(searchText) self.groupList.lastSelected = None self.searchUsed = True else: self.state.cached_packages = None self.state.packages() self.searchUsed = False self.initializeGroupList() restoreCursor() def setActionButton(self): self.actionButton.setEnabled(False) self.actionButton.setText(self.state.getActionName()) self.actionButton.setIcon(self.state.getActionIcon()) def actionStarted(self, operation): if self.state.silence: totalPackages = len(self.state._selected_packages) if not any(package.endswith('.pisi') for package in self.state._selected_packages): totalPackages += len(self.state.iface.getExtras(self.state._selected_packages)) self.progressDialog.reset() if not operation in ["System.Manager.updateRepository", "System.Manager.updateAllRepositories"]: if not self.state.silence: totalPackages = self.packageList.packageCount() self.operation.setTotalPackages(totalPackages) self.progressDialog.updateStatus(0, totalPackages, self.state.toBe()) if self.isVisible(): if operation in ["System.Manager.updateRepository", "System.Manager.updateAllRepositories"]: self.progressDialog.repoOperationView() self.progressDialog.show() self.progressDialog.enableCancel() def exceptionCaught(self, message): self.progressDialog.hide() if any(warning in message for warning in ('urlopen error','Socket Error', 'PYCURL ERROR')): errorTitle = i18n("Network Error") errorMessage = i18n("Please check your network connections and try again.") elif "Access denied" in message or "tr.org.pardus.comar.Comar.PolicyKit" in message: errorTitle = i18n("Authorization Error") errorMessage = i18n("You are not authorized for this operation.") elif "HTTP Error 404" in message: errorTitle = i18n("Pisi Error") errorMessage = i18n("Package not found. It may be upgraded in or removed from the repository. Please try upgrading repository informations.") else: errorTitle = i18n("Pisi Error") errorMessage = message self.messageBox = QMessageBox(errorTitle, errorMessage, QMessageBox.Critical, QMessageBox.Ok, 0, 0) self.messageBox.show() if self.state.state == self.state.UPGRADE: {self.state.INSTALL:self.parent.showInstallAction, self.state.REMOVE :self.parent.showRemoveAction}[self.lastState].setChecked(True) self.switchState(self.lastState) def actionFinished(self, operation): if operation == "System.Manager.installPackage": self.showSummary() if operation in ("System.Manager.installPackage", "System.Manager.removePackage", "System.Manager.updatePackage"): self.notifyFinished() if not self.state.silence: self.searchLine.clear() self.state.reset() self.progressDialog.hide() if operation in ("System.Manager.updateRepository", "System.Manager.updateAllRepositories"): self.emit(SIGNAL("repositoriesUpdated()")) self.initialize() else: qApp.exit() def actionCancelled(self): self.progressDialog.hide() if self.state.silence: qApp.exit() else: self.groupFilter() def notifyFinished(self): if not self.operation.totalPackages: return if self.state.silence: Pds.notify(i18n('Package Manager'), self.state.getSummaryInfo(self.operation.totalPackages)) elif Pds.session == pds.Kde4: from PyKDE4.kdeui import KNotification from PyKDE4.kdecore import KComponentData KNotification.event("Summary", self.state.getSummaryInfo(self.operation.totalPackages), QPixmap(), None, KNotification.CloseOnTimeout, KComponentData("package-manager", "package-manager", KComponentData.SkipMainComponentRegistration) ) else: Pds.notify(i18n('Package Manager'), self.state.getSummaryInfo(self.operation.totalPackages)) def showSummary(self): self.summaryDialog.setDesktopFiles(self.operation.desktopFiles) if self.summaryDialog.hasApplication(): self.summaryDialog.show() def setActionEnabled(self): enabled = self.packageList.isSelected() self.actionButton.setEnabled(enabled) self.basket.setActionEnabled(enabled) def switchState(self, state, action=True): self.searchLine.clear() self.lastState = self.state.state self.state.setState(state) self._selectedGroups = [] self.setActionButton() if action: self.state.stateAction() self.initialize() def emitStatusBarInfo(self, packages, packagesSize, extraPackages, extraPackagesSize): self.emit(SIGNAL("selectionStatusChanged(QString)"), self.state.statusText(packages, packagesSize, extraPackages, extraPackagesSize)) def setSelectAll(self, packages=None): if packages: self.packageList.reverseSelection(packages) def setReverseAll(self, packages=None): if packages: self.packageList.selectAll(packages) def toggleSelectAll(self, toggled): self._last_packages = self.packageList.model().getFilteredPackages() if toggled: if self.groupList.currentGroup() not in self._selectedGroups: self._selectedGroups.append(self.groupList.currentGroup()) self.setReverseAll(self._last_packages) else: if self.groupList.currentGroup() in self._selectedGroups: self._selectedGroups.remove(self.groupList.currentGroup()) self.setSelectAll(self._last_packages) # A hacky solution to repaint the list to take care of selection changes # FIXME Later self.packageList.setFocus() self.statusChanged() def showBasket(self): waitCursor() self.statusUpdater.wait() self.basket.show() restoreCursor()