class UptimeDisplayApplet(plasmascript.Applet): def __init__(self,parent,args=None): plasmascript.Applet.__init__(self,parent) def init(self): self.setHasConfigurationInterface(True) self.setAspectRatioMode(Plasma.Square) self.uptime = '' self.update_timer = QTimer() self.update_timer.start(60000) #60s QObject.connect(self.update_timer, SIGNAL("timeout()"), self.constantUpdate) self.readUptime() def sizeHint(self): return QSize(400, 400) def readUptime(self): with open('/proc/uptime', 'r') as f: uptime_seconds = float(f.readline().split()[0]) uptime_hours = int(uptime_seconds / 3600) uptime_minutes = int((uptime_seconds - (uptime_hours * 3600)) / 60) self.uptime = "%dh\n%dm" % (uptime_hours, uptime_minutes) def constantUpdate(self): self.readUptime() self.update() def paintInterface(self, painter, option, rect): painter.save() painter.setPen(Qt.black) painter.setFont(QFont('Decorative', 8)) painter.drawText(rect, Qt.AlignVCenter | Qt.AlignHCenter, str(self.uptime)) painter.restore()
def __init__( self, parent = None ): """ Constructor """ super( FrmDevolucion, self ).__init__( parent ) self.editmodel = None self.status = True # las acciones deberian de estar ocultas # El modelo principal self.navmodel = RONavigationModel( self ) # El modelo que filtra a self.navmodel self.navproxymodel = QSortFilterProxyModel( self ) self.navproxymodel.setSourceModel( self.navmodel ) # Este es el modelo con los datos de la tabla para navegar self.detailsmodel = QSqlQueryModel( self ) # Este es el filtro del modelo anterior self.detailsproxymodel = QSortFilterProxyModel( self ) self.detailsproxymodel.setSourceModel( self.detailsmodel ) # Cargar los modelos en un hilo aparte QTimer.singleShot( 0, self.loadModels )
def _loadFinished(self, ok): self.log("_loadFinished %s" % id(self.splash_request)) if self.deferred.called: # sometimes this callback is called multiple times self.log("_loadFinished called multiple times") return page_ok = ok and self.web_page.errorInfo is None maybe_redirect = not ok and self.web_page.errorInfo is None error_loading = ok and self.web_page.errorInfo is not None if maybe_redirect: self.log("Redirect or other non-fatal error detected %s" % id(self.splash_request)) # XXX: It assumes loadFinished will be called again because # redirect happens. If redirect is detected improperly, # loadFinished won't be called again, and Splash will return # the result only after a timeout. # # FIXME: This can happen if server returned incorrect # Content-Type header; there is no an additional loadFinished # signal in this case. return if page_ok: time_ms = int(self.wait_time * 1000) QTimer.singleShot(time_ms, self._loadFinishedOK) elif error_loading: self.log("loadFinished %s: %s" % (id(self.splash_request), str(self.web_page.errorInfo))) # , min_level=1) # XXX: maybe return a meaningful error page instead of generic # error message? self.deferred.errback(RenderError()) else: self.log("loadFinished %s: unknown error" % id(self.splash_request)) # , min_level=1) self.deferred.errback(RenderError())
def refresh(self): """Updates view(s).""" index = self.stackedWidget.currentIndex() if index == 1: self.populatedTable = False self.selectedWidget.clear() self.getAllSelected() elif index == 0: self.populatedTree = False self.treeWidget.clear() self.treeWidget.setDisabled(True) bnField = "ItemTracker ID" self.selectedIds = {} self.errorIds = {} selection = DB.Db.Selection self.selectedIds, self.errorIds = bn.getItemIds(bnField, selection) if len(self.selectedIds): self.strainInfo = {} self.itemIds = {} self.getBnFields() # self.populateTree() QTimer.singleShot(0, self.populateTree) elif index == 2: self.populatedCherry = False QTimer.singleShot(0, self.cherryPicking) self.updateUi()
def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self._config = {} SubscriberApplication.instance().subscribed.connect(self.statusBar().clearMessage) SubscriberApplication.instance().subscriptionError.connect(self._subscriptionError) QTimer.singleShot(0, self._chooseTeam)
class MyWindowClass(QtGui.QMainWindow, form_class): connected = bool(False) windfreak = None time = 0 def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.setupUi(self) self.ButtonUpdate_freq.clicked.connect(self.ButtonUpdate_freq_clicked)# Bind the event handlers self.ButtonUpdate_power.clicked.connect(self.ButtonUpdate_power_clicked) self.ButtonUpdate_channel.clicked.connect(self.ButtonUpdate_channel_clicked) self.ButtonConnect.clicked.connect(self.ButtonConnect_clicked) self.comboSerialBox.addItems(serial_ports()) #Gets a list of avaliable serial ports to connect to and adds to combo box def ButtonConnect_clicked(self,connection): if not self.connected: self.windfreak = wc.windfreakusb2(str(self.comboSerialBox.currentText())) self.timer = QTimer() self.connected = True self.timer.timeout.connect(self.update) self.timer.start(1000) self.control_label.setText('connected to ' + str(self.comboSerialBox.currentText())) self.freq = float(self.windfreak.get_freq())/1000 self.power = self.windfreak.get_power() self.label_freq.setText(str(self.freq)+"MHz") self.label_power.setText(str(self.power)) self.windfreak.set_clock(str(1)) #sets internal clock so that is locks self.windfreak.set_freq(str(self.freq)) def ButtonUpdate_freq_clicked(self,value): self.windfreak.set_freq(self.freq_box.text()) self.freq = float(self.windfreak.get_freq())/1000 self.label_freq.setText(str(self.freq)+"MHz") print 'freq updated' def ButtonUpdate_power_clicked(self,value): self.windfreak.set_power(self.power_box.text()) self.power = self.windfreak.get_power() self.label_power.setText(self.power) print 'power updated' def ButtonUpdate_channel_clicked(self,value): url = "http://charsiew.qoptics.quantum.nus.edu.sg:8080" try: urllib2.urlopen(url+"/switch_"+str(self.channel_box.text())) except: pass print 'channel updated' def update(self): url = "http://charsiew.qoptics.quantum.nus.edu.sg:8080" self.data = json.load(urllib2.urlopen(url+"/data")) self.label_wavelength.setText(self.data['wavelength']) self.label_optical_freq.setText(self.data['freq']) self.label_channel.setText(self.data['channel'])
def show(self, webPages): settings = Settings() server = xmlrpclib.Server(settings.serverAddress) self.setWindowTitle('updates') layout = self.layout() if layout == None: layout = QVBoxLayout() label = QLabel('Some Web Pages have changed:') layout.addWidget(label) for webPage in webPages: label = QLabel('<a href=' + webPage + '>' + self._truncate(webPage) + '</a>' ) label.setOpenExternalLinks(True) layout.addWidget(label) #buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) moreButton = QPushButton('More...') moreButton.setMaximumWidth(60) self.connect(moreButton, SIGNAL('clicked()'), self.showDiffWindow) layout.addWidget(moreButton) self.setLayout(layout) if debug.verbose: print('DEBUG: Showing notification dialog') QDialog.show(self) QTimer.singleShot(0, self.fixPosition) QTimer.singleShot(self._timeout, self.hide)
def __init__(self, argv): QMainWindow.__init__(self) #Normalize the data if true self._normalize_data=True if 'notnormalize' in sys.argv: print sys.argv self._normalize_data=False sys.argv.remove('notnormalize') self.opPredict = None self.opTrain = None self.opThreshold = None self._colorTable16 = self._createDefault16ColorColorTable() #self.g = Graph(7, 2048*1024**2*5) self.g = Graph() self.fixableOperators = [] self.featureDlg=None #The old ilastik provided the following scale names: #['Tiny', 'Small', 'Medium', 'Large', 'Huge', 'Megahuge', 'Gigahuge'] #The corresponding scales are: self.featScalesList=[0.3, 0.7, 1, 1.6, 3.5, 5.0, 10.0] self.initUic() #if the filename was specified on command line, load it if len(sys.argv) >= 2: def loadFile(): self._openFile(sys.argv[1:]) QTimer.singleShot(0, loadFile)
def __init__( self, tiposdoc, parent = None, edit = True ): ''' Constructor ''' super( FrmKardex, self ).__init__( parent ) self.tiposdoc = ",".join( [str( item ) for item in tiposdoc] ) self.edit = edit self.navigationmodel = QSqlQueryModel() self.detailsModel = QSqlQueryModel() self.navproxymodel = QSortFilterProxyModel() self.navproxymodel.setSourceModel( self.navigationmodel ) self.detailsproxymodel = QSortFilterProxyModel() self.detailsproxymodel.setSourceModel( self.detailsModel ) self.tabledetails.setModel( self.detailsproxymodel ) self.tablenavigation.setModel( self.navproxymodel ) self.editmodel = None QTimer.singleShot( 0, self.loadModels )
def __init__(self, thread, parent): QDialog.__init__(self, parent) self.ui = Ui_PlotPreview() self.ui.setupUi(self) self.parent = parent icon = QIcon() icon.addPixmap(QPixmap(":/icons/reload.png"), QIcon.Normal, QIcon.Off) self.update_btn = QPushButton(icon, "Update") self.ui.buttonBox.addButton(self.update_btn, QDialogButtonBox.ApplyRole) self.update_btn.clicked.connect(self.render_image) self._pix = None self._image_list = None self._thread = thread self.scene = QGraphicsScene() self.scene.setSceneRect(0,0,1,1) self.ui.imageView.setScene(self.scene) self.pix_item = None self.ui.imageView.setEnabled(False) self.ui.imageView.setInteractive(False) self.ui.imageView.setDragMode(QGraphicsView.ScrollHandDrag) self.pic_w = None self.pic_c = None self.show_pic_w = None self.show_pic_c = None timer = QTimer(self) timer.setSingleShot(True) timer.setInterval(500) self.timer = timer timer.timeout.connect(self.render_image) if parameters.instance.use_OpenGL: self.ui.imageView.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers)))
def refreshActionIfNeeded(self, checked=False): if backend.STATUS.devStatusChanged() or backend.STATUS.mountStatusChanged(): # wait a moment after change detected # (let the system create device files, etc..) # sometimes, an exception occurs here (for 500ms delay): # "Could not find IO device path" BlockDevice.__init__() QTimer.singleShot(int(2 * self._checkInterval), self.refreshAction)
def wait(self, time_ms, callback, onredirect=None, onerror=None): """ Wait for time_ms, then run callback. If onredirect is True then the timer is cancelled if redirect happens. If onredirect is callable then in case of redirect the timer is cancelled and this callable is called. If onerror is True then the timer is cancelled if a render error happens. If onerror is callable then in case of a render error the timer is cancelled and this callable is called. """ timer = QTimer() timer.setSingleShot(True) timer_callback = functools.partial(self._on_wait_timeout, timer=timer, callback=callback, ) timer.timeout.connect(timer_callback) self.logger.log("waiting %sms; timer %s" % (time_ms, id(timer)), min_level=2) timer.start(time_ms) self._active_timers.add(timer) if onredirect: self._timers_to_cancel_on_redirect[timer] = onredirect if onerror: self._timers_to_cancel_on_error[timer] = onerror
def __init__(self): # init the widget #QWidget.__init__(self, parent) # set up the scene self.scene=QGraphicsScene() self.scene.setSceneRect(0,0,800,600) # add a view of that scene self.view = QGraphicsView() self.view.setScene(self.scene) self.view.setRenderHint(QPainter.Antialiasing) self.view.setFixedSize(800,600) self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # set the screen sync to vertical retrace val = "1" # Set for nVidia linux os.environ["__GL_SYNC_TO_VBLANK"] = val # Set for recent linux Mesa DRI Radeon os.environ["LIBGL_SYNC_REFRESH"] = val qglf = QGLFormat() qglf.setSampleBuffers(True) self.glw = QGLWidget(qglf) self.glw.setAutoBufferSwap(False) self.view.setViewport(self.glw) #self.view.showFullScreen() self.view.show() self.last_finish = 0 QTimer.singleShot(0,self.glw.swapBuffers)
def run_method(self): def renderer_func(): renderer = WebkitRenderer() renderer.width = 0 renderer.height = 0 renderer.timeout = 10 renderer.wait = 1 renderer.format = "png" renderer.grabWholeWindow = False for url in self.listOfUrls: url = url[0] fileName = url.split('://') if len(fileName) >1: fileName = fileName[1].split('www.') else: fileName = fileName[0].split('www.') if len(fileName) >1: fileName = fileName[1].split('.') else: fileName = fileName[0].split('.') fileName = fileName[0] outfile = open("%s.png" % fileName, "w") renderer.render_to_file(url, outfile) outfile.close() app = init_qtgui() QTimer.singleShot(0, renderer_func) app.exec_() sys.exit(1)
def configurarPanelGrabacion(self): self.panelGrabacionWidget = QtGui.QWidget() self.panelGrabacion = Ui_panelAhora() self.panelGrabacion.setupUi(self.panelGrabacionWidget) self.UiVentanaPrincipal.horizontalLayout.addWidget(self.panelGrabacionWidget) # Configuro los botones QtCore.QObject.connect( self.panelGrabacion.principioBoton, QtCore.SIGNAL("pressed()"), self.mostrarPanelBienvenido ) # Para mostrar la presentacion con info del dispenser y para la barra de progreso que se va actualizando uso un QTimer # inicializo el timer y conecto su timeout con un metodo self.timerPresentacion = QTimer() QtCore.QObject.connect(self.timerPresentacion, QtCore.SIGNAL("timeout()"), self.actualizarPresentacion) # almaceno todas las imagenes de la presentacion en una lista de QPixmax self.presentacion, # y una variable para la imagen actual de la presentacion self.presentacionImagenActual presentacionArchivos = os.listdir(os.getcwd() + "/images-and-icons/") self.presentacion = [] for presentacionArchActual in presentacionArchivos: self.presentacion.append(QPixmap(os.getcwd() + "/images-and-icons/" + presentacionArchActual)) self.presentacionImagenActual = 0 self.timerBarraDeProgreso = QTimer() QtCore.QObject.connect(self.timerBarraDeProgreso, QtCore.SIGNAL("timeout()"), self.actualizarBarraDeProgreso) # ESTO NO TIENE QUE IR, ES SOLO PARA MOSTRAR QUE LA BARRA FUNCIONA self.textoBarra = ["grabando.", "grabando..", "grabando..."] self.textoBarraActual = 0
def on_chatView_loadFinished(self, ok=True): self._bodyElement = self.chatView.page().mainFrame().documentElement().findFirst('body') # check that the body element is really loaded, otherwise try again later if self._bodyElement.isNull(): QTimer.singleShot(100, self.on_chatView_loadFinished) return self._showHistoryMessages()
class VUMeter(QObject): KITCHEN_SINK = 'alsa_output.pci-0000_00_1b.0.analog-stereo' def __init__(self, parent, sink_name=None): super(VUMeter, self).__init__(parent) if sink_name == None: self.sink_name = self.KITCHEN_SINK else: self.sink_name = sink_name self.meter_rate = 344 self.display_scale = 8 self.monitor = PAPeakMonitor(self.sink_name, self.meter_rate) self.timer = QTimer() self.timer.timeout.connect(self.update) self.timer.start(100) self.view = VUWidgetView(parent) self.view.setGeometry(0, 0, 20, parent.height() ) def update(self): for sample in self.monitor: sample = sample * self.display_scale self.view.update(sample)
def waitForSignal(signal, message="", timeout=0): """Waits (max timeout msecs if given) for a signal to be emitted. It the waiting lasts more than 2 seconds, a progress dialog is displayed with the message. Returns True if the signal was emitted. Return False if the wait timed out or the dialog was canceled by the user. """ loop = QEventLoop() dlg = QProgressDialog(minimum=0, maximum=0, labelText=message) dlg.setWindowTitle(appinfo.appname) dlg.setWindowModality(Qt.ApplicationModal) QTimer.singleShot(2000, dlg.show) dlg.canceled.connect(loop.quit) if timeout: QTimer.singleShot(timeout, dlg.cancel) stop = lambda: loop.quit() signal.connect(stop) loop.exec_() signal.disconnect(stop) dlg.hide() dlg.deleteLater() return not dlg.wasCanceled()
class CalendarWidget(QFrame): def __init__(self, parent = None): QFrame.__init__(self, parent) self.timer = QTimer() self.timer.setInterval(1000) self.timer.timeout.connect(self.updateCurrentDateTime) self.timer.start() def paintEvent(self, event): QFrame.paintEvent(self, event) text = QDateTime.currentDateTime().toString(Qt.SystemLocaleLongDate) logicalRect = QRectF(QPointF(0, 0), QSizeF(QFontMetrics(self.font()).size(Qt.TextSingleLine, text))) physicalRect, frameWidth = QRectF(self.rect()), self.frameWidth() physicalRect.adjust(frameWidth, frameWidth, -frameWidth, -frameWidth) scaleForWidth = physicalRect.width() / logicalRect.width() scaleForHeight = physicalRect.height() / logicalRect.height() logicalRect.moveTo(frameWidth / scaleForWidth , frameWidth / scaleForHeight) painter = QStylePainter(self) painter.scale(scaleForWidth, scaleForHeight) painter.drawText(logicalRect, Qt.AlignCenter, text) def updateCurrentDateTime(self): if self.isVisible(): self.update()
def __init__ (self, parent = None): QTimer.__init__ (self, parent) self.startTime = 0 self.ispaused = False self.interval = 0 QTimer.setSingleShot(self,True) self.timeout.connect(self._timeend)
def run(self): botlog.info('RFIDReaderThread Running.') self.blinkPhase = False self.blinkTimer = QTimer() self.blinkTimer.timeout.connect(self.blink) self.latchTimer = QTimer() self.latchTimer.timeout.connect(self.unlatch) self.latchTimer.setSingleShot(True) self.delayTimer = QTimer() self.delayTimer.timeout.connect(self.undelay) self.delayTimer.setSingleShot(True) self.notifier = QSocketNotifier(self.reader.fileno(), QSocketNotifier.Read) self.notifier.activated.connect(self.onData) self.blinkTimer.start(250) self.notifier.setEnabled(True) self.setStatus(Status.READY) self.exec() botlog.info('RFIDReaderThread Stopped.')
def test_repaint_after_visible_change(self): self.model = LayerStackModel() self.o1 = Layer([]) self.o1.name = "Fancy Layer" self.o1.opacity = 0.5 self.model.append(self.o1) self.o2 = Layer([]) self.o2.name = "Some other Layer" self.o2.opacity = 0.25 self.model.append(self.o2) self.view = LayerWidget(None, self.model) self.view.show() self.view.updateGeometry() self.w = QWidget() self.lh = QHBoxLayout(self.w) self.lh.addWidget(self.view) self.w.setGeometry(100, 100, 300, 300) self.w.show() # Run the test within the GUI event loop QTimer.singleShot(500, self.impl ) self.app.exec_() # Were there errors? assert not TestLayerWidget.errors, "There were GUI errors/failures. See above."
def wrapper(self): instantiated = bool(super(panel.Panel, self).widget()) self.activate() if instantiated: func(self) else: QTimer.singleShot(0, lambda: func(self))
class IntegrationTest(QWidget): """ Test the controller and view """ def __init__(self, model): super(IntegrationTest, self).__init__() self.model = model model.current_time = parse(u'2014-05-29T17:54:55+01:00').\ replace(tzinfo=pytz.utc) model.start_time = parse(u'2014-05-29T17:00:00+01:00').\ replace(tzinfo=pytz.utc) model.end_time = parse(u'2014-05-29T18:00:00+01:00').\ replace(tzinfo=pytz.utc) view = AutoStopDialog(self) self.auto_stop = AutoStopController(model, view, parent=self) self.setWindowModality(Qt.WindowModal) self.setWindowTitle('Example') self.timer = QTimer() self.timer.timeout.connect(self.inc_time) self.timer.start(1000) self.show() def inc_time(self): """ Increment the mock timer """ self.model.current_time = self.model.current_time + timedelta(0, 1)
def createWidget(self): import widget w = widget.MusicView(self) w.zoomChanged.connect(self.slotMusicZoomChanged) w.updateZoomInfo() w.view.surface().selectionChanged.connect(self.updateSelection) import qpopplerview.pager self._pager = p = qpopplerview.pager.Pager(w.view) p.pageCountChanged.connect(self.slotPageCountChanged) p.currentPageChanged.connect(self.slotCurrentPageChanged) app.languageChanged.connect(self.updatePagerLanguage) selector = self.actionCollection.music_document_select selector.currentDocumentChanged.connect(w.openDocument) selector.documentClosed.connect(w.clear) if selector.currentDocument(): # open a document only after the widget has been created; # this prevents many superfluous resizes def open(): if selector.currentDocument(): w.openDocument(selector.currentDocument()) QTimer.singleShot(0, open) return w
def startShellGui(workflow_cmdline_args, eventcapture_mode, playback_args, preinit_funcs, postinit_funcs): """ Create an application and launch the shell in it. """ """ The next two lines fix the following xcb error on Ubuntu by calling X11InitThreads before loading the QApplication: [xcb] Unknown request in queue while dequeuing [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. python: ../../src/xcb_io.c:178: dequeue_pending_request: Assertion !xcb_xlib_unknown_req_in_deq failed. """ platform_str = platform.platform().lower() if "ubuntu" in platform_str or "fedora" in platform_str or "debian" in platform_str: QApplication.setAttribute(Qt.AA_X11InitThreads, True) if ilastik.config.cfg.getboolean("ilastik", "debug"): QApplication.setAttribute(Qt.AA_DontUseNativeMenuBar, True) if eventcapture_mode is not None: # Only use a special QApplication subclass if we are recording. # Otherwise, it's a performance penalty for every event processed by Qt. from eventcapture.eventRecordingApp import EventRecordingApp app = EventRecordingApp.create_app(eventcapture_mode, **playback_args) else: app = QApplication([]) _applyStyleSheet(app) splashScreen.showSplashScreen() app.processEvents() QTimer.singleShot(0, functools.partial(launchShell, workflow_cmdline_args, preinit_funcs, postinit_funcs)) QTimer.singleShot(0, splashScreen.hideSplashScreen) return app.exec_()
def bisection_finished(self, bisection, resultcode): if resultcode == Bisection.USER_EXIT: msg = "Bisection stopped." dialog = QMessageBox.information elif resultcode == Bisection.NO_DATA: msg = "Unable to find enough data to bisect." dialog = QMessageBox.warning elif resultcode == Bisection.EXCEPTION: msg = "Error: %s" % self.bisector.error[1] dialog = QMessageBox.critical else: if bisection.fetch_config.can_go_inbound() and \ isinstance(bisection.handler, NightlyHandler): # we can go on inbound, let's ask the user if QMessageBox.question( self.mainwindow, "End of the bisection", "Nightly bisection is done, but you can continue the" " bisection on inbound builds. Contibue with inbounds ?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes ) == QMessageBox.Yes: # let's go on inbound QTimer.singleShot(0, self.bisector.nightlies_to_inbound) else: # no inbound, bisection is done. self.stop() return msg = "The bisection is done." dialog = QMessageBox.information dialog(self.mainwindow, "End of the bisection", msg) self.stop()
def __init__( self, what, options, path = "", buf = "", parent = None ): QDialog.__init__( self, parent ) self.__cancelRequest = False self.__inProgress = False self.__what = what self.__options = options self.__path = path # could be a dir or a file self.__buf = buf # content in case of a modified file # Working process data self.__participantFiles = [] # Collected list of files self.__projectImportDirs = [] self.__projectImportsCache = {} # utils.settings -> /full/path/to.py self.__dirsToImportsCache = {} # /dir/path -> { my.mod: path.py, ... } self.dataModel = ImportDiagramModel() self.scene = QGraphicsScene() # Avoid pylint complains self.progressBar = None self.infoLabel = None self.__createLayout() self.setWindowTitle( 'Imports/dependencies diagram generator' ) QTimer.singleShot( 0, self.__process ) return
def getAllSelected(self): """Get all selected items by user.""" if self.populatedTable: self.stackedWidget.setCurrentIndex(1) self.updateUi() return msg = "Getting all selected entries from ItemTracker. Please wait..." self.statusbar.showMessage(msg) if len(self.itemIdsAll): try: self.tableResults = \ lims.SelectAllselectedEntries(self.itemIdsAll.keys()) except: raise RuntimeError else: self.mkInfo("No ItemTracker IDs to process") if not len(self.tableResults): user = os.environ.get("USERNAME") msg = "No selected entries for user {0}".format(user) self.statusbar.showMessage(msg, 5000) self.mkInfo(msg) self.stackedWidget.setCurrentIndex(1) self.populatedTable = False self.updateUi() else: QTimer.singleShot(0, self.populateTable)
def private_call_later(self, callback, delay=None): if delay is None: delay = 0 if not isinstance(delay, (float, int)): raise ScriptError({ "argument": "delay", "message": "splash:call_later delay must be a number", "splash_method": "call_later", }) delay = int(float(delay)*1000) if delay < 0: raise ScriptError({ "argument": "delay", "message": "splash:call_later delay must be >= 0", "splash_method": "call_later", }) if lupa.lua_type(callback) != 'function': raise ScriptError({ "argument": "callback", "message": "splash:call_later callback is not a function", "splash_method": "call_later", }) qtimer = QTimer(self.tab) qtimer.setSingleShot(True) timer = _ExposedTimer(self, qtimer) run_coro = self.get_coroutine_run_func( "splash:call_later", callback, return_error=timer.store_error ) qtimer.timeout.connect(run_coro) qtimer.start(delay) return timer
class ContextEntityItem(QTreeWidgetItem): def __init__(self, entity): super(ContextEntityItem, self).__init__([entity.name()]) self.setSizeHint(0, QSize(0, 24)) self._entity = entity self._versionsThread = threads.EntityVersionsThread( db.project(), Version.ShotgunFields, entity.tankKey()) self._loaded = False self._loading = False self._lazyTimer = QTimer() self._lazyTimer.setInterval(1000) self._lazyTimer.timeout.connect(self.loadVersions) self._versionsThread.finished.connect(self.updateData) def activeVersions(self): tree = self.treeWidget() if (not tree): return [] output = [] for i in range(1, tree.columnCount()): widget = tree.itemWidget(self, i) if (not widget): continue output += widget.activeVersions() return output def entity(self): return self._entity def contextWidget(self): return self.treeWidget() def initData(self): if (not self.readyToLoad()): self.lazyLoadVersions() else: self.loadVersions() def isLoading(self): return self._loading def reload(self): self._loaded = False self.loadVersions(True) def lazyLoadVersions(self): self._lazyTimer.start() def loadVersions(self, force=False): # make sure the item should be loaded # (by default forcing, so it will load in the # background vs. when the user displays) if (not (force or self.readyToLoad())): return False if (self._loaded): self._lazyTimer.stop() return self._loaded = False tree = self.treeWidget() # make sure the lazy timer isn't going anymore self._lazyTimer.stop() for c in range(1, tree.columnCount()): tree.setItemWidget(self, c, LoaderWidget(tree)) # start the thread self._loading = True self.contextWidget().markLoading(self, True) self._versionsThread.start() def readyToLoad(self): tree = self.treeWidget() if (not tree): return False geom = tree.geometry() rect = tree.visualItemRect(self) visible = (geom.top() <= rect.bottom() and rect.top() <= geom.bottom()) # check to see the visible state of the item if (not (visible or self.isSelected())): return False return True def reSort(self): tree = self.treeWidget() entity = self.entity() entity.sortVersions() for i in range(tree.columnCount()): widget = tree.itemWidget(self, i) if (isinstance(widget, ContextVersionsWidget)): widget.setVersions(entity.findVersions(tree.departmentAt(i))) def updateData(self): # mark that the item has been loaded self._lazyTimer.stop() self._loaded = True self._loading = False tree = self.treeWidget() # set the data for the entity self._entity.setVersionsFromShotgun(self._versionsThread.versions()) for c in range(1, tree.columnCount()): versions = self._entity.findVersions(tree.departmentAt(c)) if (versions): tree.setItemWidget( self, c, ContextVersionsWidget(tree, self._entity, versions)) else: tree.setItemWidget(self, c, None) # unmark this item as loading self.contextWidget().markLoading(self, False)
# Library imports # --------------- import sys import os # Third-party imports # ------------------- # Instead of creating a custom .spec file: inform PyInstaller of the # hidden import of QtWebKit, which is performed inside of uic.loadUi. from PyQt4.QtWebKit import QWebView # Other Qt imports used in the code below. from PyQt4.QtGui import QApplication, QDialog from PyQt4 import uic from PyQt4.QtCore import QTimer # Local imports # ------------- from pyi_get_datadir import get_data_dir # Test code # --------- app = QApplication([]) window = QDialog() uic.loadUi(os.path.join(get_data_dir(), 'PyQt4_uic', 'PyQt4-uic.ui'), window) window.show() # Exit Qt when the main loop becomes idle. QTimer.singleShot(0, app.exit) # Run the main loop, displaying the WebKit widget. app.exec_()
class Surface(QWidget): rightClicked = pyqtSignal(QPoint) linkClicked = pyqtSignal(QEvent, page.Page, popplerqt4.Poppler.Link) linkHovered = pyqtSignal(page.Page, popplerqt4.Poppler.Link) linkLeft = pyqtSignal() linkHelpRequested = pyqtSignal(QPoint, page.Page, popplerqt4.Poppler.Link) selectionChanged = pyqtSignal(QRect) def __init__(self, view): super(Surface, self).__init__(view) self.setBackgroundRole(QPalette.Dark) self._view = weakref.ref(view) self._currentLinkId = None self._selecting = False self._magnifying = False self._magnifier = None self.setMagnifier(magnifier.Magnifier()) self.setMagnifierModifiers(Qt.CTRL) self._selection = QRect() self._rubberBand = CustomRubberBand(self) self._scrolling = False self._scrollTimer = QTimer(interval=100, timeout=self._scrollTimeout) self._pageLayout = None self._highlights = weakref.WeakKeyDictionary() self.setPageLayout(layout.Layout()) self.setContextMenuPolicy(Qt.PreventContextMenu) self.setLinksEnabled(True) self.setSelectionEnabled(True) self.setShowUrlTips(True) self.view().cursorNeedUpdate.connect(self.updateCursor) def pageLayout(self): return self._pageLayout def setPageLayout(self, layout): old, self._pageLayout = self._pageLayout, layout if old: old.redraw.disconnect(self.redraw) old.changed.disconnect(self.updateLayout) layout.redraw.connect(self.redraw) layout.changed.connect(self.updateLayout) def view(self): """Returns our associated View.""" return self._view() def viewportRect(self): """Returns the rectangle of us that is visible in the View.""" return self.view().viewport().rect().translated(-self.pos()) def setSelectionEnabled(self, enabled): """Enables or disables selecting rectangular regions.""" self._selectionEnabled = enabled if not enabled: self.clearSelection() self._rubberBand.hide() self._selecting = False def selectionEnabled(self): """Returns True if selecting rectangular regions is enabled.""" return self._selectionEnabled def setLinksEnabled(self, enabled): """Enables or disables the handling of Poppler.Links in the pages.""" self._linksEnabled = enabled def linksEnabled(self): """Returns True if the handling of Poppler.Links in the pages is enabled.""" return self._linksEnabled def setShowUrlTips(self, enabled): """Enables or disables showing the URL in a tooltip when hovering a link. (Of course also setLinksEnabled(True) if you want this.) """ self._showUrlTips = enabled def showUrlTips(self): """Returns True if URLs are shown in a tooltip when hovering a link.""" return self._showUrlTips def setMagnifier(self, magnifier): """Sets the Magnifier to use (or None to disable the magnifier). The Surface takes ownership of the Magnifier. """ if self._magnifier: self._magnifier.setParent(None) magnifier.setParent(self) self._magnifier = magnifier def magnifier(self): """Returns the currently set magnifier.""" return self._magnifier def setMagnifierModifiers(self, modifiers): """Sets the modifiers (e.g. Qt.CTRL) to show the magnifier. Use None to show the magnifier always (instead of dragging). """ self._magnifierModifiers = modifiers def magnifierModifiers(self): """Returns the currently set keyboard modifiers (e.g. Qt.CTRL) to show the magnifier.""" return self._magnifierModifiers def hasSelection(self): """Returns True if there is a selection.""" return bool(self._selection) def setSelection(self, rect): """Sets the selection rectangle.""" rect = rect.normalized() old, self._selection = self._selection, rect self._rubberBand.setGeometry(rect) self._rubberBand.setVisible(bool(rect)) if rect != old: self.selectionChanged.emit(rect) def selection(self): """Returns the selection rectangle (normalized) or an invalid QRect().""" return QRect(self._selection) def clearSelection(self): """Hides the selection rectangle.""" self.setSelection(QRect()) def redraw(self, rect): """Called when the Layout wants to redraw a rectangle.""" self.update(rect) def updateLayout(self): """Conforms ourselves to our layout (that must already be updated.)""" self.clearSelection() self.resize(self._pageLayout.size()) self.update() def highlight(self, highlighter, areas, msec=0): """Highlights the list of areas using the given highlighter. Every area is a two-tuple (page, rect), where rect is a rectangle inside (0, 0, 1, 1) like the linkArea attribute of a Poppler.Link. """ d = weakref.WeakKeyDictionary() for page, areas in itertools.groupby(sorted(areas), lambda a: a[0]): d[page] = list(area[1] for area in areas) if msec: def clear(selfref=weakref.ref(self)): self = selfref() if self: self.clearHighlight(highlighter) t = QTimer(singleShot=True, timeout=clear) t.start(msec) else: t = None self.clearHighlight(highlighter) self._highlights[highlighter] = (d, t) self.update(sum((page.rect() for page in d), QRegion())) def clearHighlight(self, highlighter): """Removes the highlighted areas of the given highlighter.""" try: (d, t) = self._highlights[highlighter] except KeyError: return del self._highlights[highlighter] self.update(sum((page.rect() for page in d), QRegion())) def paintEvent(self, ev): """Handle PaintEvent on the surface to highlight the selection.""" painter = QPainter(self) pages = list(self.pageLayout().pagesAt(ev.rect())) for page in pages: page.paint(painter, ev.rect()) for highlighter, (d, t) in self._highlights.items(): rects = [] for page in pages: try: rects.extend(map(page.linkRect, d[page])) except KeyError: continue if rects: highlighter.paintRects(painter, rects) def handleMousePressEvent(self, ev): """Handle mouse press for various operations - links to source, - magnifier, - selection highlight, If event was used, return true to indicate processing should stop. """ # As the event comes from the view, we need to map it locally. pos = self.mapFromParent(ev.pos()) # selecting? if self._selectionEnabled: if self.hasSelection(): edge = selectionEdge(pos, self.selection()) if edge == _OUTSIDE: self.clearSelection() else: if ev.button() != Qt.RightButton or edge != _INSIDE: self._selecting = True self._selectionEdge = edge self._selectionRect = self.selection() self._selectionPos = pos if edge == _INSIDE: self.setCursor(Qt.SizeAllCursor) return True if not self._selecting: if ev.modifiers() & Qt.ShiftModifier and ev.button( ) == Qt.LeftButton and self._linksEnabled: page, link = self.pageLayout().linkAt(pos) if link: self.linkClickEvent(ev, page, link) return True if ev.button() == Qt.RightButton or int( ev.modifiers()) & _SCAM: if not (int(ev.modifiers()) & _SCAM == self._magnifierModifiers and ev.button() == Qt.LeftButton): self._selecting = True self._selectionEdge = _RIGHT | _BOTTOM self._selectionRect = QRect(pos, QSize(0, 0)) self._selectionPos = pos return True # link? if self._linksEnabled: page, link = self.pageLayout().linkAt(pos) if link: self.linkClickEvent(ev, page, link) return True # magnifier? if (self._magnifier and int(ev.modifiers()) & _SCAM == self._magnifierModifiers and ev.button() == Qt.LeftButton): self._magnifier.moveCenter(pos) self._magnifier.show() self._magnifier.raise_() self._magnifying = True self.setCursor(QCursor(Qt.BlankCursor)) return True return False def handleMouseReleaseEvent(self, ev): """Handle mouse release events for various operations: - hide magnifier, - selection. If event was used, return true to indicate processing should stop. """ consumed = False if self._magnifying: self._magnifier.hide() self._magnifying = False self.unsetCursor() consumed = True elif self._selecting: self._selecting = False selection = self._selectionRect.normalized() if selection.width() < 8 and selection.height() < 8: self.clearSelection() else: self.setSelection(selection) if self._scrolling: self.stopScrolling() self.unsetCursor() consumed = True if ev.button() == Qt.RightButton: # As the event comes from the view, we need to map it locally. self.rightClick(self.mapFromParent(ev.pos())) consumed = True return consumed def handleMouseMoveEvent(self, ev): """Handle mouse move events for various operations: - move magnifier, - selection extension. If event was used, return true to indicate processing should stop. """ consumed = False if self._magnifying: # As the event comes from the view, we need to map it locally. self._magnifier.moveCenter(self.mapFromParent(ev.pos())) consumed = True elif self._selecting: # As the event comes from the view, we need to map it locally. pos = self.mapFromParent(ev.pos()) self._moveSelection(pos) self._rubberBand.show() # check if we are dragging close to the edge of the view, scroll if needed view = self.viewportRect() dx = pos.x() - view.left() - 12 if dx >= 0: dx = pos.x() - view.right() + 12 if dx < 0: dx = 0 dy = pos.y() - view.top() - 12 if dy >= 0: dy = pos.y() - view.bottom() + 12 if dy < 0: dy = 0 if dx or dy: self.startScrolling(dx, dy) elif self._scrolling: self.stopScrolling() consumed = True return consumed def handleMoveEvent(self, ev): """Handle move events for various operations: - move magnifier, - selection extension. If event was used, return true to indicate processing should stop. """ consumed = False pos = self.mapFromGlobal(QCursor.pos()) if self._selecting: self._moveSelection(pos) consumed = True elif self._magnifying: self._magnifier.moveCenter(pos) consumed = True return consumed def handleHelpEvent(self, ev): """Handle help event: show link if any.""" if self._linksEnabled: page, link = self.pageLayout().linkAt(self.mapFromParent(ev.pos())) if link: self.linkHelpEvent(ev.globalPos(), page, link) return True def updateKineticCursor(self, active): """Cursor handling when kinetic move starts/stops. - reset the cursor and hide tooltips if visible at start, - update the cursor and show the appropriate tooltips at stop. Used as a slot linked to the kineticStarted() signal. """ if active: self.unsetCursor() if QToolTip.isVisible(): QToolTip.hideText() else: self.updateCursor(QCursor.pos()) if self._linksEnabled: page, link = self.pageLayout().linkAt( self.mapFromGlobal(QCursor.pos())) if link: self.linkHelpEvent(QCursor.pos(), page, link) def updateCursor(self, evpos): """Set the cursor to the right glyph, depending on action""" pos = self.mapFromGlobal(evpos) cursor = None edge = _OUTSIDE if self._selectionEnabled and self.hasSelection(): edge = selectionEdge(pos, self.selection()) if edge is not _OUTSIDE: if edge in (_TOP, _BOTTOM): cursor = Qt.SizeVerCursor elif edge in (_LEFT, _RIGHT): cursor = Qt.SizeHorCursor elif edge in (_LEFT | _TOP, _RIGHT | _BOTTOM): cursor = Qt.SizeFDiagCursor elif edge in (_TOP | _RIGHT, _BOTTOM | _LEFT): cursor = Qt.SizeBDiagCursor elif edge is _INSIDE: cursor = Qt.SizeAllCursor elif self._linksEnabled: page, link = self.pageLayout().linkAt(pos) if link: cursor = Qt.PointingHandCursor lid = id(link) else: lid = None if lid != self._currentLinkId: if self._currentLinkId is not None: self.linkHoverLeave() self._currentLinkId = lid if link: self.linkHoverEnter(page, link) self.setCursor(cursor) if cursor else self.unsetCursor() def linkHelpEvent(self, globalPos, page, link): """Called when a QHelpEvent occurs on a link. The default implementation shows a tooltip if showUrls() is True, and emits the linkHelpRequested() signal. """ if self._showUrlTips and isinstance(link, popplerqt4.Poppler.LinkBrowse): QToolTip.showText(globalPos, link.url(), self, page.linkRect(link.linkArea())) self.linkHelpRequested.emit(globalPos, page, link) def rightClick(self, pos): """Called when the right mouse button is released. (Use this instead of the contextMenuEvent as that one also fires when starting a right-button selection.) The default implementation emite the rightClicked(pos) signal and also sends a ContextMenu event to the View widget. """ self.rightClicked.emit(pos) QApplication.postEvent( self.view().viewport(), QContextMenuEvent(QContextMenuEvent.Mouse, pos + self.pos())) def linkClickEvent(self, ev, page, link): """Called when a link is clicked. The default implementation emits the linkClicked(event, page, link) signal. """ self.linkClicked.emit(ev, page, link) def linkHoverEnter(self, page, link): """Called when the mouse hovers over a link. The default implementation emits the linkHovered(page, link) signal. """ self.linkHovered.emit(page, link) def linkHoverLeave(self): """Called when the mouse does not hover a link anymore. The default implementation emits the linkLeft() signal. """ self.linkLeft.emit() def startScrolling(self, dx, dy): """Starts scrolling dx, dy about 10 times a second. Stops automatically when the end is reached. """ self._scrolling = QPoint(dx, dy) self._scrollTimer.isActive() or self._scrollTimer.start() def stopScrolling(self): """Stops scrolling.""" self._scrolling = False self._scrollTimer.stop() def _scrollTimeout(self): """(Internal) Called by the _scrollTimer.""" # change the scrollbars, but check how far they really moved. pos = self.pos() self.view().fastScrollBy(self._scrolling) diff = pos - self.pos() if not diff: self.stopScrolling() def _moveSelection(self, pos): """(Internal) Moves the dragged selection edge or corner to the given pos (QPoint).""" diff = pos - self._selectionPos self._selectionPos = pos edge = self._selectionEdge self._selectionRect.adjust(diff.x() if edge & _LEFT else 0, diff.y() if edge & _TOP else 0, diff.x() if edge & _RIGHT else 0, diff.y() if edge & _BOTTOM else 0) self._rubberBand.setGeometry(self._selectionRect.normalized()) if self.cursor().shape() in (Qt.SizeBDiagCursor, Qt.SizeFDiagCursor): # we're dragging a corner, use correct diagonal cursor bdiag = (edge in (3, 12)) ^ (self._selectionRect.width() * self._selectionRect.height() >= 0) self.setCursor(Qt.SizeBDiagCursor if bdiag else Qt.SizeFDiagCursor)
def tab_on_focus(self): QTimer.singleShot(1, self.refresh_program_list)
class EventEngine(object): """ 事件驱动引擎 事件驱动引擎中所有的变量都设置为了私有,这是为了防止不小心 从外部修改了这些变量的值或状态,导致bug。 变量说明 __queue:私有变量,事件队列 __active:私有变量,事件引擎开关 __thread:私有变量,事件处理线程 __timer:私有变量,计时器 __handlers:私有变量,事件处理函数字典 方法说明 __run: 私有方法,事件处理线程连续运行用 __process: 私有方法,处理事件,调用注册在引擎中的监听函数 __onTimer:私有方法,计时器固定事件间隔触发后,向事件队列中存入计时器事件 start: 公共方法,启动引擎 stop:公共方法,停止引擎 register:公共方法,向引擎中注册监听函数 unregister:公共方法,向引擎中注销监听函数 put:公共方法,向事件队列中存入新的事件 事件监听函数必须定义为输入参数仅为一个event对象,即: 函数 def func(event) ... 对象方法 def method(self, event) ... """ #---------------------------------------------------------------------- def __init__(self): """初始化事件引擎""" # 事件队列 self.__queue = Queue() # 事件引擎开关 self.__active = False # 事件处理线程 self.__thread = Thread(target=self.__run) # 计时器,用于触发计时器事件 self.__timer = QTimer() self.__timer.timeout.connect(self.__onTimer) # 这里的__handlers是一个字典,用来保存对应的事件调用关系 # 其中每个键对应的值是一个列表,列表中保存了对该事件进行监听的函数功能 self.__handlers = defaultdict(list) #---------------------------------------------------------------------- def __run(self): """引擎运行""" while self.__active == True: try: event = self.__queue.get(block=True, timeout=1) # 获取事件的阻塞时间设为1秒 self.__process(event) except Empty: pass #---------------------------------------------------------------------- def __process(self, event): """处理事件""" # 检查是否存在对该事件进行监听的处理函数 if event.type_ in self.__handlers: # 若存在,则按顺序将事件传递给处理函数执行 [handler(event) for handler in self.__handlers[event.type_]] # 以上语句为Python列表解析方式的写法,对应的常规循环写法为: #for handler in self.__handlers[event.type_]: #handler(event) #---------------------------------------------------------------------- def __onTimer(self): """向事件队列中存入计时器事件""" # 创建计时器事件 event = Event(type_=EVENT_TIMER) # 向队列中存入计时器事件 self.put(event) #---------------------------------------------------------------------- def start(self): """引擎启动""" # 将引擎设为启动 self.__active = True # 启动事件处理线程 self.__thread.start() # 启动计时器,计时器事件间隔默认设定为1秒 self.__timer.start(1000) #---------------------------------------------------------------------- def stop(self): """停止引擎""" # 将引擎设为停止 self.__active = False # 停止计时器 self.__timer.stop() # 等待事件处理线程退出 self.__thread.join() #---------------------------------------------------------------------- def register(self, type_, handler): """注册事件处理函数监听""" # 尝试获取该事件类型对应的处理函数列表,若无defaultDict会自动创建新的list handlerList = self.__handlers[type_] # 若要注册的处理器不在该事件的处理器列表中,则注册该事件 if handler not in handlerList: handlerList.append(handler) #---------------------------------------------------------------------- def unregister(self, type_, handler): """注销事件处理函数监听""" # 尝试获取该事件类型对应的处理函数列表,若无则忽略该次注销请求 handlerList = self.__handlers[type_] # 如果该函数存在于列表中,则移除 if handler in handlerList: handlerList.remove(handler) # 如果函数列表为空,则从引擎中移除该事件类型 if not handlerList: del self.__handlers[type_] #---------------------------------------------------------------------- def put(self, event): """向事件队列中存入事件""" self.__queue.put(event)
def __init__(self, *args): PluginBase.__init__(self, BrickServo, *args) self.setupUi(self) self.servo = self.device self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_cur = 0 self.up_siv = 0 self.up_eiv = 0 self.up_opv = 0 self.up_mv = 0 self.up_ena = [0] * 7 self.up_pos = [0] * 7 self.up_vel = [0] * 7 self.up_acc = [0] * 7 self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(50) self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect( self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect( lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_syncer = SliderSpinSyncer(self.position_slider, self.position_spin, self.position_changed) self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.period_syncer = SliderSpinSyncer(self.period_slider, self.period_spin, self.period_changed) self.pulse_width_min_spin.editingFinished.connect( self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect( self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.clicked.connect( self.minimum_voltage_button_clicked) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent=None, func=None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_thread_first_time = False self.update_done_event = Event() self.update_done_event.set() if self.firmware_version >= (1, 1, 3): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.servo.reset()) self.set_actions(reset)
class Servo(PluginBase, Ui_Servo): qtcb_under_voltage = pyqtSignal(int) def __init__(self, *args): PluginBase.__init__(self, BrickServo, *args) self.setupUi(self) self.servo = self.device self.position_list = [] self.velocity_list = [] self.acceleration_list = [] self.enable_list = [] self.up_cur = 0 self.up_siv = 0 self.up_eiv = 0 self.up_opv = 0 self.up_mv = 0 self.up_ena = [0] * 7 self.up_pos = [0] * 7 self.up_vel = [0] * 7 self.up_acc = [0] * 7 self.update_timer = QTimer() self.update_timer.timeout.connect(self.update_apply) self.update_timer.setInterval(50) self.alive = True for i in range(1, 8): label = QLabel() label.setText('Off') self.enable_list.append(label) self.status_grid.addWidget(label, i, 1) for i in range(1, 8): pk = PositionKnob() self.position_list.append(pk) self.status_grid.addWidget(pk, i, 2) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.velocity_list.append(cb) self.status_grid.addWidget(cb, i, 3) for i in range(1, 8): cb = ColorBar(Qt.Vertical) self.acceleration_list.append(cb) self.status_grid.addWidget(cb, i, 4) self.qem = QErrorMessage(self) self.qem.setWindowTitle("Under Voltage") self.test_button.clicked.connect(self.test_button_clicked) self.output_voltage_button.clicked.connect( self.output_voltage_button_clicked) self.servo_dropbox.currentIndexChanged.connect( lambda x: self.update_servo_specific()) self.enable_checkbox.stateChanged.connect(self.enable_state_changed) self.position_syncer = SliderSpinSyncer(self.position_slider, self.position_spin, self.position_changed) self.velocity_syncer = SliderSpinSyncer(self.velocity_slider, self.velocity_spin, self.velocity_changed) self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider, self.acceleration_spin, self.acceleration_changed) self.period_syncer = SliderSpinSyncer(self.period_slider, self.period_spin, self.period_changed) self.pulse_width_min_spin.editingFinished.connect( self.pulse_width_spin_finished) self.pulse_width_max_spin.editingFinished.connect( self.pulse_width_spin_finished) self.degree_min_spin.editingFinished.connect(self.degree_spin_finished) self.degree_max_spin.editingFinished.connect(self.degree_spin_finished) self.minimum_voltage_button.clicked.connect( self.minimum_voltage_button_clicked) self.qtcb_under_voltage.connect(self.cb_under_voltage) self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE, self.qtcb_under_voltage.emit) class WorkerThread(QThread): def __init__(self, parent=None, func=None): QThread.__init__(self, parent) self.func = func def run(self): self.func() self.test_event = Event() self.test_thread_object = WorkerThread(self, self.test_thread) self.update_event = Event() self.update_thread_object = WorkerThread(self, self.update_thread) self.update_thread_first_time = False self.update_done_event = Event() self.update_done_event.set() if self.firmware_version >= (1, 1, 3): reset = QAction('Reset', self) reset.triggered.connect(lambda: self.servo.reset()) self.set_actions(reset) def start(self): self.alive = True self.test_event.clear() self.update_done_event.set() self.update_event.set() if not self.test_thread_object.isRunning(): self.test_thread_object.start() if not self.update_thread_object.isRunning(): self.update_thread_object.start() self.update_servo_specific() self.update_timer.start() def stop(self): if self.test_button.text() == "Stop Test": self.test_button_clicked() self.update_timer.stop() self.update_event.clear() self.alive = False self.update_done_event.wait() def destroy(self): self.test_event.set() self.update_event.set() def get_url_part(self): return 'servo' @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickServo.DEVICE_IDENTIFIER def get_period_async(self, per): self.period_spin.setValue(per) self.period_slider.setValue(per) def is_enabled_async(self, ena): self.enable_checkbox.setChecked(ena) def get_position_async(self, pos): self.position_spin.setValue(pos) self.position_slider.setValue(pos) def get_velocity_async(self, vel): self.velocity_spin.setValue(vel) self.velocity_slider.setValue(vel) def get_acceleration_async(self, acc): self.acceleration_spin.setValue(acc) self.acceleration_slider.setValue(acc) def get_degree_async(self, deg, i): deg_min, deg_max = deg self.degree_min_spin.setValue(deg_min) self.degree_max_spin.setValue(deg_max) self.position_slider.setMinimum(deg_min) self.position_slider.setMaximum(deg_max) self.position_spin.setMinimum(deg_min) self.position_spin.setMaximum(deg_max) self.position_list[i].set_total_angle((deg_max - deg_min) / 100) self.position_list[i].set_range(deg_min / 100, deg_max / 100) def get_pulse_width_async(self, pulse): pulse_min, pulse_max = pulse self.pulse_width_min_spin.setValue(pulse_min) self.pulse_width_max_spin.setValue(pulse_max) def update_servo_specific(self): i = self.selected_servo() if i == 255: self.enable_checkbox.setChecked(False) return async_call(self.servo.get_position, i, self.get_position_async, self.increase_error_count) async_call(self.servo.get_velocity, i, self.get_velocity_async, self.increase_error_count) async_call(self.servo.get_acceleration, i, self.get_acceleration_async, self.increase_error_count) async_call(self.servo.get_period, i, self.get_period_async, self.increase_error_count) async_call(self.servo.is_enabled, i, self.is_enabled_async, self.increase_error_count) def get_lambda_deg(i): return lambda x: self.get_degree_async(x, i) async_call(self.servo.get_degree, i, get_lambda_deg(i), self.increase_error_count) async_call(self.servo.get_pulse_width, i, self.get_pulse_width_async, self.increase_error_count) def error_handler(self, error): pass def servo_current_update(self, value): self.current_label.setText(str(value) + "mA") def stack_input_voltage_update(self, sv): sv_str = "%gV" % round(sv / 1000.0, 1) self.stack_voltage_label.setText(sv_str) def external_input_voltage_update(self, ev): ev_str = "%gV" % round(ev / 1000.0, 1) self.external_voltage_label.setText(ev_str) def output_voltage_update(self, ov): ov_str = "%gV" % round(ov / 1000.0, 1) self.output_voltage_label.setText(ov_str) def minimum_voltage_update(self, mv): mv_str = "%gV" % round(mv / 1000.0, 1) self.minimum_voltage_label.setText(mv_str) def position_update(self, i, pos): self.position_list[i].set_value(pos / 100) def velocity_update(self, i, vel): self.velocity_list[i].set_height(vel * 100 / 0xFFFF) def acceleration_update(self, i, acc): self.acceleration_list[i].set_height(acc * 100 / 0xFFFF) def deactivate_servo(self, i): if self.enable_list[i].text() != 'Off': self.velocity_list[i].grey() self.acceleration_list[i].grey() def activate_servo(self, i): if self.enable_list[i].text() != 'On': self.velocity_list[i].color() self.acceleration_list[i].color() def selected_servo(self): try: return int(self.servo_dropbox.currentText()[-1:]) except: return 255 def enable_state_changed(self, state): s = self.selected_servo() try: if state == Qt.Checked: self.servo.enable(s) elif state == Qt.Unchecked: self.servo.disable(s) except ip_connection.Error: return def update_apply(self): if not self.update_thread_first_time: return self.servo_current_update(self.up_cur) self.stack_input_voltage_update(self.up_siv) self.external_input_voltage_update(self.up_eiv) self.output_voltage_update(self.up_opv) self.minimum_voltage_update(self.up_mv) for i in range(7): if self.up_ena[i]: self.activate_servo(i) self.position_update(i, self.up_pos[i]) self.velocity_update(i, self.up_vel[i]) self.acceleration_update(i, self.up_acc[i]) self.enable_list[i].setText('On') else: self.deactivate_servo(i) self.enable_list[i].setText('Off') def update_thread(self): while self.alive: time.sleep(0.1) try: servo = self.selected_servo() if servo == 255: self.up_cur = self.servo.get_overall_current() else: self.up_cur = self.servo.get_servo_current(servo) self.up_siv = self.servo.get_stack_input_voltage() self.up_eiv = self.servo.get_external_input_voltage() self.up_opv = self.servo.get_output_voltage() self.up_mv = self.servo.get_minimum_voltage() for i in range(7): self.up_ena[i] = self.servo.is_enabled(i) if self.up_ena[i]: self.activate_servo(i) self.up_pos[i] = self.servo.get_current_position(i) self.up_vel[i] = self.servo.get_current_velocity(i) self.up_acc[i] = self.servo.get_acceleration(i) #self.update_apply() self.update_done_event.set() self.update_event.wait() self.update_done_event.clear() except ip_connection.Error: pass self.update_thread_first_time = True self.update_done_event.set() def test_thread(self): def test(num, ena, acc, vel, pos): if not self.alive: return try: if ena: self.servo.enable(num) else: self.servo.disable(num) self.servo.set_acceleration(num, acc) self.servo.set_velocity(num, vel) self.servo.set_position(num, pos) except ip_connection.Error: return def random_test(): for i in range(7): test(i, random.randrange(0, 2), random.randrange(0, 65536), random.randrange(0, 65536), random.randrange(-9000, 9001)) while self.alive: self.test_event.wait() if not self.alive: return # Full Speed left for 2 seconds for i in range(7): test(i, True, 65535, 65535, 9000) time.sleep(2) self.test_event.wait() if not self.alive: return # Full Speed right for 2 seconds for i in range(7): test(i, True, 65535, 65535, -9000) time.sleep(2) self.test_event.wait() if not self.alive: return # Test different speeds for i in range(19): for j in range(7): test(j, True, 65535, 65535 * i / 18, -9000 + i * 1000) time.sleep(0.1) self.test_event.wait() if not self.alive: return time.sleep(1) self.test_event.wait() if not self.alive: return # Test acceleration for i in range(7): test(i, True, 100, 65535, -9000) time.sleep(3) self.test_event.wait() if not self.alive: return # Random for 3 seconds random_test() time.sleep(3) def test_button_clicked(self): if self.test_button.text() == "Start Test": self.test_button.setText("Stop Test") self.test_event.set() else: self.test_button.setText("Start Test") self.test_event.clear() def output_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(2000) qid.setIntMaximum(9000) qid.setIntStep(100) async_call(self.servo.get_output_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.output_voltage_selected) qid.setLabelText("Choose Output Voltage in mV.") # "<font color=red>Setting this too high can destroy your servo.</font>") qid.open() def output_voltage_selected(self, value): try: self.servo.set_output_voltage(value) except ip_connection.Error: return def position_changed(self, value): try: self.servo.set_position(self.selected_servo(), value) except ip_connection.Error: return def velocity_changed(self, value): try: self.servo.set_velocity(self.selected_servo(), value) except ip_connection.Error: return def acceleration_changed(self, value): try: self.servo.set_acceleration(self.selected_servo(), value) except ip_connection.Error: return def period_changed(self, value): try: self.servo.set_period(self.selected_servo(), value) except ip_connection.Error: return def pulse_width_spin_finished(self): try: self.servo.set_pulse_width(self.selected_servo(), self.pulse_width_min_spin.value(), self.pulse_width_max_spin.value()) except ip_connection.Error: return def degree_spin_finished(self): min = self.degree_min_spin.value() max = self.degree_max_spin.value() servo = self.selected_servo() self.position_slider.setMinimum(min) self.position_slider.setMaximum(max) self.position_spin.setMinimum(min) self.position_spin.setMaximum(max) if servo == 255: for i in range(7): self.position_list[i].set_total_angle((max - min) / 100) self.position_list[i].set_range(min / 100, max / 100) else: self.position_list[servo].set_total_angle((max - min) / 100) self.position_list[servo].set_range(min / 100, max / 100) try: self.servo.set_degree(servo, min, max) except ip_connection.Error: return def cb_under_voltage(self, ov): mv_str = self.minimum_voltage_label.text() ov_str = "%gV" % round(ov / 1000.0, 1) if not self.qem.isVisible(): self.qem.showMessage( "Under Voltage: Output Voltage of " + ov_str + " is below minimum voltage of " + mv_str, "Servo_UnterVoltage") def minimum_voltage_selected(self, value): try: self.servo.set_minimum_voltage(value) except ip_connection.Error: return def minimum_voltage_button_clicked(self): qid = QInputDialog(self) qid.setInputMode(QInputDialog.IntInput) qid.setIntMinimum(5000) qid.setIntMaximum(0xFFFF) qid.setIntStep(100) async_call(self.servo.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count) qid.intValueSelected.connect(self.minimum_voltage_selected) qid.setLabelText("Choose minimum servo voltage in mV.") qid.open()
class AnkiConnect: def __init__(self): self.anki = AnkiBridge() self.server = AjaxServer(self.handler) try: self.server.listen() self.timer = QTimer() self.timer.timeout.connect(self.advance) self.timer.start(TICK_INTERVAL) except: QMessageBox.critical( self.anki.window(), 'AnkiConnect', 'Failed to listen on port {}.\nMake sure it is available and is not in use.' .format(NET_PORT)) def advance(self): self.server.advance() def handler(self, request): name = request.get('action', '') version = request.get('version', 4) params = request.get('params', {}) reply = {'result': None, 'error': None} try: method = None for methodName, methodInst in inspect.getmembers( self, predicate=inspect.ismethod): apiVersionLast = 0 apiNameLast = None if getattr(methodInst, 'api', False): for apiVersion, apiName in getattr(methodInst, 'versions', []): if apiVersionLast < apiVersion <= version: apiVersionLast = apiVersion apiNameLast = apiName if apiNameLast is None and apiVersionLast == 0: apiNameLast = methodName if apiNameLast is not None and apiNameLast == name: method = methodInst break if method is None: raise Exception('unsupported action') else: reply['result'] = methodInst(**params) except Exception as e: reply['error'] = str(e) if version > 4: return reply else: return reply['result'] @webApi() def multi(self, actions): return self.anki.multi(actions) @webApi() def storeMediaFile(self, filename, data): return self.anki.storeMediaFile(filename, data) @webApi() def retrieveMediaFile(self, filename): return self.anki.retrieveMediaFile(filename) @webApi() def deleteMediaFile(self, filename): return self.anki.deleteMediaFile(filename) @webApi() def deckNames(self): return self.anki.deckNames() @webApi() def deckNamesAndIds(self): return self.anki.deckNamesAndIds() @webApi() def modelNames(self): return self.anki.modelNames() @webApi() def modelNamesAndIds(self): return self.anki.modelNamesAndIds() @webApi() def modelFieldNames(self, modelName): return self.anki.modelFieldNames(modelName) @webApi() def modelFieldsOnTemplates(self, modelName): return self.anki.modelFieldsOnTemplates(modelName) @webApi() def getDeckConfig(self, deck): return self.anki.getDeckConfig(deck) @webApi() def saveDeckConfig(self, config): return self.anki.saveDeckConfig(config) @webApi() def setDeckConfigId(self, decks, configId): return self.anki.setDeckConfigId(decks, configId) @webApi() def cloneDeckConfigId(self, name, cloneFrom=1): return self.anki.cloneDeckConfigId(name, cloneFrom) @webApi() def removeDeckConfigId(self, configId): return self.anki.removeDeckConfigId(configId) @webApi() def addNote(self, note): params = AnkiNoteParams(note) if params.validate(): return self.anki.addNote(params) @webApi() def addNotes(self, notes): results = [] for note in notes: params = AnkiNoteParams(note) if params.validate(): results.append(self.anki.addNote(params)) else: results.append(None) return results @webApi() def canAddNotes(self, notes): results = [] for note in notes: params = AnkiNoteParams(note) results.append(params.validate() and self.anki.canAddNote(params)) return results @webApi() def addTags(self, notes, tags, add=True): return self.anki.addTags(notes, tags, add) @webApi() def removeTags(self, notes, tags): return self.anki.addTags(notes, tags, False) @webApi() def suspend(self, cards, suspend=True): return self.anki.suspend(cards, suspend) @webApi() def unsuspend(self, cards): return self.anki.suspend(cards, False) @webApi() def areSuspended(self, cards): return self.anki.areSuspended(cards) @webApi() def areDue(self, cards): return self.anki.areDue(cards) @webApi() def getIntervals(self, cards, complete=False): return self.anki.getIntervals(cards, complete) @webApi() def upgrade(self): response = QMessageBox.question(self.anki.window(), 'AnkiConnect', 'Upgrade to the latest version?', QMessageBox.Yes | QMessageBox.No) if response == QMessageBox.Yes: data = download(URL_UPGRADE) if data is None: QMessageBox.critical(self.anki.window(), 'AnkiConnect', 'Failed to download latest version.') else: path = os.path.splitext(__file__)[0] + '.py' with open(path, 'w') as fp: fp.write(makeStr(data)) QMessageBox.information( self.anki.window(), 'AnkiConnect', 'Upgraded to the latest version, please restart Anki.') return True return False @webApi() def version(self): return API_VERSION @webApi() def findNotes(self, query=None): return self.anki.findNotes(query) @webApi() def findCards(self, query=None): return self.anki.findCards(query) @webApi() def getDecks(self, cards): return self.anki.getDecks(cards) @webApi() def changeDeck(self, cards, deck): return self.anki.changeDeck(cards, deck) @webApi() def deleteDecks(self, decks, cardsToo=False): return self.anki.deleteDecks(decks, cardsToo) @webApi() def cardsToNotes(self, cards): return self.anki.cardsToNotes(cards) @webApi() def guiBrowse(self, query=None): return self.anki.guiBrowse(query) @webApi() def guiAddCards(self): return self.anki.guiAddCards() @webApi() def guiCurrentCard(self): return self.anki.guiCurrentCard() @webApi() def guiStartCardTimer(self): return self.anki.guiStartCardTimer() @webApi() def guiAnswerCard(self, ease): return self.anki.guiAnswerCard(ease) @webApi() def guiShowQuestion(self): return self.anki.guiShowQuestion() @webApi() def guiShowAnswer(self): return self.anki.guiShowAnswer() @webApi() def guiDeckOverview(self, name): return self.anki.guiDeckOverview(name) @webApi() def guiDeckBrowser(self): return self.anki.guiDeckBrowser() @webApi() def guiDeckReview(self, name): return self.anki.guiDeckReview(name) @webApi() def guiExitAnki(self): return self.anki.guiExitAnki()
def __init__(self, *args): PluginBase.__init__(self, BrickletPiezoSpeaker, *args) self.ps = self.device self.qtcb_beep_finished.connect(self.cb_beep) self.ps.register_callback(self.ps.CALLBACK_BEEP_FINISHED, self.qtcb_beep_finished.emit) self.qtcb_morse_finished.connect(self.cb_morse) self.ps.register_callback(self.ps.CALLBACK_MORSE_CODE_FINISHED, self.qtcb_morse_finished.emit) self.has_stoppable_beep = self.firmware_version >= (2, 0, 2) self.frequency_label = QLabel('Frequency (585 - 7100 Hz):') self.frequency_box = QSpinBox() self.frequency_box.setMinimum(585) self.frequency_box.setMaximum(7100) self.frequency_box.setValue(1000) self.frequency_layout = QHBoxLayout() self.frequency_layout.addWidget(self.frequency_label) self.frequency_layout.addWidget(self.frequency_box) self.frequency_layout.addStretch() self.beep_box = QSpinBox() self.beep_box.setMinimum(0) self.beep_box.setMaximum(2147483647) self.beep_box.setValue(1000) self.beep_box.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.beep_label = QLabel('Duration [ms]:') self.beep_button = QPushButton('Send Beep') self.beep_layout = QHBoxLayout() self.beep_layout.addWidget(self.beep_label) self.beep_layout.addWidget(self.beep_box) self.beep_layout.addWidget(self.beep_button) self.morse_edit = QLineEdit() self.morse_edit.setText('- .. -. -.- . .-. ..-. --- .-. --. .') self.morse_edit.setMaxLength(60) self.morse_label = QLabel('Morse Code:') self.morse_button = QPushButton('Send Morse Code') self.morse_layout = QHBoxLayout() self.morse_layout.addWidget(self.morse_label) self.morse_layout.addWidget(self.morse_edit) self.morse_layout.addWidget(self.morse_button) self.calibrate_button = QPushButton('Calibrate') self.scale_button = QPushButton('Play Scale') self.scale_layout = QHBoxLayout() self.scale_layout.addWidget(self.scale_button) self.scale_layout.addWidget(self.calibrate_button) self.scale_layout.addStretch() self.scale_timer = QTimer() self.scale_timer.setInterval(25) self.scale_time = 585 self.status_label = QLabel('Status: Idle') self.beep_button.clicked.connect(self.beep_clicked) self.morse_button.clicked.connect(self.morse_clicked) self.scale_button.clicked.connect(self.scale_clicked) self.scale_timer.timeout.connect(self.scale_timeout) self.calibrate_button.clicked.connect(self.calibrate_clicked) layout = QVBoxLayout(self) layout.addLayout(self.frequency_layout) layout.addLayout(self.beep_layout) layout.addLayout(self.morse_layout) layout.addLayout(self.scale_layout) layout.addWidget(self.status_label) layout.addStretch()
class QsciEditor(TextEditBaseWidget): """ QScintilla Base Editor Widget """ LEXERS = { ('py', 'pyw', 'python'): (QsciLexerPython, '#'), ('f', 'for'): (QsciLexerFortran77, 'c'), ('f90', 'f95', 'f2k'): (QsciLexerFortran, '!'), ('diff', 'patch', 'rej'): (QsciLexerDiff, ''), 'css': (QsciLexerCSS, '#'), ('htm', 'html'): (QsciLexerHTML, ''), ('c', 'cpp', 'h'): (QsciLexerCPP, '//'), ('bat', 'cmd', 'nt'): (QsciLexerBatch, 'rem '), ('properties', 'session', 'ini', 'inf', 'reg', 'url', 'cfg', 'cnf', 'aut', 'iss'): (QsciLexerProperties, '#'), } TAB_ALWAYS_INDENTS = ('py', 'pyw', 'python', 'c', 'cpp', 'h') OCCURENCE_INDICATOR = QsciScintilla.INDIC_CONTAINER EOL_MODES = {"\r\n": QsciScintilla.EolWindows, "\n": QsciScintilla.EolUnix, "\r": QsciScintilla.EolMac} def __init__(self, parent=None): TextEditBaseWidget.__init__(self, parent) # Indicate occurences of the selected word self.connect(self, SIGNAL('cursorPositionChanged(int, int)'), self.__cursor_position_changed) self.__find_start = None self.__find_end = None self.__find_flags = None self.SendScintilla(QsciScintilla.SCI_INDICSETSTYLE, self.OCCURENCE_INDICATOR, QsciScintilla.INDIC_BOX) self.SendScintilla(QsciScintilla.SCI_INDICSETFORE, self.OCCURENCE_INDICATOR, 0x4400FF) self.supported_language = None self.comment_string = None # Mark errors, warnings, ... self.markers = [] self.marker_lines = {} self.error = self.markerDefine(QPixmap(get_image_path('error.png'), 'png')) self.warning = self.markerDefine(QPixmap(get_image_path('warning.png'), 'png')) # Scintilla Python API self.api = None # Mark occurences timer self.occurences_timer = QTimer(self) self.occurences_timer.setSingleShot(True) self.occurences_timer.setInterval(750) self.connect(self.occurences_timer, SIGNAL("timeout()"), self.__mark_occurences) # Context menu self.setup_context_menu() # Tab key behavior self.tab_indents = None self.tab_mode = True # see QsciEditor.set_tab_mode def setup_editor(self, linenumbers=True, language=None, code_analysis=False, code_folding=False, show_eol_chars=False, show_whitespace=False, font=None, wrap=True, tab_mode=True): # Lexer self.set_language(language) # Tab always indents (even when cursor is not at the begin of line) self.tab_indents = language in self.TAB_ALWAYS_INDENTS self.tab_mode = tab_mode if linenumbers: self.connect( self, SIGNAL('linesChanged()'), self.__lines_changed ) self.setup_margins(linenumbers, code_analysis, code_folding) if font is not None: self.set_font(font) # Re-enable brace matching (already enabled in TextEditBaseWidget.setup # but for an unknown reason, changing the 'set_font' call above reset # this setting to default, which is no brace matching): # XXX: find out why self.setBraceMatching(QsciScintilla.SloppyBraceMatch) self.setMatchedBraceBackgroundColor(Qt.yellow) self.set_eol_chars_visible(show_eol_chars) self.set_whitespace_visible(show_whitespace) self.toggle_wrap_mode(wrap) self.setup_api() self.setModified(False) def set_tab_mode(self, enable): """ enabled = tab always indent (otherwise tab indents only when cursor is at the beginning of a line) """ self.tab_mode = enable def set_language(self, language): self.supported_language = False self.comment_string = '' if language is not None: for key in self.LEXERS: if language.lower() in key: self.supported_language = True lexer_class, comment_string = self.LEXERS[key] self.comment_string = comment_string if lexer_class is not None: # Fortran lexers are sometimes unavailable: # the corresponding class is then replaced by None # (see the import lines at the beginning of the script) self.setLexer( lexer_class(self) ) break def is_python(self): return isinstance(self.lexer(), QsciLexerPython) #=============================================================================== # QScintilla #=============================================================================== def setup(self): """Reimplement TextEditBaseWidget method""" TextEditBaseWidget.setup(self) # Wrapping if CONF.get('editor', 'wrapflag'): self.setWrapVisualFlags(QsciScintilla.WrapFlagByBorder) # Indentation self.setIndentationGuides(True) self.setIndentationGuidesForegroundColor(Qt.lightGray) # 80-columns edge self.setEdgeColumn(80) self.setEdgeMode(QsciScintilla.EdgeLine) # Auto-completion self.setAutoCompletionSource(QsciScintilla.AcsAll) def setup_margins(self, linenumbers=True, code_analysis=False, code_folding=False): """ Setup margin settings (except font, now set in self.set_font) """ for i_margin in range(5): # Reset margin settings self.setMarginWidth(i_margin, 0) self.setMarginLineNumbers(i_margin, False) self.setMarginMarkerMask(i_margin, 0) self.setMarginSensitivity(i_margin, False) if linenumbers: # 1: Line numbers margin self.setMarginLineNumbers(1, True) self.update_line_numbers_margin() if code_analysis: # 2: Errors/warnings margin mask = (1 << self.error) | (1 << self.warning) self.setMarginSensitivity(0, True) self.setMarginMarkerMask(0, mask) self.setMarginWidth(0, 14) self.connect(self, SIGNAL('marginClicked(int,int,Qt::KeyboardModifiers)'), self.__margin_clicked) if code_folding: # 0: Folding margin self.setMarginWidth(2, 14) self.setFolding(QsciScintilla.BoxedFoldStyle) # Colors fcol = CONF.get('scintilla', 'margins/foregroundcolor') bcol = CONF.get('scintilla', 'margins/backgroundcolor') if fcol: self.setMarginsForegroundColor(QColor(fcol)) if bcol: self.setMarginsBackgroundColor(QColor(bcol)) fcol = CONF.get('scintilla', 'foldmarginpattern/foregroundcolor') bcol = CONF.get('scintilla', 'foldmarginpattern/backgroundcolor') if fcol and bcol: self.setFoldMarginColors(QColor(fcol), QColor(bcol)) def setup_api(self): """Load and prepare API""" if self.lexer() is None: return self.api = QsciAPIs(self.lexer()) is_api_ready = False api_path = CONF.get('editor', 'api') if not os.path.isfile(api_path): return False api_stat = CONF.get('editor', 'api_stat', None) current_api_stat = os.stat(api_path) if (api_stat is not None) and (api_stat == current_api_stat): if self.api.isPrepared(): is_api_ready = self.api.loadPrepared() else: CONF.set('editor', 'api_stat', current_api_stat) if not is_api_ready: if self.api.load(api_path): self.api.prepare() self.connect(self.api, SIGNAL("apiPreparationFinished()"), self.api.savePrepared) return is_api_ready def set_whitespace_visible(self, state): """Show/hide whitespace""" if state: self.setWhitespaceVisibility(QsciScintilla.WsVisible) else: self.setWhitespaceVisibility(QsciScintilla.WsInvisible) def set_eol_chars_visible(self, state): """Show/hide EOL characters""" self.setEolVisibility(state) def convert_eol_chars(self): """Convert EOL characters to current mode""" self.convertEols(self.eolMode()) def remove_trailing_spaces(self): """Remove trailing spaces""" text_before = unicode(self.text()) text_after = sourcecode.remove_trailing_spaces(text_before) if text_before != text_after: self.setText(text_after) def fix_indentation(self): """Replace tabs by spaces""" text_before = unicode(self.text()) text_after = sourcecode.fix_indentation(text_before) if text_before != text_after: self.setText(text_after) def set_eol_mode(self, text): """ Set QScintilla widget EOL mode based on *text* EOL characters """ if isinstance(text, QString): text = unicode(text) eol_chars = sourcecode.get_eol_chars(text) if eol_chars is not None: self.setEolMode(self.EOL_MODES[eol_chars]) def get_line_separator(self): """Return line separator based on current EOL mode""" current_mode = self.eolMode() for eol_chars, mode in self.EOL_MODES.iteritems(): if current_mode == mode: return eol_chars else: return '' def __find_first(self, text): """Find first occurence""" self.__find_flags = QsciScintilla.SCFIND_MATCHCASE | \ QsciScintilla.SCFIND_WHOLEWORD self.__find_start = 0 line = self.lines()-1 self.__find_end = self.position_from_lineindex(line, self.text(line).length()) return self.__find_next(text) def __find_next(self, text): """Find next occurence""" if self.__find_start == self.__find_end: return False self.SendScintilla(QsciScintilla.SCI_SETTARGETSTART, self.__find_start) self.SendScintilla(QsciScintilla.SCI_SETTARGETEND, self.__find_end) self.SendScintilla(QsciScintilla.SCI_SETSEARCHFLAGS, self.__find_flags) pos = self.SendScintilla(QsciScintilla.SCI_SEARCHINTARGET, len(text), text) if pos == -1: return False self.__find_start = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND) return True def __get_found_occurence(self): """Return found occurence""" spos = self.SendScintilla(QsciScintilla.SCI_GETTARGETSTART) epos = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND) return (spos, epos - spos) def __cursor_position_changed(self): """Cursor position has changed""" #TODO: Add attribute for occurences marking enable/disable: # if self.occurences_marking: self.occurences_timer.stop() self.occurences_timer.start() def __mark_occurences(self): """Marking occurences of the currently selected word""" self.SendScintilla(QsciScintilla.SCI_SETINDICATORCURRENT, self.OCCURENCE_INDICATOR) self.SendScintilla(QsciScintilla.SCI_INDICATORCLEARRANGE, 0, self.length()) if not self.supported_language: return text = self.get_current_word() if text.isEmpty(): return # Highlighting all occurences of word *text* ok = self.__find_first(text) while ok: spos = self.SendScintilla(QsciScintilla.SCI_GETTARGETSTART) epos = self.SendScintilla(QsciScintilla.SCI_GETTARGETEND) self.SendScintilla(QsciScintilla.SCI_INDICATORFILLRANGE, spos, epos-spos) ok = self.__find_next(text) def __lines_changed(self): """Update margin""" self.update_line_numbers_margin() def update_line_numbers_margin(self): """Update margin width""" width = log(self.lines(), 10) + 2 self.setMarginWidth(1, QString('0'*int(width))) def delete(self): """Remove selected text""" # Used by global callbacks in Spyder -> delete_action QsciScintilla.removeSelectedText(self) def set_font(self, font): """Set shell font""" if self.lexer() is None: self.setFont(font) else: self.lexer().setFont(font) self.setLexer(self.lexer()) self.setMarginsFont(font) def set_text(self, text): """Set the text of the editor""" self.setText(text) self.set_eol_mode(text) def get_text(self): """Return editor text""" return self.text() def paste(self): """ Reimplement QsciScintilla's method to fix the following issue: on Windows, pasted text has only 'LF' EOL chars even if the original text has 'CRLF' EOL chars """ clipboard = QApplication.clipboard() text = unicode(clipboard.text()) if len(text.splitlines()) > 1: eol_chars = self.get_line_separator() clipboard.setText( eol_chars.join((text+eol_chars).splitlines()) ) # Standard paste TextEditBaseWidget.paste(self) def fold_header(self, line): """Is it a fold header line?""" lvl = self.SendScintilla(QsciScintilla.SCI_GETFOLDLEVEL, line) return lvl & QsciScintilla.SC_FOLDLEVELHEADERFLAG def fold_expanded(self, line): """Is fold expanded?""" return self.SendScintilla(QsciScintilla.SCI_GETFOLDEXPANDED, line) def get_folded_lines(self): """Return the list of folded line numbers""" return [line for line in xrange(self.lines()) \ if self.fold_header(line) and not self.fold_expanded(line) ] def unfold_all(self): """Unfold all folded lines""" for line in self.get_folded_lines(): self.foldLine(line) #=============================================================================== # High-level editor features #=============================================================================== def highlight_line(self, line): """Highlight line number *line*""" text = unicode(self.text(line-1)).rstrip() self.setSelection(line-1, len(text), line-1, 0) self.ensureLineVisible(line-1) def cleanup_code_analysis(self): """Remove all code analysis markers""" for marker in self.markers: self.markerDeleteHandle(marker) self.markers = [] self.marker_lines = {} def process_code_analysis(self, check_results): """Analyze filename code with pyflakes""" self.cleanup_code_analysis() if check_results is None: # Not able to compile module return for message, line0, error in check_results: line1 = line0 - 1 marker = self.markerAdd(line1, 0 if error else 1) self.markers.append(marker) if line1 not in self.marker_lines: self.marker_lines[line1] = [] self.marker_lines[line1].append( (message, error) ) def __highlight_warning(self, line): self.highlight_line(line+1) self.__show_code_analysis_results(line) def go_to_next_warning(self): """Go to next code analysis warning message""" cline, _ = self.getCursorPosition() lines = sorted(self.marker_lines.keys()) for line in lines: if line > cline: self.__highlight_warning(line) return else: self.__highlight_warning(lines[0]) def go_to_previous_warning(self): """Go to previous code analysis warning message""" cline, _ = self.getCursorPosition() lines = sorted(self.marker_lines.keys(), reverse=True) for line in lines: if line < cline: self.__highlight_warning(line) return else: self.__highlight_warning(lines[0]) def __show_code_analysis_results(self, line): """Show warning/error messages""" if line in self.marker_lines: msglist = [ msg for msg, _error in self.marker_lines[line] ] self.show_calltip(self.tr("Code analysis"), msglist, color='#129625', at_line=line) def __margin_clicked(self, margin, line, modifier): """Margin was clicked, that's for sure!""" if margin == 0: self.__show_code_analysis_results(line) def mouseMoveEvent(self, event): line = self.get_line_number_at(event.pos()) self.__show_code_analysis_results(line) QsciScintilla.mouseMoveEvent(self, event) def add_prefix(self, prefix): """Add prefix to current line or selected line(s)""" if self.hasSelectedText(): # Add prefix to selected line(s) line_from, index_from, line_to, index_to = self.getSelection() if index_to == 0: line_to -= 1 self.beginUndoAction() for line in range(line_from, line_to+1): self.insertAt(prefix, line, 0) self.endUndoAction() if index_to == 0: line_to += 1 else: index_to += len(prefix) self.setSelection(line_from, index_from+len(prefix), line_to, index_to) else: # Add prefix to current line line, index = self.getCursorPosition() self.beginUndoAction() self.insertAt(prefix, line, 0) self.endUndoAction() self.setCursorPosition(line, index+len(prefix)) def remove_prefix(self, prefix): """Remove prefix from current line or selected line(s)""" if self.hasSelectedText(): # Remove prefix from selected line(s) line_from, index_from, line_to, index_to = self.getSelection() if index_to == 0: line_to -= 1 self.beginUndoAction() for line in range(line_from, line_to+1): if not self.text(line).startsWith(prefix): continue self.setSelection(line, 0, line, len(prefix)) self.removeSelectedText() if line == line_from: index_from = max([0, index_from-len(prefix)]) if line == line_to and index_to != 0: index_to = max([0, index_to-len(prefix)]) if index_to == 0: line_to += 1 self.setSelection(line_from, index_from, line_to, index_to) self.endUndoAction() else: # Remove prefix from current line line, index = self.getCursorPosition() if not self.text(line).startsWith(prefix): return self.beginUndoAction() self.setSelection(line, 0, line, len(prefix)) self.removeSelectedText() self.setCursorPosition(line, index-len(prefix)) self.endUndoAction() self.setCursorPosition(line, max([0, index-len(prefix)])) def fix_indent(self, forward=True): """ Fix indentation (Python only, no text selection) forward=True: fix indent only if text is not enough indented (otherwise force indent) forward=False: fix indent only if text is too much indented (otherwise force unindent) """ if not self.is_python(): return line, index = self.getCursorPosition() prevtext = unicode(self.text(line-1)).rstrip() indent = self.indentation(line) correct_indent = self.indentation(line-1) if prevtext.endswith(':'): # Indent correct_indent += 4 elif prevtext.endswith('continue') or prevtext.endswith('break'): # Unindent correct_indent -= 4 elif prevtext.endswith(','): rlmap = {")":"(", "]":"[", "}":"{"} for par in rlmap: i_right = prevtext.rfind(par) if i_right != -1: prevtext = prevtext[:i_right] i_left = prevtext.rfind(rlmap[par]) if i_left != -1: prevtext = prevtext[:i_left] else: break else: prevexpr = re.split(r'\(|\{|\[', prevtext)[-1] correct_indent = len(prevtext)-len(prevexpr) if forward: if indent == correct_indent or indent > correct_indent: # Force indent correct_indent = indent + 4 elif indent == correct_indent or indent < correct_indent: # Force unindent correct_indent = indent - 4 if correct_indent >= 0: self.beginUndoAction() self.setSelection(line, 0, line, indent) self.removeSelectedText() if index > indent: index -= indent-correct_indent else: index = correct_indent self.insertAt(" "*correct_indent, line, 0) self.setCursorPosition(line, index) self.endUndoAction() def __no_char_before_cursor(self): line, index = self.getCursorPosition() self.setSelection(line, 0, line, index) selected_text = unicode(self.selectedText()) self.clear_selection() return len(selected_text.strip()) == 0 def indent(self): """Indent current line or selection""" if self.hasSelectedText(): self.add_prefix( " "*4 ) elif self.__no_char_before_cursor() or \ (self.tab_indents and self.tab_mode): if self.is_python(): self.fix_indent(forward=True) else: self.add_prefix( " "*4 ) else: self.SendScintilla(QsciScintilla.SCI_TAB) def unindent(self): """Unindent current line or selection""" if self.hasSelectedText(): self.remove_prefix( " "*4 ) elif self.__no_char_before_cursor() or \ (self.tab_indents and self.tab_mode): if self.is_python(): self.fix_indent(forward=False) else: self.remove_prefix( " "*4 ) def comment(self): """Comment current line or selection""" self.add_prefix(self.comment_string) def uncomment(self): """Uncomment current line or selection""" self.remove_prefix(self.comment_string) def blockcomment(self): """Block comment current line or selection""" comline = self.comment_string + '='*(80-len(self.comment_string)) \ + self.get_line_separator() if self.hasSelectedText(): line_from, _index_from, line_to, _index_to = self.getSelection() lines = range(line_from, line_to+1) else: line, _index = self.getCursorPosition() lines = [line] self.beginUndoAction() self.insertAt( comline, lines[-1]+1, 0 ) self.insertAt( comline, lines[0], 0 ) for l in lines: self.insertAt( '# ', l+1, 0 ) self.endUndoAction() self.setCursorPosition(lines[-1]+2, 80) def __is_comment_bar(self, line): comline = '#' + '='*79 + self.get_line_separator() self.setSelection(line, 0, line+1, 0) return unicode(self.selectedText()) == comline def unblockcomment(self): """Un-block comment current line or selection""" line, index = self.getCursorPosition() self.setSelection(line, 0, line, 1) if unicode(self.selectedText()) != '#': self.setCursorPosition(line, index) return # Finding first comment bar line1 = line-1 while line1 >= 0 and not self.__is_comment_bar(line1): line1 -= 1 if not self.__is_comment_bar(line1): self.setCursorPosition(line, index) return # Finding second comment bar line2 = line+1 while line2 < self.lines() and not self.__is_comment_bar(line2): line2 += 1 if not self.__is_comment_bar(line2) or line2 > self.lines()-2: self.setCursorPosition(line, index) return lines = range(line1+1, line2) self.beginUndoAction() self.setSelection(line2, 0, line2+1, 0) self.removeSelectedText() for l in lines: self.setSelection(l, 0, l, 2) self.removeSelectedText() self.setSelection(line1, 0, line1+1, 0) self.removeSelectedText() self.endUndoAction() #=============================================================================== # Qt Event handlers #=============================================================================== def setup_context_menu(self): """Setup context menu""" self.undo_action = create_action(self, translate("SimpleEditor", "Undo"), shortcut=keybinding('Undo'), icon=get_icon('undo.png'), triggered=self.undo) self.redo_action = create_action(self, translate("SimpleEditor", "Redo"), shortcut=keybinding('Redo'), icon=get_icon('redo.png'), triggered=self.redo) self.cut_action = create_action(self, translate("SimpleEditor", "Cut"), shortcut=keybinding('Cut'), icon=get_icon('editcut.png'), triggered=self.cut) self.copy_action = create_action(self, translate("SimpleEditor", "Copy"), shortcut=keybinding('Copy'), icon=get_icon('editcopy.png'), triggered=self.copy) paste_action = create_action(self, translate("SimpleEditor", "Paste"), shortcut=keybinding('Paste'), icon=get_icon('editpaste.png'), triggered=self.paste) self.delete_action = create_action(self, translate("SimpleEditor", "Delete"), shortcut=keybinding('Delete'), icon=get_icon('editdelete.png'), triggered=self.removeSelectedText) selectall_action = create_action(self, translate("SimpleEditor", "Select all"), shortcut=keybinding('SelectAll'), icon=get_icon('selectall.png'), triggered=self.selectAll) self.menu = QMenu(self) add_actions(self.menu, (self.undo_action, self.redo_action, None, self.cut_action, self.copy_action, paste_action, self.delete_action, None, selectall_action)) # Read-only context-menu self.readonly_menu = QMenu(self) add_actions(self.readonly_menu, (self.copy_action, None, selectall_action)) def keyPressEvent(self, event): """Reimplement Qt method""" key = event.key() ctrl = event.modifiers() & Qt.ControlModifier shift = event.modifiers() & Qt.ShiftModifier # Zoom in/out if ((key == Qt.Key_Plus) and ctrl) \ or ((key==Qt.Key_Equal) and shift and ctrl): self.zoomIn() event.accept() elif (key == Qt.Key_Minus) and ctrl: self.zoomOut() event.accept() # Indent/unindent elif key == Qt.Key_Backtab: self.unindent() event.accept() elif (key == Qt.Key_Tab): if self.is_completion_widget_visible(): self.SendScintilla(QsciScintilla.SCI_TAB) else: self.indent() event.accept() elif (key == Qt.Key_V) and ctrl: self.paste() event.accept() #TODO: find other shortcuts... # elif (key == Qt.Key_3) and ctrl: # self.comment() # event.accept() # elif (key == Qt.Key_2) and ctrl: # self.uncomment() # event.accept() # elif (key == Qt.Key_4) and ctrl: # self.blockcomment() # event.accept() # elif (key == Qt.Key_5) and ctrl: # self.unblockcomment() # event.accept() else: QsciScintilla.keyPressEvent(self, event) def mousePressEvent(self, event): """Reimplement Qt method""" if event.button() == Qt.MidButton: self.setFocus() event = QMouseEvent(QEvent.MouseButtonPress, event.pos(), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) QsciScintilla.mousePressEvent(self, event) QsciScintilla.mouseReleaseEvent(self, event) self.paste() else: QsciScintilla.mousePressEvent(self, event) def contextMenuEvent(self, event): """Reimplement Qt method""" state = self.hasSelectedText() self.copy_action.setEnabled(state) self.cut_action.setEnabled(state) self.delete_action.setEnabled(state) self.undo_action.setEnabled( self.isUndoAvailable() ) self.redo_action.setEnabled( self.isRedoAvailable() ) menu = self.menu if self.isReadOnly(): menu = self.readonly_menu menu.popup(event.globalPos()) event.accept()
def __init__(self, List, *__args): super(EQApplication, self).__init__(List, *__args) self.timer = QTimer() self.timer.start(50) # You may change this if you wish. self.timer.timeout.connect(self.ui_loop)
class EventEngine(object): # ---------------------------------------------------------------------- def __init__(self): """初始化事件引擎""" # 事件队列 self.__queue = Queue() # 事件引擎开关 self.__active = False # 事件处理线程 self.__thread = Thread(target=self.__run) # 计时器,用于触发计时器事件 self.__timer = QTimer() self.__timer.timeout.connect(self.__onTimer) # 这里的__handlers是一个字典,用来保存对应的事件调用关系 # 其中每个键对应的值是一个列表,列表中保存了对该事件进行监听的函数功能 self.__handlers = defaultdict(list) # ---------------------------------------------------------------------- def __run(self): """引擎运行""" while self.__active == True: try: event = self.__queue.get(block=True, timeout=1) # 获取事件的阻塞时间设为1秒 self.__process(event) except Empty: pass # ---------------------------------------------------------------------- def __process(self, event): """处理事件""" # 检查是否存在对该事件进行监听的处理函数 if event.type_ in self.__handlers: # 若存在,则按顺序将事件传递给处理函数执行 [handler(event) for handler in self.__handlers[event.type_]] # ---------------------------------------------------------------------- def __onTimer(self): """向事件队列中存入计时器事件""" # 创建计时器事件 event_ = Event(type_=EVENT_TIMER) # 向队列中存入计时器事件 self.put(event_) # ---------------------------------------------------------------------- def start(self): """引擎启动""" # 将引擎设为启动 self.__active = True # 启动事件处理线程 self.__thread.start() # 启动计时器,计时器事件间隔默认设定为1秒 self.__timer.start(1000) # ---------------------------------------------------------------------- def stop(self): """停止引擎""" # 将引擎设为停止 self.__active = False # 停止计时器 self.__timer.stop() # 等待事件处理线程退出 self.__thread.join() # ---------------------------------------------------------------------- def register(self, type_, handler): """注册事件处理函数监听""" # 尝试获取该事件类型对应的处理函数列表,若无defaultDict会自动创建新的list handlerList = self.__handlers[type_] # 若要注册的处理器不在该事件的处理器列表中,则注册该事件 if handler not in handlerList: handlerList.append(handler) # ---------------------------------------------------------------------- def unregister(self, type_, handler): """注销事件处理函数监听""" # 尝试获取该事件类型对应的处理函数列表,若无则忽略该次注销请求 handlerList = self.__handlers[type_] # 如果该函数存在于列表中,则移除 if handler in handlerList: handlerList.remove(handler) # 如果函数列表为空,则从引擎中移除该事件类型 if not handlerList: del self.__handlers[type_] # ---------------------------------------------------------------------- def put(self, event): """向事件队列中存入事件""" self.__queue.put(event)
class BrushingInterpreter(QObject): # states FINAL = 0 DEFAULT_MODE = 1 # FIXME: This state isn't really needed, now that we use a QTimer to manage the double-click case. # (The state machine should be rewritten.) MAYBE_DRAW_MODE = 2 #received a single left-click; however, the next event #might be a double-click event; therefore the state has #not been decided yet DRAW_MODE = 3 @property def state(self): return self._current_state def __init__(self, navigationController, brushingController): QObject.__init__(self) self._navCtrl = navigationController self._navIntr = NavigationInterpreter(navigationController) self._brushingCtrl = brushingController self._current_state = self.FINAL self._temp_erasing = False # indicates, if user pressed shift # for temporary erasing (in # contrast to selecting the eraser brush) self._lineItems = [] # list of line items that have been # added to the qgraphicsscene for drawing indication self._lastEvent = None self._doubleClickTimer = None # clear the temporary line items once they # have been pushed to the sink self._brushingCtrl.wroteToSink.connect(self.clearLines) def start(self): if self._current_state == self.FINAL: self._navIntr.start() self._current_state = self.DEFAULT_MODE else: pass # ignore def stop(self): if self._brushingCtrl._isDrawing: for imageview in self._navCtrl._views: self._brushingCtrl.endDrawing(imageview.mousePos) self._current_state = self.FINAL self._navIntr.stop() def eventFilter(self, watched, event): etype = event.type() # Before we steal this event from the scene, check that it is allowing brush strokes allow_brushing = True for view in self._navCtrl._views: allow_brushing &= view.scene().allow_brushing if not allow_brushing: return self._navIntr.eventFilter(watched, event) if etype == QEvent.MouseButtonDblClick and self._doubleClickTimer is not None: # On doubleclick, cancel release handler that normally draws the stroke. self._doubleClickTimer.stop() self._doubleClickTimer = None self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, event) if self._current_state == self.DEFAULT_MODE: if etype == QEvent.MouseButtonPress \ and event.button() == Qt.LeftButton \ and event.modifiers() == Qt.NoModifier \ and self._navIntr.mousePositionValid(watched, event): ### default mode -> maybe draw mode self._current_state = self.MAYBE_DRAW_MODE # event will not be valid to use after this function exits, # so we must make a copy of it instead of just saving the pointer self._lastEvent = QMouseEvent(event.type(), event.pos(), event.globalPos(), event.button(), event.buttons(), event.modifiers()) elif self._current_state == self.MAYBE_DRAW_MODE: if etype == QEvent.MouseMove: # navigation interpreter also has to be in # default mode to avoid inconsistencies if self._navIntr.state == self._navIntr.DEFAULT_MODE: ### maybe draw mode -> maybe draw mode self._current_state = self.DRAW_MODE self.onEntry_draw(watched, self._lastEvent) self.onMouseMove_draw(watched, event) return True else: self._navIntr.eventFilter(watched, self._lastEvent) return self._navIntr.eventFilter(watched, event) elif etype == QEvent.MouseButtonDblClick: ### maybe draw mode -> default mode self._current_state = self.DEFAULT_MODE return self._navIntr.eventFilter(watched, event) elif etype == QEvent.MouseButtonRelease: def handleRelease(releaseEvent): self._current_state = self.DRAW_MODE self.onEntry_draw(watched, self._lastEvent) self.onExit_draw(watched, releaseEvent) self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, releaseEvent) # If this event is part of a double-click, we don't really want to handle it. # Typical event sequence is press, release, double-click (not two presses). # Instead of handling this right away, set a timer to do the work. # We'll cancel the timer if we see a double-click event (see above). self._doubleClickTimer = QTimer(self) self._doubleClickTimer.setInterval(200) self._doubleClickTimer.setSingleShot(True) # event will not be valid to use after this function exits, # so we must make a copy of it instead of just saving the pointer eventCopy = QMouseEvent(event.type(), event.pos(), event.button(), event.buttons(), event.modifiers()) self._doubleClickTimer.timeout.connect( partial(handleRelease, eventCopy)) self._doubleClickTimer.start() return True elif self._current_state == self.DRAW_MODE: if etype == QEvent.MouseButtonRelease and event.button( ) == Qt.LeftButton: self.onExit_draw(watched, event) ### draw mode -> default mode self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, event) return True elif etype == QEvent.MouseMove and event.buttons() & Qt.LeftButton: if self._navIntr.mousePositionValid(watched, event): self.onMouseMove_draw(watched, event) return True else: self.onExit_draw(watched, event) ### draw mode -> default mode self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, event) # let the navigation interpreter handle common events return self._navIntr.eventFilter(watched, event) ### ### Default Mode ### def onEntry_default(self, imageview, event): pass ### ### Draw Mode ### def onEntry_draw(self, imageview, event): if QApplication.keyboardModifiers() == Qt.ShiftModifier: self._brushingCtrl._brushingModel.setErasing() self._temp_erasing = True imageview.mousePos = imageview.mapScene2Data( imageview.mapToScene(event.pos())) self._brushingCtrl.beginDrawing(imageview, imageview.mousePos) def onExit_draw(self, imageview, event): self._brushingCtrl.endDrawing(imageview.mousePos) if self._temp_erasing: self._brushingCtrl._brushingModel.disableErasing() self._temp_erasing = False def onMouseMove_draw(self, imageview, event): self._navIntr.onMouseMove_default(imageview, event) o = imageview.scene().data2scene.map( QPointF(imageview.oldX, imageview.oldY)) n = imageview.scene().data2scene.map(QPointF(imageview.x, imageview.y)) # Draw temporary line for the brush stroke so the user gets feedback before the data is really updated. pen = QPen(QBrush(self._brushingCtrl._brushingModel.drawColor), self._brushingCtrl._brushingModel.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin) line = QGraphicsLineItem(o.x(), o.y(), n.x(), n.y()) line.setPen(pen) imageview.scene().addItem(line) line.setParentItem(imageview.scene().dataRectItem) self._lineItems.append(line) self._brushingCtrl._brushingModel.moveTo(imageview.mousePos) def clearLines(self): # This is called after the brush stroke is stored to the data. # Our temporary line object is no longer needed because the data provides the true pixel labels that were stored. lines = self._lineItems self._lineItems = [] for l in lines: l.hide() def updateCursorPosition(self, *args, **kwargs): self._navIntr.updateCursorPosition(*args, **kwargs)
class PiezoSpeaker(PluginBase): qtcb_beep_finished = pyqtSignal() qtcb_morse_finished = pyqtSignal() def __init__(self, *args): PluginBase.__init__(self, BrickletPiezoSpeaker, *args) self.ps = self.device self.qtcb_beep_finished.connect(self.cb_beep) self.ps.register_callback(self.ps.CALLBACK_BEEP_FINISHED, self.qtcb_beep_finished.emit) self.qtcb_morse_finished.connect(self.cb_morse) self.ps.register_callback(self.ps.CALLBACK_MORSE_CODE_FINISHED, self.qtcb_morse_finished.emit) self.has_stoppable_beep = self.firmware_version >= (2, 0, 2) self.frequency_label = QLabel('Frequency (585 - 7100 Hz):') self.frequency_box = QSpinBox() self.frequency_box.setMinimum(585) self.frequency_box.setMaximum(7100) self.frequency_box.setValue(1000) self.frequency_layout = QHBoxLayout() self.frequency_layout.addWidget(self.frequency_label) self.frequency_layout.addWidget(self.frequency_box) self.frequency_layout.addStretch() self.beep_box = QSpinBox() self.beep_box.setMinimum(0) self.beep_box.setMaximum(2147483647) self.beep_box.setValue(1000) self.beep_box.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.beep_label = QLabel('Duration [ms]:') self.beep_button = QPushButton('Send Beep') self.beep_layout = QHBoxLayout() self.beep_layout.addWidget(self.beep_label) self.beep_layout.addWidget(self.beep_box) self.beep_layout.addWidget(self.beep_button) self.morse_edit = QLineEdit() self.morse_edit.setText('- .. -. -.- . .-. ..-. --- .-. --. .') self.morse_edit.setMaxLength(60) self.morse_label = QLabel('Morse Code:') self.morse_button = QPushButton('Send Morse Code') self.morse_layout = QHBoxLayout() self.morse_layout.addWidget(self.morse_label) self.morse_layout.addWidget(self.morse_edit) self.morse_layout.addWidget(self.morse_button) self.calibrate_button = QPushButton('Calibrate') self.scale_button = QPushButton('Play Scale') self.scale_layout = QHBoxLayout() self.scale_layout.addWidget(self.scale_button) self.scale_layout.addWidget(self.calibrate_button) self.scale_layout.addStretch() self.scale_timer = QTimer() self.scale_timer.setInterval(25) self.scale_time = 585 self.status_label = QLabel('Status: Idle') self.beep_button.clicked.connect(self.beep_clicked) self.morse_button.clicked.connect(self.morse_clicked) self.scale_button.clicked.connect(self.scale_clicked) self.scale_timer.timeout.connect(self.scale_timeout) self.calibrate_button.clicked.connect(self.calibrate_clicked) layout = QVBoxLayout(self) layout.addLayout(self.frequency_layout) layout.addLayout(self.beep_layout) layout.addLayout(self.morse_layout) layout.addLayout(self.scale_layout) layout.addWidget(self.status_label) layout.addStretch() def start(self): pass def stop(self): pass def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletPiezoSpeaker.DEVICE_IDENTIFIER def cb_beep(self): self.beep_button.setDisabled(False) self.morse_button.setDisabled(False) self.scale_button.setDisabled(False) self.status_label.setText('Status: Idle') def cb_morse(self): self.beep_button.setDisabled(False) self.morse_button.setDisabled(False) self.scale_button.setDisabled(False) self.status_label.setText('Status: Idle') def calibrate_clicked(self): self.status_label.setText('Status: Calibrating...') self.status_label.repaint() QApplication.processEvents() self.ps.calibrate() self.status_label.setText('Status: New calibration stored in EEPROM') def scale_timeout(self): try: self.status_label.setText(str(self.scale_time) + 'Hz') self.ps.beep(40, self.scale_time) except ip_connection.Error: return self.scale_time += 50 if self.scale_time > 7100: self.scale_time = 585 self.scale_timer.stop() def scale_clicked(self): self.scale_time = 585 self.scale_timeout() self.scale_timer.start() self.beep_button.setDisabled(True) self.morse_button.setDisabled(True) self.scale_button.setDisabled(True) def beep_clicked(self): freq = self.frequency_box.value() duration = self.beep_box.value() try: self.ps.beep(duration, freq) except ip_connection.Error: return if duration > 0 or not self.has_stoppable_beep: self.beep_button.setDisabled(True) self.morse_button.setDisabled(True) self.scale_button.setDisabled(True) self.status_label.setText('Status: Beeping...') def morse_clicked(self): freq = self.frequency_box.value() morse = self.morse_edit.text() try: self.ps.morse_code(morse, freq) except ip_connection.Error: return self.beep_button.setDisabled(True) self.morse_button.setDisabled(True) self.scale_button.setDisabled(True) self.status_label.setText('Status: Beeping...')
class generator(QMdiSubWindow): def __init__(self, parent=None): super(generator, self).__init__(parent) self.parent = parent self.setFixedSize(670, 580) self.frame = QtGui.QFrame(self) self.frame.setGeometry(QtCore.QRect(340, 430, 321, 131)) self.frame.setFrameShape(QtGui.QFrame.StyledPanel) self.frame.setFrameShadow(QtGui.QFrame.Raised) self.frame.setObjectName(_fromUtf8("frame")) self.checkBox_4 = QtGui.QCheckBox(self.frame) self.checkBox_4.setEnabled(False) self.checkBox_4.setGeometry(QtCore.QRect(5, 5, 221, 25)) self.checkBox_4.setCheckable(True) self.checkBox_4.setObjectName(_fromUtf8("checkBox_4")) self.genPass = QtGui.QPushButton(self.frame) self.genPass.setGeometry(QtCore.QRect(65, 90, 181, 28)) self.genPass.setObjectName(_fromUtf8("genPass")) self.genPass.clicked.connect(self.strongPassword) self.genAPass = QtGui.QPushButton(self.frame) self.genAPass.setGeometry(QtCore.QRect(65, 62, 181, 28)) self.genAPass.setObjectName(_fromUtf8("genAPass")) self.genAPass.clicked.connect(self.randomAPass) self.label_5 = QtGui.QLabel(self.frame) self.label_5.setGeometry(QtCore.QRect(10, 35, 131, 20)) self.label_5.setObjectName(_fromUtf8("label_5")) self.prCombo2 = QtGui.QComboBox(self.frame) self.prCombo2.setGeometry(QtCore.QRect(145, 30, 141, 30)) self.prCombo2.setObjectName(_fromUtf8("prCombo2")) self.prCombo2.addItem(_fromUtf8("")) self.prCombo2.addItem(_fromUtf8("")) self.prCombo2.addItem(_fromUtf8("")) self.frame_2 = QtGui.QFrame(self) self.frame_2.setGeometry(QtCore.QRect(10, 290, 651, 131)) self.frame_2.setFrameShape(QtGui.QFrame.StyledPanel) self.frame_2.setFrameShadow(QtGui.QFrame.Raised) self.frame_2.setObjectName(_fromUtf8("frame_2")) #self.Time = QtGui.QLineEdit(self.frame_2) #self.Time.setGeometry(QtCore.QRect(180, 10, 71, 31)) #self.Time.setObjectName(_fromUtf8("Time")) self.tr = QtGui.QLineEdit(self.frame_2) self.tr.setGeometry(QtCore.QRect(240, 30, 71, 31)) self.tr.setObjectName(_fromUtf8("tr")) self.label_3 = QtGui.QLabel(self.frame_2) self.label_3.setGeometry(QtCore.QRect(10, 35, 231, 20)) self.label_3.setObjectName(_fromUtf8("label_3")) self.multiThread = QtGui.QCheckBox(self.frame_2) self.multiThread.setEnabled(False) self.multiThread.setGeometry(QtCore.QRect(400, 5, 181, 25)) self.multiThread.setCheckable(True) self.multiThread.setObjectName(_fromUtf8("multiThread")) self.multiThreadG = QtGui.QCheckBox(self.frame_2) self.multiThreadG.setEnabled(False) self.multiThreadG.setGeometry(QtCore.QRect(400, 35, 181, 25)) self.multiThreadG.setCheckable(True) self.multiThreadG.setObjectName(_fromUtf8("multiThreadG")) self.multiHard = QtGui.QCheckBox(self.frame_2) self.multiHard.setEnabled(False) self.multiHard.setGeometry(QtCore.QRect(400, 65, 151, 25)) self.multiHard.setCheckable(True) self.multiHard.setObjectName(_fromUtf8("multiHard")) self.hashCrack = QtGui.QPushButton(self.frame_2) self.hashCrack.setGeometry(QtCore.QRect(400, 95, 100, 28)) self.hashCrack.setEnabled(False) self.archiveCrack = QtGui.QPushButton(self.frame_2) self.archiveCrack.setGeometry(QtCore.QRect(500, 95, 100, 28)) self.archiveCrack.setEnabled(False) #self.TimeCheck = QtGui.QCheckBox(self.frame_2) #self.TimeCheck.setGeometry(QtCore.QRect(10, 12, 171, 25)) #self.TimeCheck.setObjectName(_fromUtf8("TimeCheck")) self.label_6 = QtGui.QLabel(self.frame_2) self.label_6.setGeometry(QtCore.QRect(10, 80, 141, 20)) self.label_6.setObjectName(_fromUtf8("label_6")) self.Address = QtGui.QLineEdit(self.frame_2) self.Address.setGeometry(QtCore.QRect(140, 75, 150, 32)) self.Address.setObjectName(_fromUtf8("Address")) self.setAddr = QtGui.QPushButton(self.frame_2) self.setAddr.setGeometry(QtCore.QRect(290, 75, 90, 28)) self.setAddr.setObjectName(_fromUtf8("setAddr")) self.frame_3 = QtGui.QFrame(self) self.frame_3.setGeometry(QtCore.QRect(10, 30, 651, 231)) self.frame_3.setFrameShape(QtGui.QFrame.StyledPanel) self.frame_3.setFrameShadow(QtGui.QFrame.Raised) self.frame_3.setObjectName(_fromUtf8("frame_3")) self.input = QtGui.QLineEdit(self.frame_3) self.input.setGeometry(QtCore.QRect(140, 10, 501, 32)) self.input.setObjectName(_fromUtf8("input")) self.input.setText( '{setLower}->{23}+{setLower}->{12}=4') # + {setDigit}->{34} =9') self.label = QtGui.QLabel(self.frame_3) self.label.setGeometry(QtCore.QRect(10, 15, 131, 21)) self.label.setObjectName(_fromUtf8("label")) self.executText = QtGui.QTextEdit(self.frame_3) self.executText.setGeometry(QtCore.QRect(10, 50, 631, 171)) self.executText.setObjectName(_fromUtf8("executText")) self.executText.setText(r"""setLower=r"abcdefghijklmnopqrstuvwxyz" setUpper="ABCDEFGHIJKLMNOPQRSTUVWXYZ" setDigit=r"0123456789" setSym=r"!\#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ '" setAscii=''.join([chr(i) for i in range(256)] ) setAllChars=r" !#$%&\"\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" setMyOwn="1234" setMyOwn2="567" """) self.frame_4 = QtGui.QFrame(self) self.frame_4.setGeometry(QtCore.QRect(10, 430, 321, 131)) self.frame_4.setFrameShape(QtGui.QFrame.StyledPanel) self.frame_4.setFrameShadow(QtGui.QFrame.Raised) self.frame_4.setObjectName(_fromUtf8("frame_4")) self.label_4 = QtGui.QLabel(self.frame_4) self.label_4.setEnabled(False) self.label_4.setGeometry(QtCore.QRect(10, 15, 141, 20)) self.label_4.setObjectName(_fromUtf8("label_4")) self.splitSize = QtGui.QLineEdit(self.frame_4) self.splitSize.setEnabled(False) self.splitSize.setGeometry(QtCore.QRect(155, 10, 113, 32)) self.splitSize.setObjectName(_fromUtf8("splitSize")) self.genData = QtGui.QPushButton(self.frame_4) self.genData.setGeometry(QtCore.QRect(70, 90, 181, 28)) self.genData.setObjectName(_fromUtf8("genData")) self.genData.clicked.connect(self.generateDatabase) self.prCombo1 = QtGui.QComboBox(self.frame_4) self.prCombo1.setGeometry(QtCore.QRect(110, 50, 141, 30)) self.prCombo1.setObjectName(_fromUtf8("prCombo1")) self.prCombo1.addItem(_fromUtf8("")) self.prCombo1.addItem(_fromUtf8("")) self.prCombo1.addItem(_fromUtf8("")) self.prCombo1.addItem(_fromUtf8("")) self.label_2 = QtGui.QLabel(self.frame_4) self.label_2.setGeometry(QtCore.QRect(10, 55, 91, 20)) self.label_2.setObjectName(_fromUtf8("label_2")) self.futureBtn = QtGui.QPushButton(self) self.futureBtn.setGeometry(QtCore.QRect(170, 260, 341, 28)) self.futureBtn.setObjectName(_fromUtf8("pushButton")) self.futureBtn.clicked.connect(parent.future.show) self.setWindowTitle('Main window') self.checkBox_4.setText( _translate("MainWindow", "Use quantum randombit server", None)) self.genPass.setText( _translate("MainWindow", "Generate strong password", None)) self.genAPass.setText( _translate("MainWindow", "A random strong password", None)) #self.Time.setText(_translate("MainWindow", "1", None)) self.tr.setText(_translate("MainWindow", "-35", None)) self.label_3.setText( _translate("MainWindow", "Log_2 of each password probablity:", None)) self.multiThread.setText( _translate("MainWindow", "Use multiThread by CPU", None)) self.multiThreadG.setText( _translate("MainWindow", "Use multiThread by GPU", None)) self.multiHard.setText( _translate("MainWindow", "Use multiHardDisk", None)) self.hashCrack.setText(_translate("MainWindow", "Crack hashes", None)) self.archiveCrack.setText( _translate("MainWindow", "Crack archives", None)) #self.TimeCheck.setText(_translate("MainWindow", "Time to stop (hourse):", None)) self.label_6.setText( _translate("MainWindow", "Output file Address:", None)) self.Address.setText(_translate("MainWindow", "output.txt", None)) self.setAddr.setText(_translate("MainWindow", "SetAddress", None)) self.label.setText( _translate("MainWindow", "Password structure:", None)) self.label_4.setText( _translate("MainWindow", "Split output files (GB): ", None)) self.splitSize.setText(_translate("MainWindow", "100", None)) self.genData.setText( _translate("MainWindow", "Generate database", None)) self.prCombo1.setItemText( 0, _translate("MainWindow", "Dual frequency", None)) self.prCombo1.setItemText( 1, _translate("MainWindow", "Mono frequency", None)) self.prCombo1.setItemText( 2, _translate("MainWindow", "Triple frequency", None)) self.prCombo1.setItemText(3, _translate("MainWindow", "Brut force", None)) self.label_2.setText(_translate("MainWindow", "Filter method:", None)) self.futureBtn.setText( _translate("MainWindow", "See \"futurer\" window for disabled items", None)) self.label_5.setText( _translate("MainWindow", "Probablity method:", None)) self.prCombo2.setItemText( 0, _translate("MainWindow", "Dual frequency", None)) self.prCombo2.setItemText( 1, _translate("MainWindow", "Mono frequency", None)) self.prCombo2.setItemText( 2, _translate("MainWindow", "Triple frequency", None)) def initOp(self): def externExecutText(cmd): try: exec(cmd) except Exception as msg: sendErr(msg) A = locals() ret = {} for ai in A: if ai[:3] == 'set': ret[ai] = A[ai] return ret def externStruct(command, Vars, L): locals().update(Vars) cmd = [] cmdFlag = False ctr = 0 for i in range(len(command)): if cmdFlag: cmd[-1] += command[i] if command[i] == '{': if ctr == 0: cmdFlag = True cmd += [''] ctr += 1 if command[i] == '}': ctr -= 1 if ctr == 0: cmd[-1] = cmd[-1][:-1] cmdFlag = False cmd = [cmd[i:i + 2] for i in range(0, len(cmd), 2)] chars = [[Vars[cij] for cij in ci[0].split(',')] for ci in cmd] tempStruct = [[int(cij) for cij in ci[1]] for ci in cmd] chars = [''.join(set(''.join(si))) for si in chars] ret = [] for a in itertools.product(*tempStruct): if sum(a) == L: r = [] for i in range(len(a)): r += [chars[i]] * a[i] ret += [r] return ret Vars = externExecutText(str(self.executText.toPlainText())) """try: self.T=float(str(self.Time.text())) print('t=',self.T) except Exception as a: sendErr('time of password generation must be a float. if you want to generate cantinusly enter 0.\n\t'+str(a)) return""" try: inp = str(self.input.text()) for i in range(-1, -len(inp), -1): if inp[i] == '=': break L = int(inp[i + 1:].replace(' ', '')) struct = externStruct(inp, Vars, L) if len(struct) == 0 or struct == None: sendErr('Nothing to do!') return except Exception as a: print('inputLineEdit', a) sendErr('Bad syntax detected in inputed structure!') return try: self.treshold = 2**float(str(self.tr.text())) except Exception as a: print('tr', a) sendErr('log_2(treashold) must be a float. (negative)') return self.passworder = password(struct) self.output = open(str(self.Address.text()), 'w') def randomAPass(self): class dialogOutput(QMdiSubWindow): def __init__(self, text, parent=None): super(dialogOutput, self).__init__(parent) self.setWindowTitle('Practical strong password') self.setFixedSize(250, 75) self.output = QtGui.QLineEdit(text, self) self.output.setGeometry(10, 25, 230, 45) self.initOp() ret = '' global a a = self.passworder dist = str(self.prCombo2.currentText()) if dist == 'Mono frequency': f = f1 elif dist == 'Dual frequency': f = f2 elif dist == 'Triple frequency': f = f3 while ret == '' or f(ret) > self.treshold: st = random.sample(self.passworder.structure, 1)[0] ret = ''.join([random.sample(sti, 1)[0] for sti in st]) print(ret) W = dialogOutput(ret, self) self.parent.mdi.addSubWindow(W) W.show() def generateDatabase(self): self.initOp() global database database = self.passworder.initDatabase( str(self.prCombo1.currentText()), self.treshold) self.timer = QTimer(self) self.time = 0 self.counter = 0 self.timer.start(1) for pw in database: self.output.write(pw) self.output.write('\n') self.counter += 1 if self.passworder.stoped: break self.output.close() def timeOutEvent(self): self.passworder.time += 1 print('time :{t}, pass: {p}'.format(t=passworder.time, p=passworder.counter)) if self.passworder.time >= self.passworder.T: self.passworder.setStop() self.timer.stop() self.passworder.output.flush() #print(passwordGenerator.active) def strongPassword(self): self.initOp() self.setEnabled(False) global f, database database = self.passworder.initDatabase('Brut force', self.treshold) self.timer = QTimer(self) self.time = 0 self.counter = 0 self.timer.start(1) dist = str(self.prCombo2.currentText()) if dist == 'Mono frequency': f = f1 elif dist == 'Dual frequency': f = f2 elif dist == 'Triple frequency': f = f3 for pw in database: if f(pw) < self.treshold: self.output.write(pw) self.output.write('\n') self.counter += 1 if self.passworder.stoped: break self.output.close() self.setEnabled(True)
class AnkiConnect: def __init__(self): self.server = WebServer(self.handler) try: self.server.listen() self.timer = QTimer() self.timer.timeout.connect(self.advance) self.timer.start(TICK_INTERVAL) except: QMessageBox.critical( self.window(), 'AnkiConnect', 'Failed to listen on port {}.\nMake sure it is available and is not in use.' .format(NET_PORT)) def advance(self): self.server.advance() def handler(self, request): name = request.get('action', '') version = request.get('version', 4) params = request.get('params', {}) reply = {'result': None, 'error': None} try: method = None for methodName, methodInst in inspect.getmembers( self, predicate=inspect.ismethod): apiVersionLast = 0 apiNameLast = None if getattr(methodInst, 'api', False): for apiVersion, apiName in getattr(methodInst, 'versions', []): if apiVersionLast < apiVersion <= version: apiVersionLast = apiVersion apiNameLast = apiName if apiNameLast is None and apiVersionLast == 0: apiNameLast = methodName if apiNameLast is not None and apiNameLast == name: method = methodInst break if method is None: raise Exception('unsupported action') else: reply['result'] = methodInst(**params) except Exception as e: reply['error'] = str(e) if version > 4: return reply else: return reply['result'] def download(self, url): resp = web.urlopen(url, timeout=URL_TIMEOUT) if resp.code == 200: return resp.read() else: raise Exception('return code for download of {} was {}'.format( url, resp.code)) def window(self): return aqt.mw def reviewer(self): reviewer = self.window().reviewer if reviewer is None: raise Exception('reviewer is not available') else: return reviewer def collection(self): collection = self.window().col if collection is None: raise Exception('collection is not available') else: return collection def decks(self): decks = self.collection().decks if decks is None: raise Exception('decks are not available') else: return decks def scheduler(self): scheduler = self.collection().sched if scheduler is None: raise Exception('scheduler is not available') else: return scheduler def database(self): database = self.collection().db if database is None: raise Exception('database is not available') else: return database def media(self): media = self.collection().media if media is None: raise Exception('media is not available') else: return media def startEditing(self): self.window().requireReset() def stopEditing(self): if self.collection() is not None: self.window().maybeReset() def createNote(self, note): collection = self.collection() model = collection.models.byName(note['modelName']) if model is None: raise Exception('model was not found: {}'.format( note['modelName'])) deck = collection.decks.byName(note['deckName']) if deck is None: raise Exception('deck was not found: {}'.format(note['deckName'])) ankiNote = anki.notes.Note(collection, model) ankiNote.model()['did'] = deck['id'] ankiNote.tags = note['tags'] for name, value in note['fields'].items(): if name in ankiNote: ankiNote[name] = value duplicateOrEmpty = ankiNote.dupeOrEmpty() if duplicateOrEmpty == 1: raise Exception('cannot create note because it is empty') elif duplicateOrEmpty == 2: raise Exception('cannot create note because it is a duplicte') elif duplicateOrEmpty == False: return ankiNote else: raise Exception('cannot create note for unknown reason') # # Miscellaneous # @api() def version(self): return API_VERSION @api() def upgrade(self): response = QMessageBox.question(self.window(), 'AnkiConnect', 'Upgrade to the latest version?', QMessageBox.Yes | QMessageBox.No) if response == QMessageBox.Yes: try: data = self.download(URL_UPGRADE) path = os.path.splitext(__file__)[0] + '.py' with open(path, 'w') as fp: fp.write(makeStr(data)) QMessageBox.information( self.window(), 'AnkiConnect', 'Upgraded to the latest version, please restart Anki.') return True except Exception as e: QMessageBox.critical(self.window(), 'AnkiConnect', 'Failed to download latest version.') raise e return False @api() def sync(self): self.window().onSync() @api() def multi(self, actions): return map(self.handler, actions) # # Decks # @api() def deckNames(self): return self.decks().allNames() @api() def deckNamesAndIds(self): decks = {} for deck in self.deckNames(): decks[deck] = self.decks().id(deck) return decks @api() def getDecks(self, cards): decks = {} for card in cards: did = self.database().scalar('select did from cards where id=?', card) deck = self.decks().get(did)['name'] if deck in decks: decks[deck].append(card) else: decks[deck] = [card] return decks @api() def createDeck(self, deck): try: self.startEditing() did = self.decks().id(deck) finally: self.stopEditing() return did @api() def changeDeck(self, cards, deck): self.startEditing() did = self.collection().decks.id(deck) mod = anki.utils.intTime() usn = self.collection().usn() # normal cards scids = anki.utils.ids2str(cards) # remove any cards from filtered deck first self.collection().sched.remFromDyn(cards) # then move into new deck self.collection().db.execute( 'update cards set usn=?, mod=?, did=? where id in ' + scids, usn, mod, did) self.stopEditing() @api() def deleteDecks(self, decks, cardsToo=False): try: self.startEditing() decks = filter(lambda d: d in self.deckNames(), decks) for deck in decks: did = self.decks().id(deck) self.decks().rem(did, cardsToo) finally: self.stopEditing() @api() def getDeckConfig(self, deck): if not deck in self.deckNames(): return False collection = self.collection() did = collection.decks.id(deck) return collection.decks.confForDid(did) @api() def saveDeckConfig(self, config): collection = self.collection() config['id'] = str(config['id']) config['mod'] = anki.utils.intTime() config['usn'] = collection.usn() if not config['id'] in collection.decks.dconf: return False collection.decks.dconf[config['id']] = config collection.decks.changed = True return True @api() def setDeckConfigId(self, decks, configId): configId = str(configId) for deck in decks: if not deck in self.deckNames(): return False collection = self.collection() if not configId in collection.decks.dconf: return False for deck in decks: did = str(collection.decks.id(deck)) aqt.mw.col.decks.decks[did]['conf'] = configId return True @api() def cloneDeckConfigId(self, name, cloneFrom='1'): configId = str(cloneFrom) if not configId in self.collection().decks.dconf: return False config = self.collection().decks.getConf(configId) return self.collection().decks.confId(name, config) @api() def removeDeckConfigId(self, configId): configId = str(configId) collection = self.collection() if configId == 1 or not configId in collection.decks.dconf: return False collection.decks.remConf(configId) return True @api() def storeMediaFile(self, filename, data): self.deleteMediaFile(filename) self.media().writeData(filename, base64.b64decode(data)) @api() def retrieveMediaFile(self, filename): filename = os.path.basename(filename) filename = normalize('NFC', filename) filename = self.media().stripIllegal(filename) path = os.path.join(self.media().dir(), filename) if os.path.exists(path): with open(path, 'rb') as file: return base64.b64encode(file.read()).decode('ascii') return False @api() def deleteMediaFile(self, filename): self.media().syncDelete(filename) @api() def addNote(self, note): ankiNote = self.createNote(note) audio = note.get('audio') if audio is not None and len(audio['fields']) > 0: data = download(audio['url']) if data is not None: if audio['skipHash'] is None: skip = False else: m = hashlib.md5() m.update(data) skip = audio['skipHash'] == m.hexdigest() if not skip: for field in audio['fields']: if field in ankiNote: ankiNote[field] += u'[sound:{}]'.format( audio['filename']) self.media().writeData(audio['filename'], data) collection = self.collection() self.startEditing() collection.addNote(ankiNote) collection.autosave() self.stopEditing() return ankiNote.id @api() def canAddNote(self, note): try: return bool(self.createNote(note)) except: return False @api() def updateNoteFields(self, note): ankiNote = self.collection().getNote(note['id']) if ankiNote is None: raise Exception('note was not found: {}'.format(note['id'])) for name, value in note['fields'].items(): if name in ankiNote: ankiNote[name] = value ankiNote.flush() @api() def addTags(self, notes, tags, add=True): self.startEditing() self.collection().tags.bulkAdd(notes, tags, add) self.stopEditing() @api() def removeTags(self, notes, tags): return self.addTags(notes, tags, False) @api() def getTags(self): return self.collection().tags.all() @api() def suspend(self, cards, suspend=True): for card in cards: if self.suspended(card) == suspend: cards.remove(card) if len(cards) == 0: return False scheduler = self.scheduler() self.startEditing() if suspend: scheduler.suspendCards(cards) else: scheduler.unsuspendCards(cards) self.stopEditing() return True @api() def unsuspend(self, cards): self.suspend(cards, False) @api() def suspended(self, card): card = self.collection().getCard(card) return card.queue == -1 @api() def areSuspended(self, cards): suspended = [] for card in cards: suspended.append(self.suspended(card)) return suspended @api() def areDue(self, cards): due = [] for card in cards: if self.findCards('cid:{} is:new'.format(card)): due.append(True) else: date, ivl = self.collection().db.all( 'select id/1000.0, ivl from revlog where cid = ?', card)[-1] if ivl >= -1200: duo.append( bool(self.findCards('cid:{} is:due'.format(card)))) else: due.append(date - ivl <= time()) return due @api() def getIntervals(self, cards, complete=False): intervals = [] for card in cards: if self.findCards('cid:{} is:new'.format(card)): intervals.append(0) else: interval = self.collection().db.list( 'select ivl from revlog where cid = ?', card) if not complete: interval = interval[-1] intervals.append(interval) return intervals @api() def modelNames(self): return self.collection().models.allNames() @api() def modelNamesAndIds(self): models = {} for model in self.modelNames(): models[model] = int(self.collection().models.byName(model)['id']) return models @api() def modelNameFromId(self, modelId): model = self.collection().models.get(modelId) if model is None: raise Exception('model was not found: {}'.format(modelId)) else: return model['name'] @api() def modelFieldNames(self, modelName): model = self.collection().models.byName(modelName) if model is None: raise Exception('model was not found: {}'.format(modelName)) else: return [field['name'] for field in model['flds']] @api() def modelFieldsOnTemplates(self, modelName): model = self.collection().models.byName(modelName) if model is None: raise Exception('model was not found: {}'.format(modelName)) templates = {} for template in model['tmpls']: fields = [] for side in ['qfmt', 'afmt']: fieldsForSide = [] # based on _fieldsOnTemplate from aqt/clayout.py matches = re.findall('{{[^#/}]+?}}', template[side]) for match in matches: # remove braces and modifiers match = re.sub(r'[{}]', '', match) match = match.split(':')[-1] # for the answer side, ignore fields present on the question side + the FrontSide field if match == 'FrontSide' or side == 'afmt' and match in fields[ 0]: continue fieldsForSide.append(match) fields.append(fieldsForSide) templates[template['name']] = fields return templates @api() def deckNameFromId(self, deckId): deck = self.collection().decks.get(deckId) if deck is None: raise Exception('deck was not found: {}'.format(deckId)) else: return deck['name'] @api() def findNotes(self, query=None): if query is None: return [] else: return self.collection().findNotes(query) @api() def findCards(self, query=None): if query is None: return [] else: return self.collection().findCards(query) @api() def cardsInfo(self, cards): result = [] for cid in cards: try: card = self.collection().getCard(cid) model = card.model() note = card.note() fields = {} for info in model['flds']: order = info['ord'] name = info['name'] fields[name] = { 'value': note.fields[order], 'order': order } result.append({ 'cardId': card.id, 'fields': fields, 'fieldOrder': card.ord, 'question': card._getQA()['q'], 'answer': card._getQA()['a'], 'modelName': model['name'], 'deckName': self.deckNameFromId(card.did), 'css': model['css'], 'factor': card.factor, #This factor is 10 times the ease percentage, # so an ease of 310% would be reported as 3100 'interval': card.ivl, 'note': card.nid }) except TypeError as e: # Anki will give a TypeError if the card ID does not exist. # Best behavior is probably to add an 'empty card' to the # returned result, so that the items of the input and return # lists correspond. result.append({}) return result @api() def notesInfo(self, notes): result = [] for nid in notes: try: note = self.collection().getNote(nid) model = note.model() fields = {} for info in model['flds']: order = info['ord'] name = info['name'] fields[name] = { 'value': note.fields[order], 'order': order } result.append({ 'noteId': note.id, 'tags': note.tags, 'fields': fields, 'modelName': model['name'], 'cards': self.collection().db.list( 'select id from cards where nid = ? order by ord', note.id) }) except TypeError as e: # Anki will give a TypeError if the note ID does not exist. # Best behavior is probably to add an 'empty card' to the # returned result, so that the items of the input and return # lists correspond. result.append({}) return result @api() def cardsToNotes(self, cards): return self.collection().db.list( 'select distinct nid from cards where id in ' + anki.utils.ids2str(cards)) @api() def guiBrowse(self, query=None): browser = aqt.dialogs.open('Browser', self.window()) browser.activateWindow() if query is not None: browser.form.searchEdit.lineEdit().setText(query) if hasattr(browser, 'onSearch'): browser.onSearch() else: browser.onSearchActivated() return browser.model.cards @api() def guiAddCards(self): addCards = aqt.dialogs.open('AddCards', self.window()) addCards.activateWindow() @api() def guiReviewActive(self): return self.reviewer().card is not None and self.window( ).state == 'review' @api() def guiCurrentCard(self): if not self.guiReviewActive(): raise Exception('Gui review is not currently active.') reviewer = self.reviewer() card = reviewer.card model = card.model() note = card.note() fields = {} for info in model['flds']: order = info['ord'] name = info['name'] fields[name] = {'value': note.fields[order], 'order': order} if card is not None: return { 'cardId': card.id, 'fields': fields, 'fieldOrder': card.ord, 'question': card._getQA()['q'], 'answer': card._getQA()['a'], 'buttons': [b[0] for b in reviewer._answerButtonList()], 'modelName': model['name'], 'deckName': self.deckNameFromId(card.did), 'css': model['css'], 'template': card.template()['name'] } @api() def guiStartCardTimer(self): if not self.guiReviewActive(): return False card = self.reviewer().card if card is not None: card.startTimer() return True else: return False @api() def guiShowQuestion(self): if self.guiReviewActive(): self.reviewer()._showQuestion() return True else: return False @api() def guiShowAnswer(self): if self.guiReviewActive(): self.window().reviewer._showAnswer() return True else: return False @api() def guiAnswerCard(self, ease): if not self.guiReviewActive(): return False reviewer = self.reviewer() if reviewer.state != 'answer': return False if ease <= 0 or ease > self.scheduler().answerButtons(reviewer.card): return False reviewer._answerCard(ease) return True @api() def guiDeckOverview(self, name): collection = self.collection() if collection is not None: deck = collection.decks.byName(name) if deck is not None: collection.decks.select(deck['id']) self.window().onOverview() return True return False @api() def guiDeckBrowser(self): self.window().moveToState('deckBrowser') @api() def guiDeckReview(self, name): if self.guiDeckOverview(name): self.window().moveToState('review') return True else: return False @api() def guiExitAnki(self): timer = QTimer() def exitAnki(): timer.stop() self.window().close() timer.timeout.connect(exitAnki) timer.start( 1000) # 1s should be enough to allow the response to be sent. @api() def addNotes(self, notes): results = [] for note in notes: try: results.append(self.addNote(note)) except Exception: results.append(None) return results @api() def canAddNotes(self, notes): results = [] for note in notes: results.append(self.canAddNote(note)) return results
class Gui(QMainWindow): """ Main GUI Class contains the main function and interfaces between the GUI and functions """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) """ Set GUI to track mouse """ QWidget.setMouseTracking(self, True) """ Dynamixel bus TODO: add other motors here as needed with their correct address""" self.dxlbus = DXL_BUS(DEVICENAME, BAUDRATE) port_num = self.dxlbus.port() base = DXL_MX(port_num, 1) shld = DXL_MX(port_num, 2) elbw = DXL_MX(port_num, 3) wrst = DXL_AX(port_num, 4) wrst2 = DXL_AX(port_num, 5) wrst3 = DXL_XL(port_num, 6) gripper = DXL_XL(port_num, 7) """Objects Using Other Classes""" self.kinect = Kinect() self.rexarm = Rexarm((base, shld, elbw, wrst, wrst2, wrst3), gripper) self.tp = TrajectoryPlanner(self.rexarm) self.sm = StateMachine(self.rexarm, self.tp, self.kinect) """ Attach Functions to Buttons & Sliders TODO: NAME AND CONNECT BUTTONS AS NEEDED """ self.ui.btn_estop.clicked.connect(self.estop) self.ui.btnUser1.setText("Calibrate") self.ui.btnUser1.clicked.connect( partial(self.sm.set_next_state, "calibrate")) self.ui.btnUser2.setText("Record") self.ui.btnUser2.clicked.connect( partial(self.sm.set_next_state, "record")) self.ui.btnUser3.setText("Playback") self.ui.btnUser3.clicked.connect( partial(self.sm.set_next_state, "playback")) self.ui.sldrBase.valueChanged.connect(self.sliderChange) self.ui.sldrShoulder.valueChanged.connect(self.sliderChange) self.ui.sldrElbow.valueChanged.connect(self.sliderChange) self.ui.sldrWrist.valueChanged.connect(self.sliderChange) self.ui.sldrWrist2.valueChanged.connect(self.sliderChange) self.ui.sldrWrist3.valueChanged.connect(self.sliderChange) self.ui.sldrHand.valueChanged.connect(self.sliderChange) self.ui.sldrMaxTorque.valueChanged.connect(self.sliderChange) self.ui.sldrSpeed.valueChanged.connect(self.sliderChange) self.ui.chk_directcontrol.stateChanged.connect(self.directControlChk) self.ui.rdoutStatus.setText("Waiting for input") self.ui.btn_exec.clicked.connect( partial(self.sm.set_next_state, "execute")) self.ui.btnUser4.setText("TP test") self.ui.btnUser4.clicked.connect( partial(self.sm.set_next_state, "TP test")) self.ui.btnUser5.setText("Detect blocks") self.ui.btnUser5.clicked.connect( partial(self.sm.set_next_state, "Detect Blocks")) self.ui.btnUser11.setText("IK_set_pose") self.ui.btnUser11.clicked.connect( partial(self.sm.set_next_state, "IK_set_pose")) self.ui.btnUser12.setText("IK_Test") self.ui.btnUser12.clicked.connect( partial(self.sm.set_next_state, "IK_test")) self.ui.btnUser10.setText("Grab_Place") self.ui.btnUser10.clicked.connect( partial(self.sm.set_next_state, "Grab_Place")) self.ui.btnUser9.setText("BlockSlider") self.ui.btnUser9.clicked.connect( partial(self.sm.set_next_state, "BlockSlider")) self.ui.btnUser8.setText("Pick_N_Stack") self.ui.btnUser8.clicked.connect( partial(self.sm.set_next_state, "Pick_N_Stack")) """initalize manual control off""" self.ui.SliderFrame.setEnabled(False) """initalize rexarm""" self.rexarm.initialize() """Setup Threads""" self.videoThread = VideoThread(self.kinect) self.videoThread.updateFrame.connect(self.setImage) self.videoThread.start() self.logicThread = LogicThread(self.sm) self.logicThread.start() self.displayThread = DisplayThread(self.rexarm, self.sm) self.displayThread.updateJointReadout.connect(self.updateJointReadout) self.displayThread.updateEndEffectorReadout.connect( self.updateEndEffectorReadout) self.displayThread.updateStatusMessage.connect( self.updateStatusMessage) self.displayThread.start() """ Setup Timer this runs the trackMouse function every 50ms """ self._timer = QTimer(self) self._timer.timeout.connect(self.trackMouse) self._timer.start(50) """ Slots attach callback functions to signals emitted from threads""" @pyqtSlot(QImage, QImage, QImage) def setImage(self, rgb_image, depth_image, block_image): if (self.ui.radioVideo.isChecked()): self.ui.videoDisplay.setPixmap(QPixmap.fromImage(rgb_image)) if (self.ui.radioDepth.isChecked()): self.ui.videoDisplay.setPixmap(QPixmap.fromImage(depth_image)) if (self.ui.radioBlockDetect.isChecked()): self.ui.videoDisplay.setPixmap(QPixmap.fromImage(block_image)) @pyqtSlot(list) def updateJointReadout(self, joints): self.ui.rdoutBaseJC.setText(str("%+.2f" % (joints[0] * R2D))) self.ui.rdoutShoulderJC.setText( str("%+.2f" % ((joints[1] * R2D) + 90.0))) self.ui.rdoutElbowJC.setText(str("%+.2f" % (joints[2] * R2D))) self.ui.rdoutWristJC.setText(str("%+.2f" % (joints[3] * R2D))) self.ui.rdoutWrist2JC.setText(str("%+.2f" % (joints[4] * R2D))) if (len(joints) > 5): self.ui.rdoutWrist3JC.setText(str("%+.2f" % (joints[5] * R2D))) else: self.ui.rdoutWrist3JC.setText(str("N.A.")) @pyqtSlot(list) def updateEndEffectorReadout(self, pos): self.ui.rdoutX.setText(str("%+.2f" % (pos[0]))) self.ui.rdoutY.setText(str("%+.2f" % (pos[1]))) self.ui.rdoutZ.setText(str("%+.2f" % (pos[2]))) self.ui.rdoutT.setText(str("%+.2f" % (pos[3]))) self.ui.rdoutG.setText(str("%+.2f" % (pos[4]))) self.ui.rdoutP.setText(str("%+.2f" % (pos[5]))) @pyqtSlot(str) def updateStatusMessage(self, msg): self.ui.rdoutStatus.setText(msg) """ Other callback functions attached to GUI elements""" def estop(self): self.rexarm.estop = True self.sm.set_next_state("estop") def sliderChange(self): """ Function to change the slider labels when sliders are moved and to command the arm to the given position """ self.ui.rdoutBase.setText(str(self.ui.sldrBase.value())) self.ui.rdoutShoulder.setText(str(self.ui.sldrShoulder.value())) self.ui.rdoutElbow.setText(str(self.ui.sldrElbow.value())) self.ui.rdoutWrist.setText(str(self.ui.sldrWrist.value())) self.ui.rdoutWrist2.setText(str(self.ui.sldrWrist2.value())) self.ui.rdoutWrist2.setText(str(self.ui.sldrWrist3.value())) self.ui.rdoutWrist2.setText(str(self.ui.sldrHand.value())) self.ui.rdoutTorq.setText(str(self.ui.sldrMaxTorque.value()) + "%") self.ui.rdoutSpeed.setText(str(self.ui.sldrSpeed.value()) + "%") self.rexarm.set_torque_limits([self.ui.sldrMaxTorque.value() / 100.0] * self.rexarm.num_joints, update_now=False) self.rexarm.set_speeds_normalized_global(self.ui.sldrSpeed.value() / 100.0, update_now=False) joint_positions = np.array([ self.ui.sldrBase.value() * D2R, self.ui.sldrShoulder.value() * D2R, self.ui.sldrElbow.value() * D2R, self.ui.sldrWrist.value() * D2R, self.ui.sldrWrist2.value() * D2R, self.ui.sldrWrist3.value() * D2R ]) self.rexarm.set_positions(joint_positions, update_now=False) # self.rexarm.pause(0.1) self.rexarm.set_gripper_position(self.ui.sldrHand.value() * D2R, update_now=False) # self.rexarm.gripper.set_position(self.ui.sldrHand.value()*D2R) def directControlChk(self, state): if state == Qt.Checked: self.sm.set_next_state("manual") self.ui.SliderFrame.setEnabled(True) else: self.sm.set_next_state("idle") self.ui.SliderFrame.setEnabled(False) def trackMouse(self): """ Mouse position presentation in GUI TODO: after implementing workspace calibration display the world coordinates the mouse points to in the RGB video image. """ x = QWidget.mapFromGlobal(self, QCursor.pos()).x() y = QWidget.mapFromGlobal(self, QCursor.pos()).y() if ((x < MIN_X) or (x >= MAX_X) or (y < MIN_Y) or (y >= MAX_Y)): self.ui.rdoutMousePixels.setText("(-,-,-)") self.ui.rdoutMouseWorld.setText("(-,-,-)") else: x = x - MIN_X y = y - MIN_Y if (self.kinect.currentDepthFrame.any() != 0): z = self.kinect.currentDepthFrame[y][x] self.ui.rdoutMousePixels.setText("(%.0f,%.0f,%.0f)" % (x, y, z)) #convert camera data to depth in mm depth = 1000 * 0.1236 * np.tan(z / 2842.5 + 1.1863) # if self.kinect.kinectCalibrated == True : world_frame = depth * np.dot(self.kinect.projection, [x, y, 1]) #To convert depth to IK convention world_frame[2] = -world_frame[2] + 939 self.ui.rdoutMouseWorld.setText( "(%.0f,%.0f,%.0f)" % (world_frame[0], world_frame[1], world_frame[2])) self.kinect.world_frame = world_frame # use this variable in click and grab #else : # self.ui.rdoutMouseWorld.setText("(-,-,-)") def mousePressEvent(self, QMouseEvent): """ Function used to record mouse click positions for calibration """ """ Get mouse posiiton """ x = QMouseEvent.x() y = QMouseEvent.y() """ If mouse position is not over the camera image ignore """ if ((x < MIN_X) or (x > MAX_X) or (y < MIN_Y) or (y > MAX_Y)): return """ Change coordinates to image axis """ self.kinect.last_click[0] = x - MIN_X self.kinect.last_click[1] = y - MIN_Y self.kinect.new_click = True
def eventFilter(self, watched, event): etype = event.type() # Before we steal this event from the scene, check that it is allowing brush strokes allow_brushing = True for view in self._navCtrl._views: allow_brushing &= view.scene().allow_brushing if not allow_brushing: return self._navIntr.eventFilter(watched, event) if etype == QEvent.MouseButtonDblClick and self._doubleClickTimer is not None: # On doubleclick, cancel release handler that normally draws the stroke. self._doubleClickTimer.stop() self._doubleClickTimer = None self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, event) if self._current_state == self.DEFAULT_MODE: if etype == QEvent.MouseButtonPress \ and event.button() == Qt.LeftButton \ and event.modifiers() == Qt.NoModifier \ and self._navIntr.mousePositionValid(watched, event): ### default mode -> maybe draw mode self._current_state = self.MAYBE_DRAW_MODE # event will not be valid to use after this function exits, # so we must make a copy of it instead of just saving the pointer self._lastEvent = QMouseEvent(event.type(), event.pos(), event.globalPos(), event.button(), event.buttons(), event.modifiers()) elif self._current_state == self.MAYBE_DRAW_MODE: if etype == QEvent.MouseMove: # navigation interpreter also has to be in # default mode to avoid inconsistencies if self._navIntr.state == self._navIntr.DEFAULT_MODE: ### maybe draw mode -> maybe draw mode self._current_state = self.DRAW_MODE self.onEntry_draw(watched, self._lastEvent) self.onMouseMove_draw(watched, event) return True else: self._navIntr.eventFilter(watched, self._lastEvent) return self._navIntr.eventFilter(watched, event) elif etype == QEvent.MouseButtonDblClick: ### maybe draw mode -> default mode self._current_state = self.DEFAULT_MODE return self._navIntr.eventFilter(watched, event) elif etype == QEvent.MouseButtonRelease: def handleRelease(releaseEvent): self._current_state = self.DRAW_MODE self.onEntry_draw(watched, self._lastEvent) self.onExit_draw(watched, releaseEvent) self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, releaseEvent) # If this event is part of a double-click, we don't really want to handle it. # Typical event sequence is press, release, double-click (not two presses). # Instead of handling this right away, set a timer to do the work. # We'll cancel the timer if we see a double-click event (see above). self._doubleClickTimer = QTimer(self) self._doubleClickTimer.setInterval(200) self._doubleClickTimer.setSingleShot(True) # event will not be valid to use after this function exits, # so we must make a copy of it instead of just saving the pointer eventCopy = QMouseEvent(event.type(), event.pos(), event.button(), event.buttons(), event.modifiers()) self._doubleClickTimer.timeout.connect( partial(handleRelease, eventCopy)) self._doubleClickTimer.start() return True elif self._current_state == self.DRAW_MODE: if etype == QEvent.MouseButtonRelease and event.button( ) == Qt.LeftButton: self.onExit_draw(watched, event) ### draw mode -> default mode self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, event) return True elif etype == QEvent.MouseMove and event.buttons() & Qt.LeftButton: if self._navIntr.mousePositionValid(watched, event): self.onMouseMove_draw(watched, event) return True else: self.onExit_draw(watched, event) ### draw mode -> default mode self._current_state = self.DEFAULT_MODE self.onEntry_default(watched, event) # let the navigation interpreter handle common events return self._navIntr.eventFilter(watched, event)
class Rme(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) uicLoad("ffado/mixer/rme", self) self.init() def init(self): self.PhantomSwitches = { self.phantom_0: ['/Control/Phantom', 0], self.phantom_1: ['/Control/Phantom', 1], self.phantom_2: ['/Control/Phantom', 2], self.phantom_3: ['/Control/Phantom', 3], } self.Switches = { self.ff400_chan3_opt_instr: ['/Control/Chan3_opt_instr'], self.ff400_chan3_opt_pad: ['/Control/Chan3_opt_pad'], self.ff400_chan4_opt_instr: ['/Control/Chan4_opt_instr'], self.ff400_chan4_opt_pad: ['/Control/Chan4_opt_pad'], self.spdif_output_optical: ['/Control/SPDIF_output_optical', 0], self.spdif_output_emphasis: ['/Control/SPDIF_output_emphasis', 0], self.spdif_output_pro: ['/Control/SPDIF_output_pro', 0], self.spdif_output_nonaudio: ['/Control/SPDIF_output_nonaudio', 0], } self.Radiobuttons = { self.level_in_lo_gain: ['/Control/Input_level', 1], self.level_in_p4dBu: ['/Control/Input_level', 2], self.level_in_m10dBV: ['/Control/Input_level', 3], self.level_out_hi_gain: ['/Control/Output_level', 1], self.level_out_p4dBu: ['/Control/Output_level', 2], self.level_out_m10dBV: ['/Control/Output_level', 3], self.spdif_input_coax: ['/Control/SPDIF_input_mode', 0], self.spdif_input_optical: ['/Control/SPDIF_input_mode', 1], self.phones_hi_gain: ['/Control/Phones_level', 1], self.phones_p4dBu: ['/Control/Phones_level', 2], self.phones_m10dBV: ['/Control/Phones_level', 3], self.clock_mode_autosync: ['/Control/Clock_mode', 1], self.clock_mode_master: ['/Control/Clock_mode', 0], self.sync_ref_wordclk: ['/Control/Sync_ref', 0], self.sync_ref_adat1: ['/Control/Sync_ref', 1], self.sync_ref_adat2: ['/Control/Sync_ref', 2], self.sync_ref_spdif: ['/Control/Sync_ref', 3], self.sync_ref_tco: ['/Control/Sync_ref', 4], } self.Checkboxes = { self.ch1_instr_fuzz: ['/Control/Chan1_instr_opts', 0x04], self.ch1_instr_limiter: ['/Control/Chan1_instr_opts', 0x08], self.ch1_instr_filter: ['/Control/Chan1_instr_opts', 0x02], } self.Gains = { self.gain_mic1: ['/Control/Gains', 0], self.gain_mic2: ['/Control/Gains', 1], self.gain_input3: ['/Control/Gains', 2], self.gain_input4: ['/Control/Gains', 3], } self.Combos = { self.ff800_ch1_src: ['/Control/Chan1_source'], self.ff800_ch7_src: ['/Control/Chan7_source'], self.ff800_ch8_src: ['/Control/Chan8_source'], } # Other mixer variables self.is_streaming = 0 self.sample_rate = 0 self.model = 0 self.tco_present = 0 # Public slot: update phantom power hardware switches def updatePhantomSwitch(self, a0): sender = self.sender() # Value is the phantom switch value, with a corresponding enable # bit in the high 16 bit word val = (a0 << self.PhantomSwitches[sender][1]) | ( 0x00010000 << self.PhantomSwitches[sender][1]) log.debug("phantom switch %d set to %d" % (self.PhantomSwitches[sender][1], a0)) self.hw.setDiscrete(self.PhantomSwitches[sender][0], val) # Public slot: update generic switches def updateSwitch(self, a0): sender = self.sender() log.debug("switch %s set to %d" % (self.Switches[sender][0], a0)) self.hw.setDiscrete(self.Switches[sender][0], a0) # Public slot: update generic radiobuttons def updateRadiobutton(self, a0): sender = self.sender() if (a0 != 0): # Only change the control state on a button being "checked" log.debug( "radiobutton group %s set to %d" % (self.Radiobuttons[sender][0], self.Radiobuttons[sender][1])) self.hw.setDiscrete(self.Radiobuttons[sender][0], self.Radiobuttons[sender][1]) def updateCheckboxes(self, a0): sender = self.sender() val = self.hw.getDiscrete(self.Checkboxes[sender][0]) if (a0 != 0): val = val | self.Checkboxes[sender][1] else: val = val & ~self.Checkboxes[sender][1] log.debug("checkbox group %s set to %d" % (self.Checkboxes[sender][0], val)) self.hw.setDiscrete(self.Checkboxes[sender][0], val) # Public slot: update gains def updateGain(self, a0): sender = self.sender() log.debug("gain %s[%d] set to %d" % (self.Gains[sender][0], self.Gains[sender][1], a0)) self.hw.setMatrixMixerValue(self.Gains[sender][0], 0, self.Gains[sender][1], a0) def updateBandwidthLimit(self, a0): # Account for the "No ADAT-2" item which will not be present on # a FF400. if (self.model == RME_MODEL_FF400 and a0 > 0): a0 = a0 + 1 # log.debug("limit update: %d" % (a0)); self.hw.setDiscrete('/Control/Bandwidth_limit', a0) def updateCombo(self, a0): sender = self.sender() log.debug("combo %s set to %d" % (self.Combos[sender][0], a0)) self.hw.setDiscrete(self.Combos[sender][0], a0) def updateStreamingState(self): ss = self.streamingstatus.selected() ss_txt = self.streamingstatus.getEnumLabel(ss) if ss_txt != 'Idle': self.is_streaming = True else: self.is_streaming = False if (self.last_streaming_state != self.is_streaming): self.bandwidth_limit.setEnabled(not (self.is_streaming)) self.last_streaming_state = self.is_streaming def status_update(self): # log.debug("timer event") self.updateStreamingState() clk_mode = ['Master', 'Slave'] src_str = ['None', 'ADAT 1', 'ADAT 2', 'SPDIF', 'Wordclock', 'TCO'] sync_stat = ['No lock', 'Locked', 'Synced'] sysclock_mode = self.hw.getDiscrete('/Control/sysclock_mode') sysclock_freq = self.hw.getDiscrete('/Control/sysclock_freq') autosync_freq = self.hw.getDiscrete('/Control/autosync_freq') autosync_src = self.hw.getDiscrete('/Control/autosync_src') sync_status = self.hw.getDiscrete('/Control/sync_status') spdif_freq = self.hw.getDiscrete('/Control/spdif_freq') self.sysclock_freq.setText("%d Hz" % (sysclock_freq)) self.sysclock_mode.setText(clk_mode[sysclock_mode]) self.autosync_freq.setText("%d Hz" % (autosync_freq)) self.autosync_src.setText(src_str[autosync_src]) self.sync_check_adat1_status.setText(sync_stat[sync_status & 0x03]) self.sync_check_adat2_status.setText(sync_stat[(sync_status >> 2) & 0x03]) self.sync_check_spdif_status.setText(sync_stat[(sync_status >> 4) & 0x03]) self.sync_check_wclk_status.setText(sync_stat[(sync_status >> 6) & 0x03]) self.sync_check_tco_status.setText(sync_stat[(sync_status >> 8) & 0x03]) self.spdif_freq.setText("%d Hz" % (spdif_freq)) # Hide and disable a control def disable_hide(self, widget): widget.hide() widget.setEnabled(False) def initValues(self): # print self.hw.servername # print self.hw.basepath self.inputmatrix = MatrixMixer( self.hw.servername, self.hw.basepath + "/Mixer/InputFaders", self, 0x8000, self.hw.basepath + "/Mixer/InputMutes", self.hw.basepath + "/Mixer/InputInverts", True) layout = QtGui.QVBoxLayout() scrollarea = QtGui.QScrollArea() scrollarea.setWidgetResizable(True) scrollarea.setWidget(self.inputmatrix) layout.addWidget(scrollarea) self.mixer.setLayout(layout) self.playbackmatrix = MatrixMixer( self.hw.servername, self.hw.basepath + "/Mixer/PlaybackFaders", self, 0x8000, self.hw.basepath + "/Mixer/PlaybackMutes", self.hw.basepath + "/Mixer/PlaybackInverts", True) layout = QtGui.QVBoxLayout() scrollarea = QtGui.QScrollArea() scrollarea.setWidgetResizable(True) scrollarea.setWidget(self.playbackmatrix) layout.addWidget(scrollarea) self.playbackmixer.setLayout(layout) self.outputmatrix = MatrixMixer( self.hw.servername, self.hw.basepath + "/Mixer/OutputFaders", self, 0x8000, self.hw.basepath + "/Mixer/OutputMutes", None, True) layout = QtGui.QVBoxLayout() scrollarea = QtGui.QScrollArea() scrollarea.setWidget(self.outputmatrix) scrollarea.setWidgetResizable(True) # This is a bit of a hack, but it works to ensure this single-row # matrix mixer doesn't fill the entire screen but also doesn't end # up with a pointless scrollbar. The matrix mixer's minimum height # is 0 according to minimumHeight(), which is probably the # fundamental issue here; however, I've already wasted too much time # trying to get this to work so if the hack is effective we'll run # with it. scrollarea.setMinimumHeight(150) layout.addWidget(scrollarea, 0, Qt.AlignTop) self.outputmixer.setLayout(layout) self.is_streaming = False self.last_streaming_state = False # Retrieve other device settings as needed and customise the UI # based on these options. self.model = self.hw.getDiscrete('/Control/Model') log.debug("device model identifier: %d" % (self.model)) self.tco_present = self.hw.getDiscrete('/Control/TCO_present') log.debug("device has TCO: %d" % (self.tco_present)) #self.sample_rate = self.hw.getDiscrete('/Mixer/Info/SampleRate') #log.debug("device sample rate: %d" % (self.sample_rate)) # The Fireface-400 only has 2 phantom-capable channels if (self.model == RME_MODEL_FF400): self.disable_hide(self.phantom_2) self.disable_hide(self.phantom_3) else: self.phantom_0.setText("Mic 7") self.phantom_1.setText("Mic 8") self.phantom_2.setText("Mic 9") self.phantom_3.setText("Mic 10") # Instrument options, input jack selection controls and an ADAT2 # input are applicable only to the FF800 if (self.model != RME_MODEL_FF800): self.instrument_options_group.setEnabled(False) self.input_plug_select_group.setEnabled(False) self.sync_ref_adat2.setEnabled(False) self.sync_check_adat2_label.setEnabled(False) self.sync_check_adat2_status.setEnabled(False) for ctrl, info in self.Combos.iteritems(): if (not (ctrl.isEnabled())): continue val = self.hw.getDiscrete(info[0]) log.debug("combo %s is %d" % (info[0], val)) ctrl.setCurrentIndex(val) QObject.connect(ctrl, SIGNAL('currentIndexChanged(int)'), self.updateCombo) if (not (self.tco_present)): self.sync_check_tco_label.setEnabled(False) self.sync_check_tco_status.setEnabled(False) self.sync_ref_tco.setEnabled(False) # Only the FF400 has specific channel 3/4 options, input gain # controls and switchable phones level if (self.model != RME_MODEL_FF400): self.disable_hide(self.input_gains_group) self.disable_hide(self.channel_3_4_options_group) self.phones_level_group.setEnabled(False) # Add the "No ADAT-2" item to the bandwidth limit control if the # device is not a FF400. Set the control to reflect the current # device setting and connect an update signal. if (self.model != RME_MODEL_FF400): self.bandwidth_limit.insertItem(1, "No ADAT-2") val = self.hw.getDiscrete('/Control/Bandwidth_limit') if (self.model == RME_MODEL_FF400 and val > 1): val = val - 1 self.bandwidth_limit.setCurrentIndex(val) QObject.connect(self.bandwidth_limit, SIGNAL('currentIndexChanged(int)'), self.updateBandwidthLimit) # Get current hardware values and connect GUI element signals to # their respective slots for ctrl, info in self.PhantomSwitches.iteritems(): if (not (ctrl.isEnabled())): continue val = (self.hw.getDiscrete(info[0]) >> info[1]) & 0x01 log.debug("phantom switch %d is %d" % (info[1], val)) if val: ctrl.setChecked(True) else: ctrl.setChecked(False) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updatePhantomSwitch) for ctrl, info in self.Switches.iteritems(): if (not (ctrl.isEnabled())): continue val = self.hw.getDiscrete(info[0]) log.debug("switch %s is %d" % (info[0], val)) if val: ctrl.setChecked(True) else: ctrl.setChecked(False) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateSwitch) for ctrl, info in self.Radiobuttons.iteritems(): if (not (ctrl.isEnabled())): continue # This is a touch wasteful since it means we retrieve the control # value once per radio button rather than once per radio button # group. In time we might introduce radiobutton groupings in the # self.* datastructures to avoid this, but for the moment this is # easy and it works. val = self.hw.getDiscrete(info[0]) if (val == info[1]): val = 1 else: val = 0 ctrl.setChecked(val) log.debug("Radiobutton %s[%d] is %d" % (info[0], info[1], val)) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateRadiobutton) for ctrl, info in self.Checkboxes.iteritems(): if (not (ctrl.isEnabled())): continue # This is a touch wasteful since it means we retrieve the control # value once per checkbox button rather than once per checkbox # group. In time we might introduce checkbox groupings in the # self.* datastructures to avoid this, but for the moment this is # easy and it works. val = self.hw.getDiscrete(info[0]) if (val & info[1]): val = 1 else: val = 0 ctrl.setChecked(val) log.debug("Checkbox %s[%d] is %d" % (info[0], info[1], val)) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateCheckboxes) for ctrl, info in self.Gains.iteritems(): if (not (ctrl.isEnabled())): continue val = self.hw.getMatrixMixerValue(info[0], 0, info[1]) log.debug("gain %s[%d] is %d" % (info[0], info[1], val)) ctrl.setValue(val) QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateGain) self.updateStreamingState() #log.debug("device streaming flag: %d" % (self.is_streaming)) self.update_timer = QTimer(self) QObject.connect(self.update_timer, SIGNAL('timeout()'), self.status_update) self.update_timer.start(1000)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) """ Set GUI to track mouse """ QWidget.setMouseTracking(self, True) """ Dynamixel bus TODO: add other motors here as needed with their correct address""" self.dxlbus = DXL_BUS(DEVICENAME, BAUDRATE) port_num = self.dxlbus.port() base = DXL_MX(port_num, 1) shld = DXL_MX(port_num, 2) elbw = DXL_MX(port_num, 3) wrst = DXL_AX(port_num, 4) wrst2 = DXL_AX(port_num, 5) wrst3 = DXL_XL(port_num, 6) gripper = DXL_XL(port_num, 7) """Objects Using Other Classes""" self.kinect = Kinect() self.rexarm = Rexarm((base, shld, elbw, wrst, wrst2, wrst3), gripper) self.tp = TrajectoryPlanner(self.rexarm) self.sm = StateMachine(self.rexarm, self.tp, self.kinect) """ Attach Functions to Buttons & Sliders TODO: NAME AND CONNECT BUTTONS AS NEEDED """ self.ui.btn_estop.clicked.connect(self.estop) self.ui.btnUser1.setText("Calibrate") self.ui.btnUser1.clicked.connect( partial(self.sm.set_next_state, "calibrate")) self.ui.btnUser2.setText("Record") self.ui.btnUser2.clicked.connect( partial(self.sm.set_next_state, "record")) self.ui.btnUser3.setText("Playback") self.ui.btnUser3.clicked.connect( partial(self.sm.set_next_state, "playback")) self.ui.sldrBase.valueChanged.connect(self.sliderChange) self.ui.sldrShoulder.valueChanged.connect(self.sliderChange) self.ui.sldrElbow.valueChanged.connect(self.sliderChange) self.ui.sldrWrist.valueChanged.connect(self.sliderChange) self.ui.sldrWrist2.valueChanged.connect(self.sliderChange) self.ui.sldrWrist3.valueChanged.connect(self.sliderChange) self.ui.sldrHand.valueChanged.connect(self.sliderChange) self.ui.sldrMaxTorque.valueChanged.connect(self.sliderChange) self.ui.sldrSpeed.valueChanged.connect(self.sliderChange) self.ui.chk_directcontrol.stateChanged.connect(self.directControlChk) self.ui.rdoutStatus.setText("Waiting for input") self.ui.btn_exec.clicked.connect( partial(self.sm.set_next_state, "execute")) self.ui.btnUser4.setText("TP test") self.ui.btnUser4.clicked.connect( partial(self.sm.set_next_state, "TP test")) self.ui.btnUser5.setText("Detect blocks") self.ui.btnUser5.clicked.connect( partial(self.sm.set_next_state, "Detect Blocks")) self.ui.btnUser11.setText("IK_set_pose") self.ui.btnUser11.clicked.connect( partial(self.sm.set_next_state, "IK_set_pose")) self.ui.btnUser12.setText("IK_Test") self.ui.btnUser12.clicked.connect( partial(self.sm.set_next_state, "IK_test")) self.ui.btnUser10.setText("Grab_Place") self.ui.btnUser10.clicked.connect( partial(self.sm.set_next_state, "Grab_Place")) self.ui.btnUser9.setText("BlockSlider") self.ui.btnUser9.clicked.connect( partial(self.sm.set_next_state, "BlockSlider")) self.ui.btnUser8.setText("Pick_N_Stack") self.ui.btnUser8.clicked.connect( partial(self.sm.set_next_state, "Pick_N_Stack")) """initalize manual control off""" self.ui.SliderFrame.setEnabled(False) """initalize rexarm""" self.rexarm.initialize() """Setup Threads""" self.videoThread = VideoThread(self.kinect) self.videoThread.updateFrame.connect(self.setImage) self.videoThread.start() self.logicThread = LogicThread(self.sm) self.logicThread.start() self.displayThread = DisplayThread(self.rexarm, self.sm) self.displayThread.updateJointReadout.connect(self.updateJointReadout) self.displayThread.updateEndEffectorReadout.connect( self.updateEndEffectorReadout) self.displayThread.updateStatusMessage.connect( self.updateStatusMessage) self.displayThread.start() """ Setup Timer this runs the trackMouse function every 50ms """ self._timer = QTimer(self) self._timer.timeout.connect(self.trackMouse) self._timer.start(50)
def multi_mode(cli_parsed): dbm = db_manager.DB_Manager(cli_parsed.d + '/ew.db') dbm.open_connection() if not cli_parsed.resume: dbm.initialize_db() dbm.save_options(cli_parsed) m = Manager() targets = m.Queue() lock = m.Lock() multi_counter = m.Value('i', 0) display = None def exitsig(*args): dbm.close() if current_process().name == 'MainProcess': print '' print 'Resume using ./EyeWitness.py --resume {0}'.format( cli_parsed.d + '/ew.db') os._exit(1) signal.signal(signal.SIGINT, exitsig) if cli_parsed.resume: pass else: url_list, rdp_list, vnc_list = target_creator(cli_parsed) if any((cli_parsed.web, cli_parsed.headless)): for url in url_list: dbm.create_http_object(url, cli_parsed) for rdp in rdp_list: dbm.create_vnc_rdp_object('rdp', rdp, cli_parsed) for vnc in vnc_list: dbm.create_vnc_rdp_object('vnc', vnc, cli_parsed) if any((cli_parsed.web, cli_parsed.headless)): if cli_parsed.web and not cli_parsed.show_selenium: display = Display(visible=0, size=(1920, 1080)) display.start() multi_total = dbm.get_incomplete_http(targets) if multi_total > 0: if cli_parsed.resume: print 'Resuming Web Scan ({0} Hosts Remaining)'.format( str(multi_total)) else: print 'Starting Web Requests ({0} Hosts)'.format( str(multi_total)) if multi_total < cli_parsed.threads: num_threads = multi_total else: num_threads = cli_parsed.threads for i in xrange(num_threads): targets.put(None) try: workers = [ Process(target=worker_thread, args=(cli_parsed, targets, lock, (multi_counter, multi_total))) for i in xrange(num_threads) ] for w in workers: w.start() for w in workers: w.join() except Exception as e: print str(e) # Set up UA table here if cli_parsed.cycle is not None: ua_dict = get_ua_values(cli_parsed.cycle) if not cli_parsed.ua_init: dbm.clear_table("ua") completed = dbm.get_complete_http() completed[:] = [x for x in completed if x.error_state is None] for item in completed: for browser, ua in ua_dict.iteritems(): dbm.create_ua_object(item, browser, ua) cli_parsed.ua_init = True dbm.clear_table("opts") dbm.save_options(cli_parsed) for browser, ua in ua_dict.iteritems(): targets = m.Queue() multi_counter.value = 0 multi_total = dbm.get_incomplete_ua(targets, browser) if multi_total > 0: print( "[*] Starting requests for User Agent {0}" " ({1} Hosts)").format(browser, str(multi_total)) if multi_total < cli_parsed.threads: num_threads = multi_total else: num_threads = cli_parsed.threads for i in xrange(num_threads): targets.put(None) workers = [ Process(target=worker_thread, args=(cli_parsed, targets, lock, (multi_counter, multi_total), (browser, ua))) for i in xrange(num_threads) ] for w in workers: w.start() for w in workers: w.join() if any((cli_parsed.vnc, cli_parsed.rdp)): log._LOG_LEVEL = log.Level.ERROR multi_total, targets = dbm.get_incomplete_vnc_rdp() if multi_total > 0: print '' print 'Starting VNC/RDP Requests ({0} Hosts)'.format( str(multi_total)) app = QtGui.QApplication(sys.argv) timer = QTimer() timer.start(10) timer.timeout.connect(lambda: None) # add qt4 reactor import qt4reactor qt4reactor.install() from twisted.internet import reactor for target in targets: if os.path.dirname(cli_parsed.d) != os.path.dirname( target.screenshot_path): target.set_paths(cli_parsed.d) tdbm = db_manager.DB_Manager(cli_parsed.d + '/ew.db') if target.proto == 'vnc': reactor.connectTCP( target.remote_system, target.port, vnc_module.RFBScreenShotFactory( target.screenshot_path, reactor, app, target, tdbm)) else: reactor.connectTCP( target.remote_system, int(target.port), rdp_module.RDPScreenShotFactory( reactor, app, 1200, 800, target.screenshot_path, cli_parsed.timeout, target, tdbm)) reactor.runReturn() app.exec_() if display is not None: display.stop() results = dbm.get_complete_http() vnc_rdp = dbm.get_complete_vnc_rdp() dbm.close() m.shutdown() write_vnc_rdp_data(cli_parsed, vnc_rdp) sort_data_and_write(cli_parsed, results) if cli_parsed.ocr: for target in targets: try: rdp_module.parse_screenshot(cli_parsed.d, target) except IOError: pass
class MinMaxSource(QObject): """ A datasource that serves as a normalizing decorator for other datasources. """ isDirty = pyqtSignal(object) boundsChanged = pyqtSignal( object ) # When a new min/max is discovered in the result of a request, this signal is fired with the new (dmin, dmax) def __init__(self, rawSource, parent=None): """ rawSource: The original datasource whose data will be normalized """ super(MinMaxSource, self).__init__(parent) self._rawSource = rawSource self._rawSource.isDirty.connect(self.isDirty) self._bounds = [1e9, -1e9] self._delayedDirtySignal = QTimer() self._delayedDirtySignal.setSingleShot(True) self._delayedDirtySignal.setInterval(10) self._delayedDirtySignal.timeout.connect( partial(self.setDirty, sl[:, :, :, :, :])) @property def dataSlot(self): if hasattr(self._rawSource, "_orig_outslot"): return self._rawSource._orig_outslot else: return None def dtype(self): return self._rawSource.dtype() def request(self, slicing): rawRequest = self._rawSource.request(slicing) return MinMaxUpdateRequest(rawRequest, self._getMinMax) def setDirty(self, slicing): self.isDirty.emit(slicing) def __eq__(self, other): equal = True if other is None: return False equal &= isinstance(other, MinMaxSource) equal &= (self._rawSource == other._rawSource) return equal def __ne__(self, other): return not (self == other) def _getMinMax(self, data): dmin = np.min(data) dmax = np.max(data) dmin = min(self._bounds[0], dmin) dmax = max(self._bounds[1], dmax) dirty = False if (self._bounds[0] - dmin) > 1e-2: dirty = True if (dmax - self._bounds[1]) > 1e-2: dirty = True if dirty: self._bounds[0] = min(self._bounds[0], dmin) self._bounds[1] = max(self._bounds[0], dmax) self.boundsChanged.emit(self._bounds) # Our min/max have changed, which means we must force the TileProvider to re-request all tiles. # If we simply mark everything dirty now, then nothing changes for the tile we just rendered. # (It was already dirty. That's why we are rendering it right now.) # And when this data gets back to the TileProvider that requested it, the TileProvider will mark this tile clean again. # To ENSURE that the current tile is marked dirty AFTER the TileProvider has stored this data (and marked the tile clean), # we'll use a timer to set everything dirty. # This fixes ilastik issue #418 # Finally, note that before this timer was added, the problem described above occurred at random due to a race condition: # Sometimes the 'dirty' signal was processed BEFORE the data (bad) and sometimes it was processed after the data (good), # due to the fact that the Qt signals are always delivered in the main thread. # Perhaps a better way to fix this would be to store a timestamp in the TileProvider for dirty notifications, which # could be compared with the request timestamp before clearing the dirty state for each tile. # Signal everything dirty with a timer, as described above. self._delayedDirtySignal.start() # Now, that said, we can still give a slightly more snappy response to the OTHER tiles (not this one) # if we immediately tell the TileProvider we are dirty. This duplicates some requests, but that shouldn't be a big deal. self.setDirty(sl[:, :, :, :, :])
class FileOutlineViewer( QWidget ): """ The file outline viewer widget """ def __init__( self, editorsManager, parent = None ): QWidget.__init__( self, parent ) self.__editorsManager = editorsManager self.__mainWindow = parent self.__editorsManager.currentChanged.connect( self.__onTabChanged ) self.connect( self.__editorsManager, SIGNAL( "tabClosed" ), self.__onTabClosed ) self.connect( self.__editorsManager, SIGNAL( 'bufferSavedAs' ), self.__onSavedBufferAs ) self.connect( self.__editorsManager, SIGNAL( 'fileTypeChanged' ), self.__onFileTypeChanged ) self.__outlineBrowsers = {} # UUID -> OutlineAttributes self.__currentUUID = None self.__updateTimer = QTimer( self ) self.__updateTimer.setSingleShot( True ) self.__updateTimer.timeout.connect( self.__updateView ) self.findButton = None self.outlineViewer = None self.toolbar = None self.__createLayout() self.__modifiedFormat = Settings().modifiedFormat # create the context menu self.__menu = QMenu( self ) self.__findMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'findusage.png' ), 'Find where used', self.__findWhereUsed ) return def setTooltips( self, switchOn ): " Sets the tooltips mode " for key in self.__outlineBrowsers: self.__outlineBrowsers[ key ].browser.setTooltips( switchOn ) return def __connectOutlineBrowser( self, browser ): " Connects a new buffer signals " browser.setContextMenuPolicy( Qt.CustomContextMenu ) browser.customContextMenuRequested.connect( self.__handleShowContextMenu ) self.connect( browser, SIGNAL( "selectionChanged" ), self.__selectionChanged ) return def __createLayout( self ): " Helper to create the viewer layout " # Toolbar part - buttons self.findButton = QAction( PixmapCache().getIcon( 'findusage.png' ), 'Find where highlighted item is used', self ) self.findButton.setVisible( False ) self.findButton.triggered.connect( self.__findWhereUsed ) self.showParsingErrorsButton = QAction( PixmapCache().getIcon( 'showparsingerrors.png' ), 'Show lexer/parser errors', self ) self.showParsingErrorsButton.triggered.connect( self.__showParserError ) self.showParsingErrorsButton.setEnabled( False ) self.toolbar = QToolBar( self ) self.toolbar.setMovable( False ) self.toolbar.setAllowedAreas( Qt.TopToolBarArea ) self.toolbar.setIconSize( QSize( 16, 16 ) ) self.toolbar.setFixedHeight( 28 ) self.toolbar.setContentsMargins( 0, 0, 0, 0 ) self.toolbar.addAction( self.findButton ) self.toolbar.addAction( self.showParsingErrorsButton ) # Prepare members for reuse self.__noneLabel = QLabel( "\nNot a python file" ) self.__noneLabel.setFrameShape( QFrame.StyledPanel ) self.__noneLabel.setAlignment( Qt.AlignHCenter ) headerFont = self.__noneLabel.font() headerFont.setPointSize( headerFont.pointSize() + 2 ) self.__noneLabel.setFont( headerFont ) self.__noneLabel.setAutoFillBackground( True ) noneLabelPalette = self.__noneLabel.palette() noneLabelPalette.setColor( QPalette.Background, GlobalData().skin.nolexerPaper ) self.__noneLabel.setPalette( noneLabelPalette ) self.__layout = QVBoxLayout() self.__layout.setContentsMargins( 0, 0, 0, 0 ) self.__layout.setSpacing( 0 ) self.__layout.addWidget( self.toolbar ) self.__layout.addWidget( self.__noneLabel ) self.setLayout( self.__layout ) return def __selectionChanged( self, index ): " Handles the changed selection " if index is None: self.__outlineBrowsers[ self.__currentUUID ].contentItem = None else: self.__outlineBrowsers[ self.__currentUUID ].contentItem = \ self.__outlineBrowsers[ self.__currentUUID ].browser.model().item( index ) self.__updateButtons() return def __handleShowContextMenu( self, coord ): """ Show the context menu """ browser = self.__outlineBrowsers[ self.__currentUUID ].browser index = browser.indexAt( coord ) if not index.isValid(): return # This will update the contextItem self.__selectionChanged( index ) contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem if contextItem is None: return self.__findMenuItem.setEnabled( self.findButton.isEnabled() ) self.__menu.popup( QCursor.pos() ) return def __goToDefinition( self ): " Jump to definition context menu handler " contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem if contextItem is not None: self.__outlineBrowsers[ self.__currentUUID ].browser.openItem( contextItem ) return def __findWhereUsed( self ): """ Find where used context menu handler """ contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem if contextItem is not None: GlobalData().mainWindow.findWhereUsed( contextItem.getPath(), contextItem.sourceObj ) return def __updateButtons( self ): " Updates the toolbar buttons depending on what is selected " self.findButton.setEnabled( False ) contextItem = self.__outlineBrowsers[ self.__currentUUID ].contentItem if contextItem is None: return if contextItem.itemType in [ FunctionItemType, ClassItemType, AttributeItemType, GlobalItemType ]: self.findButton.setEnabled( True ) return def __onTabChanged( self, index ): " Triggered when another tab becomes active " # If the timer is still active that means the tab was switched before # the handler had a chance to work. Therefore update the previous tab # first if so. if self.__updateTimer.isActive(): self.__updateTimer.stop() self.__updateView() # Now, switch the outline browser to the new tab if index == -1: widget = self.__editorsManager.currentWidget() else: widget = self.__editorsManager.getWidgetByIndex( index ) if widget is None: if self.__currentUUID is not None: self.__outlineBrowsers[ self.__currentUUID ].browser.hide() self.__currentUUID = None self.__noneLabel.show() self.showParsingErrorsButton.setEnabled( False ) return if widget.getType() not in [ MainWindowTabWidgetBase.PlainTextEditor, MainWindowTabWidgetBase.VCSAnnotateViewer ]: if self.__currentUUID is not None: self.__outlineBrowsers[ self.__currentUUID ].browser.hide() self.__currentUUID = None self.__noneLabel.show() self.showParsingErrorsButton.setEnabled( False ) return # This is text editor, detect the file type if widget.getFileType() not in [ PythonFileType, Python3FileType ]: if self.__currentUUID is not None: self.__outlineBrowsers[ self.__currentUUID ].browser.hide() self.__currentUUID = None self.__noneLabel.show() self.showParsingErrorsButton.setEnabled( False ) return # This is a python file, check if we already have the parsed info in # the cache uuid = widget.getUUID() if uuid in self.__outlineBrowsers: # We have it, hide the current and show the existed if self.__currentUUID is not None: self.__outlineBrowsers[ self.__currentUUID ].browser.hide() self.__currentUUID = None else: self.__noneLabel.hide() self.__currentUUID = uuid self.__outlineBrowsers[ self.__currentUUID ].browser.show() info = self.__outlineBrowsers[ self.__currentUUID ].info self.showParsingErrorsButton.setEnabled( info.isOK != True ) return # It is first time we are here, create a new editor = widget.getEditor() editor.SCEN_CHANGE.connect( self.__onBufferChanged ) editor.cursorPositionChanged.connect( self.__cursorPositionChanged ) info = getBriefModuleInfoFromMemory( editor.text() ) self.showParsingErrorsButton.setEnabled( info.isOK != True ) shortFileName = widget.getShortName() browser = OutlineBrowser( uuid, shortFileName, info, self ) browser.setHeaderHighlight( info.isOK != True ) self.__connectOutlineBrowser( browser ) self.__layout.addWidget( browser ) if self.__currentUUID is not None: self.__outlineBrowsers[ self.__currentUUID ].browser.hide() self.__currentUUID = None else: self.__noneLabel.hide() self.__currentUUID = uuid attributes = OutlineAttributes() attributes.browser = browser attributes.contextItem = None attributes.info = info attributes.shortFileName = shortFileName attributes.changed = False self.__outlineBrowsers[ self.__currentUUID ] = attributes self.__outlineBrowsers[ self.__currentUUID ].browser.show() return def getCurrentUsedInfo( self ): " Provides the info used to show the current outline window " if self.__currentUUID in self.__outlineBrowsers: return self.__outlineBrowsers[ self.__currentUUID ].info return None def __cursorPositionChanged( self, xpos, ypos ): " Triggered when a cursor position is changed " if self.__updateTimer.isActive(): # If a file is very large and the cursor is moved # straight after changes this will delay the update till # the real pause. self.__updateTimer.stop() self.__updateTimer.start( 1500 ) return def __onBufferChanged( self ): " Triggered when a change in the buffer is identified " if self.__currentUUID is None: return widget = self.__editorsManager.getWidgetByUUID( self.__currentUUID ) if widget is None: return if widget.getEditor().ignoreBufferChangedSignal: return if self.__mainWindow.debugMode: return self.__updateTimer.stop() if self.__currentUUID in self.__outlineBrowsers: if self.__outlineBrowsers[ self.__currentUUID ].changed == False: self.__outlineBrowsers[ self.__currentUUID ].changed = True browser = self.__outlineBrowsers[ self.__currentUUID ].browser fName = self.__outlineBrowsers[ self.__currentUUID ].shortFileName title = self.__modifiedFormat % fName browser.model().sourceModel().updateRootData( 0, title ) self.__updateTimer.start( 1500 ) return def __updateView( self ): " Updates the view when a file is changed " self.__updateTimer.stop() info = self.getCurrentBufferInfo() if info is None: return self.showParsingErrorsButton.setEnabled( info.isOK != True ) browser = self.__outlineBrowsers[ self.__currentUUID ].browser fName = self.__outlineBrowsers[ self.__currentUUID ].shortFileName browser.setHeaderHighlight( info.isOK != True ) if not info.isOK: title = self.__modifiedFormat % fName browser.model().sourceModel().updateRootData( 0, title ) return browser.model().sourceModel().updateRootData( 0, fName ) self.__outlineBrowsers[ self.__currentUUID ].changed = False browser.updateFileItem( browser.model().sourceModel().rootItem, info ) self.__outlineBrowsers[ self.__currentUUID ].info = info return def getCurrentBufferInfo( self ): " Provides the current buffer parsed info " if self.__currentUUID is None: return None widget = self.__editorsManager.getWidgetByUUID( self.__currentUUID ) if widget is None: return None editor = widget.getEditor() info = getBriefModuleInfoFromMemory( editor.text() ) return info def __onTabClosed( self, uuid ): " Triggered when a tab is closed " if uuid in self.__outlineBrowsers: del self.__outlineBrowsers[ uuid ] return def __onSavedBufferAs( self, fileName, uuid ): " Triggered when a file is saved with a new name " if uuid in self.__outlineBrowsers: baseName = os.path.basename( fileName ) if detectFileType( fileName ) not in [ PythonFileType, Python3FileType ]: # It's not a python file anymore if uuid == self.__currentUUID: self.__outlineBrowsers[ uuid ].browser.hide() self.__noneLabel.show() self.__currentUUID = None del self.__outlineBrowsers[ uuid ] self.showParsingErrorsButton.setEnabled( False ) self.findButton.setEnabled( False ) return # Still python file with a different name browser = self.__outlineBrowsers[ uuid ].browser self.__outlineBrowsers[ uuid ].shortFileName = baseName if self.__outlineBrowsers[ uuid ].changed: title = self.__modifiedFormat % baseName else: title = baseName browser.model().sourceModel().updateRootData( 0, title ) return def __onFileTypeChanged( self, fileName, uuid, newFileType ): " Triggered when the current buffer file type is changed, e.g. .cgi " if newFileType in [ PythonFileType, Python3FileType ]: # The file became a python one if uuid not in self.__outlineBrowsers: self.__onTabChanged( -1 ) else: if uuid in self.__outlineBrowsers: # It's not a python file any more if uuid == self.__currentUUID: self.__outlineBrowsers[ uuid ].browser.hide() self.__noneLabel.show() self.__currentUUID = None del self.__outlineBrowsers[ uuid ] self.showParsingErrorsButton.setEnabled( False ) self.findButton.setEnabled( False ) return def __showParserError( self ): " Shows the parser errors window " if self.__currentUUID is None: return try: fName = self.__outlineBrowsers[ self.__currentUUID ].shortFileName widget = self.__editorsManager.getWidgetByUUID( self.__currentUUID ) if widget is None: return editor = widget.getEditor() info = getBriefModuleInfoFromMemory( editor.text() ) dialog = ParserErrorsDialog( fName, info ) dialog.exec_() except Exception, ex: logging.error( str( ex ) ) return
def initValues(self): # print self.hw.servername # print self.hw.basepath self.inputmatrix = MatrixMixer( self.hw.servername, self.hw.basepath + "/Mixer/InputFaders", self, 0x8000, self.hw.basepath + "/Mixer/InputMutes", self.hw.basepath + "/Mixer/InputInverts", True) layout = QtGui.QVBoxLayout() scrollarea = QtGui.QScrollArea() scrollarea.setWidgetResizable(True) scrollarea.setWidget(self.inputmatrix) layout.addWidget(scrollarea) self.mixer.setLayout(layout) self.playbackmatrix = MatrixMixer( self.hw.servername, self.hw.basepath + "/Mixer/PlaybackFaders", self, 0x8000, self.hw.basepath + "/Mixer/PlaybackMutes", self.hw.basepath + "/Mixer/PlaybackInverts", True) layout = QtGui.QVBoxLayout() scrollarea = QtGui.QScrollArea() scrollarea.setWidgetResizable(True) scrollarea.setWidget(self.playbackmatrix) layout.addWidget(scrollarea) self.playbackmixer.setLayout(layout) self.outputmatrix = MatrixMixer( self.hw.servername, self.hw.basepath + "/Mixer/OutputFaders", self, 0x8000, self.hw.basepath + "/Mixer/OutputMutes", None, True) layout = QtGui.QVBoxLayout() scrollarea = QtGui.QScrollArea() scrollarea.setWidget(self.outputmatrix) scrollarea.setWidgetResizable(True) # This is a bit of a hack, but it works to ensure this single-row # matrix mixer doesn't fill the entire screen but also doesn't end # up with a pointless scrollbar. The matrix mixer's minimum height # is 0 according to minimumHeight(), which is probably the # fundamental issue here; however, I've already wasted too much time # trying to get this to work so if the hack is effective we'll run # with it. scrollarea.setMinimumHeight(150) layout.addWidget(scrollarea, 0, Qt.AlignTop) self.outputmixer.setLayout(layout) self.is_streaming = False self.last_streaming_state = False # Retrieve other device settings as needed and customise the UI # based on these options. self.model = self.hw.getDiscrete('/Control/Model') log.debug("device model identifier: %d" % (self.model)) self.tco_present = self.hw.getDiscrete('/Control/TCO_present') log.debug("device has TCO: %d" % (self.tco_present)) #self.sample_rate = self.hw.getDiscrete('/Mixer/Info/SampleRate') #log.debug("device sample rate: %d" % (self.sample_rate)) # The Fireface-400 only has 2 phantom-capable channels if (self.model == RME_MODEL_FF400): self.disable_hide(self.phantom_2) self.disable_hide(self.phantom_3) else: self.phantom_0.setText("Mic 7") self.phantom_1.setText("Mic 8") self.phantom_2.setText("Mic 9") self.phantom_3.setText("Mic 10") # Instrument options, input jack selection controls and an ADAT2 # input are applicable only to the FF800 if (self.model != RME_MODEL_FF800): self.instrument_options_group.setEnabled(False) self.input_plug_select_group.setEnabled(False) self.sync_ref_adat2.setEnabled(False) self.sync_check_adat2_label.setEnabled(False) self.sync_check_adat2_status.setEnabled(False) for ctrl, info in self.Combos.iteritems(): if (not (ctrl.isEnabled())): continue val = self.hw.getDiscrete(info[0]) log.debug("combo %s is %d" % (info[0], val)) ctrl.setCurrentIndex(val) QObject.connect(ctrl, SIGNAL('currentIndexChanged(int)'), self.updateCombo) if (not (self.tco_present)): self.sync_check_tco_label.setEnabled(False) self.sync_check_tco_status.setEnabled(False) self.sync_ref_tco.setEnabled(False) # Only the FF400 has specific channel 3/4 options, input gain # controls and switchable phones level if (self.model != RME_MODEL_FF400): self.disable_hide(self.input_gains_group) self.disable_hide(self.channel_3_4_options_group) self.phones_level_group.setEnabled(False) # Add the "No ADAT-2" item to the bandwidth limit control if the # device is not a FF400. Set the control to reflect the current # device setting and connect an update signal. if (self.model != RME_MODEL_FF400): self.bandwidth_limit.insertItem(1, "No ADAT-2") val = self.hw.getDiscrete('/Control/Bandwidth_limit') if (self.model == RME_MODEL_FF400 and val > 1): val = val - 1 self.bandwidth_limit.setCurrentIndex(val) QObject.connect(self.bandwidth_limit, SIGNAL('currentIndexChanged(int)'), self.updateBandwidthLimit) # Get current hardware values and connect GUI element signals to # their respective slots for ctrl, info in self.PhantomSwitches.iteritems(): if (not (ctrl.isEnabled())): continue val = (self.hw.getDiscrete(info[0]) >> info[1]) & 0x01 log.debug("phantom switch %d is %d" % (info[1], val)) if val: ctrl.setChecked(True) else: ctrl.setChecked(False) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updatePhantomSwitch) for ctrl, info in self.Switches.iteritems(): if (not (ctrl.isEnabled())): continue val = self.hw.getDiscrete(info[0]) log.debug("switch %s is %d" % (info[0], val)) if val: ctrl.setChecked(True) else: ctrl.setChecked(False) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateSwitch) for ctrl, info in self.Radiobuttons.iteritems(): if (not (ctrl.isEnabled())): continue # This is a touch wasteful since it means we retrieve the control # value once per radio button rather than once per radio button # group. In time we might introduce radiobutton groupings in the # self.* datastructures to avoid this, but for the moment this is # easy and it works. val = self.hw.getDiscrete(info[0]) if (val == info[1]): val = 1 else: val = 0 ctrl.setChecked(val) log.debug("Radiobutton %s[%d] is %d" % (info[0], info[1], val)) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateRadiobutton) for ctrl, info in self.Checkboxes.iteritems(): if (not (ctrl.isEnabled())): continue # This is a touch wasteful since it means we retrieve the control # value once per checkbox button rather than once per checkbox # group. In time we might introduce checkbox groupings in the # self.* datastructures to avoid this, but for the moment this is # easy and it works. val = self.hw.getDiscrete(info[0]) if (val & info[1]): val = 1 else: val = 0 ctrl.setChecked(val) log.debug("Checkbox %s[%d] is %d" % (info[0], info[1], val)) QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateCheckboxes) for ctrl, info in self.Gains.iteritems(): if (not (ctrl.isEnabled())): continue val = self.hw.getMatrixMixerValue(info[0], 0, info[1]) log.debug("gain %s[%d] is %d" % (info[0], info[1], val)) ctrl.setValue(val) QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateGain) self.updateStreamingState() #log.debug("device streaming flag: %d" % (self.is_streaming)) self.update_timer = QTimer(self) QObject.connect(self.update_timer, SIGNAL('timeout()'), self.status_update) self.update_timer.start(1000)
# image then we show a one on the top left corner #=========================================================================== from ilastik.widgets.boxListView import BoxListView from PyQt4.QtGui import QWidget app = QApplication([]) boxListModel = BoxListModel() h, w = (500, 500) LV = BoxListView() LV.setModel(boxListModel) LV._table.setShowGrid(True) g = Graph() cron = QTimer() cron.start(500 * 100) op = OpArrayPiper2(graph=g) #Generate random noise shape = (1, w, h, 1, 1) #array = np.random.randint(0,255,500*500).reshape(shape).astype(np.uint8) import scipy array = scipy.misc.lena().astype(np.uint8) array = vigra.sampling.resize(array.astype(np.float32), (h, w)).reshape(shape).astype(np.uint8) op.Input.setValue(array) def do(): #Generate #array[:] = np.random.randint(0,255,500*500).reshape(shape).astype(np.uint8)
def ttest_populateParameters_changeParamter_value(self): fun = sys._getframe().f_code.co_name print "Run: %s.%s() " % (self.__class__.__name__, fun) parent = None self.form = DataSourceDlg(parent) self.form.show() self.form.ui.setupUi(self.form) self.enableButtons() self.form.ui.typeComboBox.setCurrentIndex( self.form.ui.typeComboBox.findText("")) self.form.ui.dQueryLineEdit.setText("") self.enableButtons() self.form.connectWidgets() myParam = { "DB name": "sdfsdf", "DB host": "wer", "DB port": "wwer", "DB user": "******", "DB password": "******", "Mysql cnf": "weer", "Oracle mode": "wwer", "Oracle DSN": "aasdf" } table = self.form.ui.dParameterTableWidget na = self.__rnd.randint(0, len(myParam) - 1) sel = myParam.keys()[na] sel = "DB password" self.form.dbParam = dict(myParam) self.form.populateParameters(sel) self.checkParam(myParam, table, sel) if sel == "DB password": QTimer.singleShot(10, self.checkMessageBox) self.form.ui.dParamComboBox.setCurrentIndex( self.form.ui.dParamComboBox.findText(str(sel))) ch = table.currentRow() QTest.mouseClick(self.form.ui.dAddPushButton, Qt.LeftButton) item = table.item(ch, 0) pname = str(item.data(Qt.UserRole).toString()) it = QTableWidgetItem(unicode(pname)) it.setData(Qt.DisplayRole, QVariant("Myname2")) it.setData(Qt.UserRole, QVariant(pname)) table.setItem(ch, 0, it) self.checkParam(dict(myParam, **{str(sel): "Myname2"}), self.form.ui.dParameterTableWidget, None) self.checkParam(dict(myParam, **{str(sel): "Myname2"}), self.form.ui.dParameterTableWidget, None) self.assertEqual(self.form.dbParam, dict(myParam, **{str(sel): "Myname2"})) table.setCurrentCell(ch, 0) QTimer.singleShot(10, self.rmParamWidgetClose) QTest.mouseClick(self.form.ui.dRemovePushButton, Qt.LeftButton) self.checkParam(dict(myParam, **{str(sel): "Myname2"}), self.form.ui.dParameterTableWidget, str(sel)) self.assertEqual(self.form.dbParam, dict(myParam, **{str(sel): "Myname2"})) QTimer.singleShot(10, self.rmParamWidget) it = table.item(table.currentRow(), 0) QTest.mouseClick(self.form.ui.dRemovePushButton, Qt.LeftButton) rparam = dict(myParam) del rparam[sel] self.checkParam(rparam, self.form.ui.dParameterTableWidget, None) self.assertEqual(self.form.dbParam, dict(rparam))
def __init__(self, parent, plot): super().__init__(parent, plot) self.__timer = QTimer(self, interval=50) self.__timer.timeout.connect(self.__timout) self.__count = itertools.count() self.__pos = None
def autoScroll(self): """ On autoscroll """ QTimer.singleShot(0, self.scrollToBottom)
def __init__(self): QCoreApplication.__init__(self, []) self.timer = QTimer() self.timer.timeout.connect(self.test) self.timer.start(0)
def __init__(self, datadir=None, logdir=None): DistUpgradeView.__init__(self) # silence the PyQt4 logger logger = logging.getLogger("PyQt4") logger.setLevel(logging.INFO) if not datadir or datadir == '.': localedir=os.path.join(os.getcwd(),"mo") else: localedir="/usr/share/locale/ubuntu-release-upgrader" # FIXME: i18n must be somewhere relative do this dir try: gettext.bindtextdomain("ubuntu-release-upgrader", localedir) gettext.textdomain("ubuntu-release-upgrader") except Exception as e: logging.warning("Error setting locales (%s)" % e) #about = KAboutData("adept_manager","Upgrader","0.1","Dist Upgrade Tool for Kubuntu",KAboutData.License_GPL,"(c) 2007 Canonical Ltd", #"http://wiki.kubuntu.org/KubuntuUpdateManager", "*****@*****.**") #about.addAuthor("Jonathan Riddell", None,"*****@*****.**") #about.addAuthor("Michael Vogt", None,"*****@*****.**") #KCmdLineArgs.init(["./dist-upgrade.py"],about) # we test for DISPLAY here, QApplication does not throw a # exception when run without DISPLAY but dies instead if not "DISPLAY" in os.environ: raise Exception("No DISPLAY in os.environ found") self.app = QApplication(["ubuntu-release-upgrader"]) if os.path.exists("/usr/share/icons/oxygen/48x48/apps/system-software-update.png"): messageIcon = QPixmap("/usr/share/icons/oxygen/48x48/apps/system-software-update.png") else: messageIcon = QPixmap("/usr/share/icons/hicolor/48x48/apps/adept_manager.png") self.app.setWindowIcon(QIcon(messageIcon)) self.window_main = UpgraderMainWindow() self.window_main.setParent(self) self.window_main.show() self.prev_step = 0 # keep a record of the latest step self._opCacheProgress = KDEOpProgress(self.window_main.progressbar_cache, self.window_main.progress_text) self._acquireProgress = KDEAcquireProgressAdapter(self) self._cdromProgress = KDECdromProgressAdapter(self) self._installProgress = KDEInstallProgressAdapter(self) # reasonable fault handler sys.excepthook = self._handleException self.window_main.showTerminalButton.setEnabled(False) self.app.connect(self.window_main.showTerminalButton, SIGNAL("clicked()"), self.showTerminal) #kdesu requires us to copy the xauthority file before it removes it when Adept is killed fd, copyXauth = tempfile.mkstemp("", "adept") if 'XAUTHORITY' in os.environ and os.environ['XAUTHORITY'] != copyXauth: shutil.copy(os.environ['XAUTHORITY'], copyXauth) os.environ["XAUTHORITY"] = copyXauth # Note that with kdesudo this needs --nonewdcop ## create a new DCOP-Client: #client = DCOPClient() ## connect the client to the local DCOP-server: #client.attach() #for qcstring_app in client.registeredApplications(): # app = str(qcstring_app) # if app.startswith("adept"): # adept = DCOPApp(qcstring_app, client) # adeptInterface = adept.object("MainApplication-Interface") # adeptInterface.quit() # This works just as well subprocess.call(["killall", "adept_manager"]) subprocess.call(["killall", "adept_updater"]) # init gettext gettext.bindtextdomain("ubuntu-release-upgrader",localedir) gettext.textdomain("ubuntu-release-upgrader") self.translate_widget_children() self.window_main.label_title.setText(self.window_main.label_title.text().replace("Ubuntu", "Kubuntu")) # setup terminal text in hidden by default spot self.window_main.konsole_frame.hide() self.konsole_frame_layout = QHBoxLayout(self.window_main.konsole_frame) self.window_main.konsole_frame.setMinimumSize(600, 400) self.terminal_text = DumbTerminal(self._installProgress, self.window_main.konsole_frame) self.konsole_frame_layout.addWidget(self.terminal_text) self.terminal_text.show() # for some reason we need to start the main loop to get everything displayed # this app mostly works with processEvents but run main loop briefly to keep it happily displaying all widgets QTimer.singleShot(10, self.exitMainLoop) self.app.exec_()