class View (QFrame): def __init__ (self, name, graph_view, scene, parent=None): QFrame.__init__(self, parent) self.graph_view = graph_view self.graph_view.setView0 (self) self.scene = scene self.setFrameStyle (QFrame.Sunken | QFrame.StyledPanel) self.font = QFont() self.font.setPointSize(10) self.graphicsView = CustomGraphicsView () self.graphicsView.setRenderHint (QPainter.Antialiasing, True) self.graphicsView.setDragMode (QGraphicsView.RubberBandDrag) self.graphicsView.setViewportUpdateMode (QGraphicsView.SmartViewportUpdate) #self.graphicsView.setMouseTracking(True) # toolbox definition + group page definition sizePolicy = QSizePolicy (QSizePolicy.Fixed, QSizePolicy.Expanding) self.setObjectName ('Form') self.resize (900, 1000) self._toolBox = QToolBox (self) self._toolBox.setGeometry (QRect (0, 0, 131, 301)) self._toolBox.setFont (self.font) self._toolBox.setObjectName ('_toolBox') self._toolBox.setCursor (Qt.PointingHandCursor) self.groupCluster = QWidget () self.groupCluster.setGeometry (QRect(0, 0, 91, 241)) self.groupCluster.setObjectName ('groupCluster') self.groupLineEdit = QLineEdit (self.groupCluster) self.groupLineEdit.setGeometry (QRect (2, 20, 60, 16)) self.groupLineEdit.setObjectName ('groupLineEdit') self.label = QLabel (self.groupCluster) self.label.setGeometry (QRect (4, 6, 62, 16)) self.label.setFont (self.font) self.label.setObjectName ('label') self.label_2 = QLabel (self.groupCluster) self.label_2.setGeometry (QRect (4, 40, 62, 16)) self.label_2.setFont (self.font) self.label_2.setObjectName ('label_2') self.groupLineEdit_2 = QLineEdit (self.groupCluster) self.groupLineEdit_2.setGeometry (QRect(2, 54, 60, 16)) self.groupLineEdit_2.setObjectName ('groupLineEdit_2') self.pushButton = QPushButton (self.groupCluster) self.pushButton.setGeometry (QRect (2, 90, 60, 16)) self.pushButton.setFont (self.font) self.pushButton.setObjectName ('pushButton') self._toolBox.addItem (self.groupCluster, '') self._toolBox.setItemText (self._toolBox.indexOf (self.groupCluster), QApplication.translate ("Form", "Group", None, QApplication.UnicodeUTF8)) self.setWindowTitle (QApplication.translate ("Form", "Form", None, QApplication.UnicodeUTF8)) self.label.setText (QApplication.translate ("Form", "name group", None, QApplication.UnicodeUTF8)) self.label_2.setText (QApplication.translate ("Form", "group id", None, QApplication.UnicodeUTF8)) self.pushButton.setText (QApplication.translate ("Form", "add cluster", None, QApplication.UnicodeUTF8)) self._toolBox.setSizePolicy (sizePolicy) self._toolBox.setEnabled (False) # adding the first cluster to the toolbox - a cluster is always present! self._cluster_page_list = [] self.connect (self.pushButton, SIGNAL ("clicked()"), self.addCluster) # connect the 'add-cluster' button to the method that taps into the model for cluster addition. self.connect (self.graph_view.getComm(), SIGNAL ("addCluster_MSignal(int)"), self.addClusterPage) self.connect (self.graph_view.getComm(), SIGNAL ("deleteCluster_MSignal(int)"), self.removeClusterPage) self.connect (self.graph_view.getComm(), SIGNAL ("updateClusterName_MSignal(int, QString)"), self.updateClusterViewName) self.addCluster () # add the first cluster. At least one cluster needs to be always present. self.disableAllClusterPagesDeleteButton() # since there's only one cluster page, the delete button is disabled. #size = self.style ().pixelMetric (QStyle.PM_ToolBarIconSize) iconSize = QSize (16, 16) #QSize (size, size) zoomInIcon = QToolButton () zoomInIcon.setCursor (Qt.PointingHandCursor) zoomInIcon.setAutoRepeat (True) zoomInIcon.setAutoRepeatInterval (33) zoomInIcon.setAutoRepeatDelay (0) zoomInIcon.setIconSize (iconSize) zoomOutIcon = QToolButton () zoomOutIcon.setCursor (Qt.PointingHandCursor) zoomOutIcon.setAutoRepeat (True) zoomOutIcon.setAutoRepeatInterval (33) zoomOutIcon.setAutoRepeatDelay (0) zoomOutIcon.setIconSize (iconSize) self.zoomSlider = QSlider () self.zoomSlider.setCursor (Qt.PointingHandCursor) self.zoomSlider.setMinimum (200) self.zoomSlider.setMaximum (280) self.zoomSlider.setValue (240) self.zoomSlider.setTickPosition (QSlider.TicksRight) # Zoom slider layout zoomSliderLayout = QVBoxLayout () zoomSliderLayout.addWidget (zoomInIcon) zoomSliderLayout.addWidget (self.zoomSlider) zoomSliderLayout.addWidget (zoomOutIcon) self.printOutBtn = QPushButton() self.printOutBtn.setText ("print") self.printOutBtn.setFont (self.font) self.printOutBtn.setEnabled (False) self.newJADESceneBtn = QPushButton() self.newJADESceneBtn.setText ("new") self.newJADESceneBtn.setFont (self.font) self.newJADESceneBtn.setEnabled (False) self.loadNodesDescrpBtn = QPushButton() self.loadNodesDescrpBtn.setText ("load Nodes Description") self.loadNodesDescrpBtn.setFont (self.font) self.loadNodesDescrpBtn.setEnabled (True) self.graphLoadBtn = QPushButton() self.graphLoadBtn.setText ("load") self.graphLoadBtn.setFont (self.font) self.graphLoadBtn.setEnabled (False) self.graphSaveBtn = QPushButton() self.graphSaveBtn.setText ("save") self.graphSaveBtn.setFont (self.font) self.graphSaveBtn.setEnabled (False) self.resetButton = QToolButton () self.resetButton.setText ("r") self.resetButton.setFont (self.font) self.resetButton.setEnabled (False) self.message_bar = QLineEdit () self.message_bar.setGeometry (QRect (0, 0, 190, 12)) self.message_bar.setObjectName ('message_bar') self.message_bar.setText ('Node description file, please.') self.message_bar.setFont (self.font) self.message_bar.setEnabled (True) self.message_bar.setReadOnly (True) self.spacer = QSpacerItem (30, 20, QSizePolicy.Fixed, QSizePolicy.Fixed ); # Label layout labelLayout = QHBoxLayout () self.label = QLabel (name) self.label.setFont (self.font) labelLayout.addWidget (self.loadNodesDescrpBtn) labelLayout.addWidget (self.newJADESceneBtn) labelLayout.addWidget (self.graphLoadBtn) labelLayout.addWidget (self.graphSaveBtn) labelLayout.addWidget (self.printOutBtn) labelLayout.addItem (self.spacer) labelLayout.addWidget (self.message_bar) #labelLayout.addWidget (self.label) labelLayout.addStretch () # top layout topLayout = QGridLayout () topLayout.setHorizontalSpacing (0) topLayout.setVerticalSpacing (0) topLayout.addLayout (labelLayout, 0, 1) topLayout.addWidget (self._toolBox, 1, 0) topLayout.addWidget (self.resetButton, 0, 2) topLayout.addWidget (self.graphicsView, 1, 1) topLayout.addLayout (zoomSliderLayout, 1, 2) self.setLayout (topLayout) self.connect (self.resetButton, SIGNAL ("clicked()"), self.resetView) self.connect (self.zoomSlider, SIGNAL ("valueChanged(int)"), self.setupMatrix) self.connect (self.graphicsView.verticalScrollBar (), SIGNAL ("valueChanged(int)"), self.setResetButtonEnabled) self.connect (self.graphicsView.horizontalScrollBar (), SIGNAL ("valueChanged(int)"), self.setResetButtonEnabled) self.connect (zoomInIcon, SIGNAL ("clicked()"), self.zoomIn) self.connect (zoomOutIcon, SIGNAL ("clicked()"), self.zoomOut) self.setupMatrix () self.printer = QPrinter (QPrinter.HighResolution) self.prev_selection_list = [] self.isClusterRemovalOverridden = False def setMessageBarText (self, text): self.message_bar.setText (text) def enableControls (self): self.printOutBtn.setEnabled (True) self.newJADESceneBtn.setEnabled (True) self.graphLoadBtn.setEnabled (True) self.graphSaveBtn.setEnabled (True) self._toolBox.setEnabled (True) def disableControls (self): self.printOutBtn.setEnabled (False) self.newJADESceneBtn.setEnabled (False) self.graphLoadBtn.setEnabled (False) self.graphSaveBtn.setEnabled (False) self._toolBox.setEnabled (False) def setGraphicsViewCSSBackground (self): self.graphicsView.setStyleSheet('background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(125, 125, 135, 255), stop:1 rgba(215, 215, 215, 255));\ncolor: rgb(255, 255, 255);') def selectionChanged (self): current_selection_list = self.scene.selectedItems () list_of_unselected_items = [item for item in self.prev_selection_list if item not in current_selection_list] # un-mark items in list_of_unselected_items for item in list_of_unselected_items: if self.graph_view.isTag (item) == True: item.switchToUnSelectedStateColour () # mark items in current_selection_list for item in current_selection_list: if self.graph_view.isTag (item) == True: item.switchToSelectedStateColour () self.prev_selection_list = current_selection_list # - - - cluster-specific methods - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def addCluster (self): self.graph_view.delegateClusterAddition () def addClusterPage (self, new_cluster_id): self.enableAllClusterPagesDeleteButton () # enable all the cluster page's delete buttons (as I can be bothered to go look for the one that got previously disabled) tmp_w = QWidget () tmp_l = QLabel (tmp_w) tmp_e = QLineEdit (tmp_w) tmp_b = QPushButton (tmp_w) self._cluster_page_list.append ([new_cluster_id, tmp_w, tmp_l, tmp_e, tmp_b]) tmp_w.setGeometry (QRect (0, 0, 131, 241)) tmp_w.setObjectName ('Cluster_' + str (new_cluster_id)) tmp_l.setGeometry (QRect (4, 6, 62, 16)) tmp_l.setFont (self.font) tmp_l.setObjectName ('label_' + str (new_cluster_id)) tmp_e.setGeometry (QRect (2, 20, 60, 16)) tmp_e.setObjectName ('groupLineEdit_' + str (new_cluster_id)) tmp_b.setGeometry (QRect (2, 50, 60, 16)) tmp_b.setFont (self.font) tmp_b.setObjectName ('pushButton_' + str (new_cluster_id)) self._toolBox.addItem (tmp_w, 'cluster_page_'+str(new_cluster_id)) self._toolBox.setItemText (self._toolBox.indexOf (tmp_w), QApplication.translate ('Form', 'C_'+str(new_cluster_id), None, QApplication.UnicodeUTF8)) tmp_l.setText (QApplication.translate ("Form", "name cluster", None, QApplication.UnicodeUTF8)) tmp_b.setText (QApplication.translate ("Form", "delete", None, QApplication.UnicodeUTF8)) self._toolBox.setCurrentIndex (new_cluster_id) QMetaObject.connectSlotsByName (self) # hook up the delete button (use a closure) receiver = lambda : self.removeCluster (new_cluster_id) self.connect (tmp_b, SIGNAL ("clicked()"), receiver) # connect the 'add cluster' button to the method generating new cluster pages. receiver2 = lambda value : self.updateClusterModelName (new_cluster_id, value) self.connect (tmp_e, SIGNAL ("textChanged(QString)"), receiver2) def removeAllClusters (self): copy_list = list (self._cluster_page_list) self.isClusterRemovalOverridden = True for item in copy_list: self.removeCluster (item[0]) self.graph_view.initGraphViewLists () self.graph_view.initComm () self.graph_view.initModel () self._cluster_page_list = [] self.addCluster () # add the first cluster. At least one cluster needs to be always present. self.isClusterRemovalOverridden = False # remove override def removeCluster (self, cluster_id): self.graph_view.delegateClusterRemoval (cluster_id) def removeClusterPage (self, cluster_id): threshold = 1 if self.isClusterRemovalOverridden==False else 0 qq = len(self._cluster_page_list) if qq > threshold: for i in range (qq-1, -1, -1): if int(self._cluster_page_list[i][0]) == cluster_id: self._toolBox.removeItem (self._toolBox.indexOf(self._cluster_page_list[i][1])) del self._cluster_page_list[i] break if len(self._cluster_page_list) == 1: self.disableAllClusterPagesDeleteButton () def disableAllClusterPagesDeleteButton (self): if len(self._cluster_page_list) > 0: for item in self._cluster_page_list: item[4].setEnabled (False) def enableAllClusterPagesDeleteButton (self): if len(self._cluster_page_list) > 0: for item in self._cluster_page_list: item[4].setEnabled (True) def updateClusterModelName (self, cluster_id, text): self.graph_view.delegateUpdateClusterName (cluster_id, text) def updateClusterViewName (self, cluster_id, text): if len(self._cluster_page_list) > 0: for item in self._cluster_page_list: if int(item[0]) == cluster_id: item[3].setText (str(text)) def updateCurrentClusterNodeList (self, node): # fetch the current cluster's id. curr_widget = self._toolBox.currentWidget() for item in self._cluster_page_list: if item[1] == curr_widget: # delegate cluster node list update. self.graph_view.delegateClusterNodeListUpdate (item[0], node) break def getCurrentClusterIndex (self): return self._toolBox.currentIndex () # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def getGraphicsView (self): return self.graphicsView def resetView (self): self.zoomSlider.setValue (250) self.setupMatrix () self.graphicsView.ensureVisible (QRectF (0, 0, 0, 0)) self.resetButton.setEnabled (False) def setResetButtonEnabled (self): self.resetButton.setEnabled (True) def setupMatrix (self): scale = pow (2.0, (self.zoomSlider.value () - 250) / 50.0) matrix = QMatrix () matrix.scale (scale, scale) self.graphicsView.setMatrix (matrix) self.setResetButtonEnabled () def printOutGraph (self): qqq = QPainter (self.printer) self.graphicsView.render(qqq) def importNodesDescription (self): aa = QFileDialog (self).getOpenFileName() if aa != QString (u''): # it can be equal to QString(u'') when the user presses the Escape key, so in that circumstance, nothing is returned. self.graph_view.setNodesDescription (open(aa).read()) def resetScene (self): self.removeAllClusters () self.resetView () def exportGraph (self): aa = QFileDialog (self).getSaveFileName () if aa != QString (u''): # it can be equal to QString(u'') when the user presses the Escape key, so in that circumstance, nothing is returned. file0 = open (aa, 'w') file0.write (self.graph_view.delegateExport ()) file0.close () print '\n*** file exported.\n' def importGraph (self): aa = QFileDialog (self).getOpenFileName () if aa != QString (u''): # it can be equal to QString(u'') when the user presses the Escape key, so in that circumstance, nothing is returned. file0 = open (aa, 'r') XML_content = file0.read() file0.close () self.graph_view.delegateImport (XML_content) print '\n*** file imported.\n' # zoom slider def zoomIn (self) : self.zoomSlider.setValue (self.zoomSlider.value() + 1) def zoomOut (self) : self.zoomSlider.setValue (self.zoomSlider.value() - 1) def getZoomSlider (self): return self.zoomSlider def setToolboxCSSColorScheme (self, css): self._toolBox.setStyleSheet (css) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def wireViewItemsUp (self): self.connect (self.newJADESceneBtn, SIGNAL ("clicked()"), self.resetScene) self.connect (self.loadNodesDescrpBtn, SIGNAL ("clicked()"), self.importNodesDescription) self.connect (self.graphSaveBtn, SIGNAL ("clicked()"), self.exportGraph) self.connect (self.graphLoadBtn, SIGNAL ("clicked()"), self.importGraph) self.connect (self.printOutBtn, SIGNAL ("clicked()"), self.printOutGraph)
class MyMainWindow(QMainWindow): ' Main Window ' def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self.statusBar().showMessage(__doc__) self.setWindowTitle(__doc__) self.setMinimumSize(250, 280) self.setMaximumSize(300, 300) self.resize(250, 290) self.setWindowIcon(QIcon.fromTheme("face-monkey")) self.setStyleSheet('''QWidget { color: rgba( 0, 255, 255, 255 ); background-color: #323232; font-family: 'Ubuntu Light'; font-size: 14px; } QToolTip { border: 1px solid black; background-color: #ffa02f; background-image: None; padding: 1px; border-radius: 3px; opacity: 100; } QWidget:item:hover { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619 ); color: #000000; } QWidget:item:selected { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QWidget:disabled { color: #404040; background-color: #323232; } QWidget:focus { background-image: None; border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QPushButton { background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646 ); border-width: 1px; border-color: #1e1e1e; border-style: solid; border-radius: 6; padding: 3px; font-size: 12px; padding-left: 5px; padding-right: 5px; background-image: None; } QPushButton:pressed { background-image: None; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525 ); } QComboBox { background-image: None; selection-background-color: #ffaa00; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646 ); border-style: solid; border: 1px solid #1e1e1e; border-radius: 5; } QComboBox:hover, QPushButton:hover { background-image: url(.bg.png); border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QComboBox:on { padding-top: 3px; padding-left: 4px; background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525 ); selection-background-color: #ffaa00; background-image: None; } QComboBox QAbstractItemView { background-image: None; border: 2px solid darkgray; selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a ); } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 15px; border-left-width: 0px; border-left-color: darkgray; border-left-style: solid; border-top-right-radius: 3px; border-bottom-right-radius: 3px; background-image: None; } QComboBox::down-arrow { background-image: None; } QSlider { border-width: 2px; border-color: #1e1e1e; border-style: solid; padding: 3px; font-size: 8px; padding-left: 5px; padding-right: 5px; width: 25px; border-radius: 5px; } QSlider::sub-page:vertical { background: red; border: none; width: 25px; } QSlider::add-page:vertical { background: green; border: none; width: 25px; } QSlider::handle:vertical { background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1, y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(150, 255, 255, 255) ); width: 10px; height: 25px; border: 1px solid grey; text-align: center; border-top-left-radius: 2px; border-bottom-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius 2px; margin-left: 2px; margin-right: 2px; } QSlider::handle:vertical:hover { border: 2px solid #ffaa00; margin-left: 2px; margin-right: 2px; } QSlider::sub-page:vertical:disabled { background: #bbb; border-color: #999; } QSlider::add-page:vertical:disabled { background: #eee; border-color: #999; } QSlider::handle:vertical:disabled { background: #eee; border: 1px solid #aaa; border-radius: 4px; } ''') self.label1 = QLabel(self) self.label1.setText('Use Debug') self.label1.setGeometry(QtCore.QRect(25, 25, 125, 25)) self.slider1 = QSlider(self) self.slider1.setGeometry(QtCore.QRect(150, 25, 25, 25)) self.slider1.setTickInterval(1) self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider1.TickPosition(QSlider.TicksBothSides) self.slider1.setRange(0, 1) self.slider1.setValue(1) self.sli1lbl = QLabel(str(self.slider1.value()), self.slider1) self.sli1lbl.move(9, 5) self.sli1lbl.setAutoFillBackground(False) self.slider1.valueChanged.connect( lambda: self.sli1lbl.setText(str(self.slider1.value()))) self.slider1.sliderPressed.connect( lambda: self.slider1.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider1.sliderReleased.connect( lambda: self.slider1.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label2 = QLabel(self) self.label2.setText('Make Executable') self.label2.setGeometry(QtCore.QRect(25, 75, 125, 25)) self.slider2 = QSlider(self) self.slider2.setGeometry(QtCore.QRect(150, 75, 25, 25)) self.slider2.setTickInterval(1) self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider2.TickPosition(QSlider.TicksBothSides) self.slider2.setRange(0, 1) self.slider2.setValue(1) self.sli2lbl = QLabel(str(self.slider2.value()), self.slider2) self.sli2lbl.move(9, 5) self.sli2lbl.setAutoFillBackground(False) self.slider2.valueChanged.connect( lambda: self.sli2lbl.setText(str(self.slider2.value()))) self.slider2.sliderPressed.connect( lambda: self.slider2.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider2.sliderReleased.connect( lambda: self.slider2.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label3 = QLabel(self) self.label3.setText('Relative Imports') self.label3.setGeometry(QtCore.QRect(25, 125, 125, 25)) self.slider3 = QSlider(self) self.slider3.setGeometry(QtCore.QRect(150, 125, 25, 25)) self.slider3.setTickInterval(1) self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor)) self.slider3.TickPosition(QSlider.TicksBothSides) self.slider3.setRange(0, 1) self.slider3.setValue(0) self.sli3lbl = QLabel(str(self.slider3.value()), self.slider3) self.sli3lbl.move(9, 5) self.sli3lbl.setAutoFillBackground(False) self.slider3.valueChanged.connect( lambda: self.sli3lbl.setText(str(self.slider3.value()))) self.slider3.sliderPressed.connect( lambda: self.slider3.setCursor(QCursor(QtCore.Qt.ClosedHandCursor))) self.slider3.sliderReleased.connect( lambda: self.slider3.setCursor(QCursor(QtCore.Qt.OpenHandCursor))) self.label4 = QLabel(self) self.label4.setText('Indent Spaces') self.label4.setGeometry(QtCore.QRect(25, 175, 125, 25)) self.combo1 = QComboBox(self) self.combo1.setCursor(QCursor(QtCore.Qt.PointingHandCursor)) self.combo1.addItems(['4', '0', '2', '6', '8']) self.combo1.setGeometry(QtCore.QRect(150, 175, 50, 25)) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setGeometry(QtCore.QRect(25, 225, 200, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Close | QDialogButtonBox.Help) self.buttonBox.setCenterButtons(False) self.buttonBox.helpRequested.connect(lambda: QMessageBox.about( self, __doc__, str(__doc__ + ', ' + ',\nversion ' + __version__ + '(' + __license__ + '),\nby ' + __author__ + ', ' + __email__))) self.buttonBox.accepted.connect(self.run) self.buttonBox.rejected.connect(self.close) palette = self.palette() palette.setBrush(QPalette.Base, Qt.transparent) self.setPalette(palette) self.setAttribute(Qt.WA_OpaquePaintEvent, False) def run(self): 'Run the actual conversion.' # Ask the User for the source .ui file as input filein = str(QFileDialog.getOpenFileName( self, __doc__, path.expanduser("~"), 'UI(*.ui)')).strip() # Parse Value of Slider1 as the Debug flag parameter if self.slider1.value() == 0: arg1 = '' else: arg1 = '--debug ' # Parse Value of Slider2 as the Execute flag parameter if self.slider2.value() == 0: arg2 = '' else: arg2 = '--execute ' # Parse Value of Slider3 as the relative imports flag parameter if self.slider3.value() == 0: arg3 = '' else: arg3 = '--from-imports ' # debug #print(arg1, arg2, arg3, str(self.combo1.currentText())) # run the subprocesses subprocess.Popen( 'nice --adjustment=19 pyuic4 ' + arg1 + arg2 + arg3 + '--indent=' + str(self.combo1.currentText()) + ' --output=' + str(filein).lower().replace('.ui', '.py') + ' ' + filein + ' && chmod -v +x ' + str(filein).lower().replace('.ui', '.py'), shell=True) def paintEvent(self, event): ' Paint semi-transparent background ' painter = QPainter(self) painter.fillRect(event.rect(), Qt.transparent) painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0)) painter.setOpacity(0.75) painter.drawRoundedRect(self.rect(), 75, 50) painter.end()
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)