Пример #1
0
 def statusBarTimer(self):
   q = self.q
   ret = QTimer(q)
   ret.setSingleShot(True)
   ret.setInterval(5000)
   ret.timeout.connect(q.statusBar().hide)
   return ret
class ColumnResizer(QObject):
	def __init__(self):
		super(ColumnResizer, self).__init__()

		self._widgets = []
		self._gridColumnInfoList = []
		self._updateTimer = QTimer(self)
		self._updateTimer.setSingleShot(True)
		self._updateTimer.setInterval(0)
		self._updateTimer.timeout.connect(self._updateWidth)

	# Public methods

	def addWidgetsFromLayout(self, layout, column):
		"""
		:type layout: QGridLayout
		:type column: int
		"""
		assert column >= 0
		if isinstance(layout, QGridLayout):
			self._addWidgetsFromGridLayout(layout, column)
		else:
			print "ColumnResizerResizer does not support layouts of type:", type(layout)

	def eventFilter(self, obj, event):
		"""
		Overrides QObject.eventFilter()
		"""
		if event.type() == QEvent.Resize:
			self._scheduleWidthUpdate()
		return False

	# Private methods

	@Slot()
	def _updateWidth(self):
		width = 0
		for widget in self._widgets:
			width = max(widget.sizeHint().width(), width)
		for info in self._gridColumnInfoList:
			info[0].setColumnMinimumWidth(info[1], width)

	def _addWidget(self, widget):
		self._widgets.append(widget)
		widget.installEventFilter(self)
		self._scheduleWidthUpdate()

	def _addWidgetsFromGridLayout(self, layout, column):
		for row in range(layout.rowCount()):
			item = layout.itemAtPosition(row, column)
			if not item:
				continue
			widget = item.widget()
			if not widget:
				continue
			self._addWidget(widget)
		self._gridColumnInfoList.append([layout, column])

	def _scheduleWidthUpdate(self):
		self._updateTimer.start()
Пример #3
0
    class _SkWindowObject(object):
        def __init__(self, q, wid=0, pyobj=None):
            if not pyobj:
                pyobj = SkWindowPyObject(wid)
            self.obj = pyobj
            self.valid = self.obj.valid

            # Refresh timer
            self.refreshTimer = QTimer(q)
            self.refreshTimer.setInterval(200)
            self.refreshTimer.timeout.connect(q.refresh)

            self.refreshCount = 0  # int

        def reset(self):
            """Reset cached fields"""
            self.valid = False
            if hasattr(self, 'geometry'):
                del self.geometry
            if hasattr(self, 'visible'):
                del self.visible
            if hasattr(self, 'windowState'):
                del self.windowState
            if hasattr(self, 'contentSize'):
                del self.contentSize

        def updateWindowState(self):
            self.windowState = (
                Qt.WindowFullScreen if self.obj.fullscreen else
                Qt.WindowMinimized if self.obj.minimized else Qt.WindowNoState)
Пример #4
0
    def __init__(self, process, input_queue, output_queue):
        super(MainWidget, self).__init__()
        self.done = False
        layout = QtGui.QVBoxLayout()

        logo = QtGui.QLabel()
        logo.setPixmap('./data/logo.png')
        logo.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
        layout.addWidget(logo)

        status_list = self.status_list = QtGui.QListWidget()
        status_list.addItem('Chowdren, the blazingly fast runtime for '
                            'Clickteam Fusion.')
        status_list.addItem(u'Copyright (c) Mathias K\xe6rlev 2012-2015.')
        status_list.addItem('Applications made with Chowdren are subject to '
                            'the GNU General Public License.')

        layout.addWidget(status_list)

        self.setLayout(layout)

        timer = QTimer(self)
        timer.setInterval(100)
        timer.timeout.connect(self.process_console)
        timer.start()

        self.process = process
        self.output_queue = output_queue
        self.input_queue = input_queue

        self.log = open('chowdrenlog.txt', 'wb')
Пример #5
0
class RecomenDesktopApp(TaskTrayApp):
    def __init__(self, parent=None):
        super(RecomenDesktopApp, self).__init__(parent)

        # :: DBへのアップデートチェック
        self.updateChecker = DBUpdateChecker()
        self.updateChecker.start()

        self.updateChecker.finished.connect(self.add_news)

        # :: DBの新規更新の定期チェック
        self.updateCheck_timer = QTimer()
        self.updateCheck_timer.setInterval(10)

        self.stack = []

    @Slot()
    def add_news(self, news):
        print "add_news"
        if not news.hasupdate:
            return

        for new in news.get_datas():
            if new in self.get_local_db():
                print "Non News late"
                continue
            self.add_stack(new)
            print "add stack"

    def add_stack(self, n):
        self.stack.append(n)


    def get_local_db(self):
        return [2,3,4,5]
Пример #6
0
class Mlt(QtCore.QThread):
    s_producer_update = QtCore.Signal(object)
    s_play = QtCore.Signal(object)
    s_stop = QtCore.Signal(object)
    s_seek = QtCore.Signal(object)

    def __init__(self, parent=None):
        super(Mlt, self).__init__()
        self.parent = parent
        self.consumer = None
        self.producer = None
        self.movie_file = None
        self.profile = None

        self.position_timer = QTimer()
        self.position_timer.setInterval(125)
        self.position_timer.timeout.connect(self.onPositionTimeout)

    def onPositionTimeout(self):
        self.s_producer_update.emit(self.producer)

    def run(self):
        """
        starts thread
        """
        try:
            self.setup()
        except RuntimeError, err:
            print 'ERROR: Mlt.run: starting thread:', err
            self.quit()
class Panel(QWidget):
    def __init__(self, parent=None, instr=None, lock=None, title="Instrument Panel"):
        # This class derivates from a Qt Widget so we have to call
        # the class builder ".__init__()"
        QWidget.__init__(self)
        # "self" is now a Qt Widget, then we load the user interface
        # generated with QtDesigner and call it self.ui
        self.ui = Keithley6221_Ui.Ui_Panel()
        # Now we have to feed the GUI building method of this object (self.ui)
        # with the current Qt Widget 'self', but the widgets from the design will actually be built as children
        # of the object self.ui
        self.ui.setupUi(self)
        self.setWindowTitle(title)
        self.reserved_access_to_instr = lock
        self.instr = instr
        self.monitor_timer = QTimer()
        # The timer would not wait for the completion of the task otherwise
        self.monitor_timer.setSingleShot(True)
        self.monitor_timer.timeout.connect(self.monitor)
        self.firsttime = 0
        # bug: if the box is checked in the .ui file, the system freezes
        # if self.ui.monitor.isChecked():self.monitor()

    def monitor(self, state=1):
        if state != 1:
            self.monitor_timer.stop()
        elif state and not (self.monitor_timer.isActive()):
            with self.reserved_access_to_instr:
                I = self.instr.query_current_source_amplitude()
                Vcomp = self.instr.query_voltage_compliance()
                outstate = self.instr.query_output_ON()
            self.ui.I_disp.setText(str(I * 1e6) + u" μA")
            self.ui.V_disp.setText(str(Vcomp) + " V")
            self.ui.outputON.setChecked(outstate)
            self.monitor_timer.start(self.ui.refresh_rate.value() * 1000)

    def update_timer_timeout(self, secs):
        # The value must be converted to milliseconds
        self.monitor_timer.setInterval(secs * 1000)

    def change_I(self, value=0):
        with self.reserved_access_to_instr:
            self.instr.set_current_source_amplitude(value * 1e6)

    def change_V_comp(self, value=0):
        with self.reserved_access_to_instr:
            self.instr.set_voltage_compliance(value)

    def switch_output(self, value=False):
        if value:
            with self.reserved_access_to_instr:
                self.instr.output_ON()
        else:
            with self.reserved_access_to_instr:
                self.instr.output_OFF()

    def reset_inst(self):
        with self.reserved_access_to_instr:
            self.instr.reset()
Пример #8
0
class PhotoListModel(QAbstractListModel):
    URL_ROLE = Qt.UserRole + 1
    IMAGE_URL_ROLE = Qt.UserRole + 2
    HEIGHT_ROLE = Qt.UserRole + 3
    WIDTH_ROLE = Qt.UserRole + 4

    def __init__(self, album, parent=None):
        super(PhotoListModel, self).__init__(parent)
        self._album = album
        self._photos = []
        self._cache = []
        self._done = False
        keys = {}
        keys[PhotoListModel.URL_ROLE] = "url"
        keys[PhotoListModel.IMAGE_URL_ROLE] = "imageUrl"
        keys[PhotoListModel.HEIGHT_ROLE] = "height"
        keys[PhotoListModel.WIDTH_ROLE] = "width"
        self.setRoleNames(keys)
        self._load = PhotoLoad(self)
        self._load.start()
        self._timer = QTimer()
        self._timer.setInterval(1000)
        self._timer.timeout.connect(self.loadCache)
        self._timer.start()

    def rowCount(self, index):
        return len(self._photos)

    def appendCache(self, itens):
        self._cache += itens

    def loadCache(self):
        self.beginInsertRows(QModelIndex(), len(self._photos),
                             len(self._photos) + len(self._cache))
        self._photos += self._cache
        self.endInsertRows()
        self._cache = []
        if self._done:
            self._timer.stop()

    def data(self, index, role):
        if not index.isValid():
            return None

        if index.row() > len(self._photos):
            return None

        img = self._photos[index.row()]
        if role == PhotoListModel.URL_ROLE:
            return img.url
        elif role == PhotoListModel.IMAGE_URL_ROLE:
            return img.imageUrl
        elif role == PhotoListModel.HEIGHT_ROLE:
            return img.height
        elif role == PhotoListModel.WIDTH_ROLE:
            return img.width
        else:
            return None
Пример #9
0
class PhotoListModel(QAbstractListModel):
    URL_ROLE = Qt.UserRole + 1
    IMAGE_URL_ROLE = Qt.UserRole + 2
    HEIGHT_ROLE = Qt.UserRole + 3
    WIDTH_ROLE = Qt.UserRole + 4

    def __init__(self, album, parent=None):
        super(PhotoListModel, self).__init__(parent)
        self._album = album
        self._photos = []
        self._cache = []
        self._done = False
        keys = {}
        keys[PhotoListModel.URL_ROLE] = "url"
        keys[PhotoListModel.IMAGE_URL_ROLE] = "imageUrl"
        keys[PhotoListModel.HEIGHT_ROLE] = "height"
        keys[PhotoListModel.WIDTH_ROLE] = "width"
        self.setRoleNames(keys)
        self._load = PhotoLoad(self)
        self._load.start()
        self._timer = QTimer()
        self._timer.setInterval(1000)
        self._timer.timeout.connect(self.loadCache)
        self._timer.start()

    def rowCount(self, index):
        return len(self._photos)

    def appendCache(self, itens):
        self._cache += itens

    def loadCache(self):
        self.beginInsertRows(QModelIndex(), len(self._photos), len(self._photos) + len(self._cache))
        self._photos += self._cache
        self.endInsertRows()
        self._cache = []
        if self._done:
            self._timer.stop()

    def data(self, index, role):
        if not index.isValid():
            return None

        if index.row() > len(self._photos):
            return None

        img = self._photos[index.row()]
        if role == PhotoListModel.URL_ROLE:
            return img.url
        elif role == PhotoListModel.IMAGE_URL_ROLE:
            return img.imageUrl
        elif role == PhotoListModel.HEIGHT_ROLE:
            return img.height
        elif role == PhotoListModel.WIDTH_ROLE:
            return img.width
        else:
            return None
Пример #10
0
class Watcher(QObject):

    fileDeleted = Signal((str,str,))
    fileAdded = Signal((str,str,))
    fileChanged = Signal((str,str,bool,))
    checked = Signal()
    ioError = Signal((str,))
    
    TOLERANCE = 15
    
    def __init__(self, parent=None):
        super(Watcher, self).__init__(parent)
       
        self.fileAdded.connect(self.added)
        self.fileChanged.connect(self.changed)
        self.fileDeleted.connect(self.deleted)
       
    @Slot()
    def checkout(self):
        raise NotImplementedError
    
    @Slot()
    def startCheckout(self):
        self.checkTimer = QTimer()
        self.checkTimer.setInterval(self.interval)
        self.checkTimer.timeout.connect(self.checkout)
        
        self.checkTimer.start()
        
    @Slot(str, str)
    def added(self, location, serverpath):
        print 'Added {0}: {1}'.format(self.LOCATION, serverpath)
        
    @Slot(str, str)
    def changed(self, location, serverpath):
        print 'Changed {0}: {1}'.format(self.LOCATION, serverpath)
        
    @Slot(str, str)
    def deleted(self, location, serverpath):
        print 'Deleted {0}: {1}'.format(self.LOCATION, serverpath)

    def localFromServer(self, serverpath):
        # Removing leading '/' so `os.path.join` doesn't treat
        # `localpath` as an absolute path
        localpath = serverpath[1:] if serverpath.startswith('/') else serverpath
        localpath = QDir.toNativeSeparators(localpath)
        localpath = os.path.join(self.localdir, localpath)
        
        return localpath
        
    def serverFromLocal(self, localpath):
        serverpath = localpath.replace(self.localdir, '')
        serverpath = QDir.fromNativeSeparators(serverpath)
        
        return serverpath
Пример #11
0
 def onLoopRequested(loopRequest):
     print 'l: ', l
     if l:
         l.pop()
         led.toggle(not led.isToggled())
     ledTimer = QTimer(toggleObject)
     ledTimer.setSingleShot(True)
     ledTimer.setInterval(200)
     ledTimer.timeout.connect(
         partial(loopRequest.completeRequest, True if l else False))
     ledTimer.start()
     if not l: l.extend(range(20))
Пример #12
0
class Reader(QThread):
    data = Signal(Meter)
    warning = Signal(str)
    error = Signal(str)

    def __init__(self, port):
        QThread.__init__(self)

        self._port = port
        self._serial = None
        self._parser = Parser()
        self._cancel = False
        self._timeout = None

    def run(self):
        self._timeout = QTimer()
        self._timeout.setInterval(2000)
        self._timeout.timeout.connect(self.__onTimeout)

        try:
            self._serial = serial.Serial(self._port,
                                         baudrate=19200,
                                         bytesize=serial.SEVENBITS,
                                         stopbits=serial.STOPBITS_ONE,
                                         parity=serial.PARITY_ODD,
                                         timeout=1)
            self._serial.dtr = True
            self._serial.rts = False

            while not self._cancel:
                if not self._timeout.isActive():
                    self._timeout.start()
                data = self._serial.readline()
                data = data.strip()
                if len(data) == 12:
                    timestamp = time.time()
                    result = self._parser.parse(data, timestamp)
                    if result is not None:
                        self._timeout.stop()
                        self.data.emit(result)
                    else:
                        self.warning.emit('Invalid data received')
                QApplication.processEvents()
            self._serial.close()
        except serial.SerialException as e:
            self.error.emit(e.message)

    def __onTimeout(self):
        self.warning.emit('No data received')

    def stop(self):
        self._cancel = True
Пример #13
0
class _ThreadPoolStatus(object):
  def __init__(self, q):
    self.activeThreadCount = 0
    self.refreshTimer = QTimer(q)
    self.refreshTimer.setInterval(500)
    self.refreshTimer.timeout.connect(self.refresh)
    self.refreshTimer.start()

  def refresh(self):
    value = QThreadPool.globalInstance().activeThreadCount()
    if self.activeThreadCount != value:
      self.activeThreadCount = value
      self.q.threadCountChanged.emit(value)
Пример #14
0
class MidiMonitorUnit(unit.Sink, unit.Unit):
  def __init__(self, style='hex', show_time=False, *args, **kwargs):
    unit.Unit.__init__(self, *args, **kwargs)
    unit.Sink.__init__(self)
    self._style = style
    self._show_time = show_time
    self.messages = list()
    self._max_messages = 100
    self._client = jackpatch.Client('jackdaw-monitor')
    self._client.activate()
    self._sink_type = 'midi'
    self._sink_port = jackpatch.Port(client=self._client,
      name='capture', flags=jackpatch.JackPortIsInput)
    self._timer = QTimer()
    self._timer.setInterval(0)
    self._timer.timeout.connect(self.receive)
    self._timer.start()
  @property
  def style(self):
    return(self._style)
  @style.setter
  def style(self, value):
    if (value != self._style):
      self._style = value
      self.on_change()
  @property
  def show_time(self):
    return(self._show_time)
  @show_time.setter
  def show_time(self, value):
    if (value != self._show_time):
      self._show_time = value
      self.on_change()
  def receive(self):
    message_added = False
    while (True):
      result = self._sink_port.receive()
      if (result is None): break
      (data, time) = result
      self.messages.append((data, time))
      message_added = True
    if (message_added):
      # trim the message list if it gets too long to conserve memory
      if (len(self.messages) > self._max_messages):
        self.messages = self.messages[-self._max_messages:]
      self.on_change()
  def serialize(self):
    obj = unit.Unit.serialize(self)
    obj['style'] = self.style
    obj['show_time'] = self.show_time
    return(obj)
Пример #15
0
class MyGlWidget(QGLWidget):
    "PySideApp uses Qt library to create an opengl context, listen to keyboard events, and clean up"

    def __init__(self, renderer, glformat, app):
        "Creates an OpenGL context and a window, and acquires OpenGL resources"
        super(MyGlWidget, self).__init__(glformat)
        self.renderer = renderer
        self.app = app
        # Use a timer to rerender as fast as possible
        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.setInterval(0)
        self.timer.timeout.connect(self.render_vr)
        # Accept keyboard events
        self.setFocusPolicy(Qt.StrongFocus)

    def __enter__(self):
        "setup for RAII using 'with' keyword"
        return self

    def __exit__(self, type_arg, value, traceback):
        "cleanup for RAII using 'with' keyword"
        self.dispose_gl()

    def initializeGL(self):
        if self.renderer is not None:
            self.renderer.init_gl()
        self.timer.start()

    def paintGL(self):
        "render scene one time"
        self.renderer.render_scene()
        self.swapBuffers() # Seems OK even in single-buffer mode
        
    def render_vr(self):
        self.makeCurrent()
        self.paintGL()
        self.doneCurrent()
        self.timer.start() # render again real soon now

    def disposeGL(self):
        if self.renderer is not None:
            self.makeCurrent()
            self.renderer.dispose_gl()
            self.doneCurrent()

    def keyPressEvent(self, event):
        "press ESCAPE to quit the application"
        key = event.key()
        if key == Qt.Key_Escape:
            self.app.quit()
Пример #16
0
class MyGlWidget(QGLWidget):
    "PySideApp uses Qt library to create an opengl context, listen to keyboard events, and clean up"

    def __init__(self, renderer, glformat, app):
        "Creates an OpenGL context and a window, and acquires OpenGL resources"
        super(MyGlWidget, self).__init__(glformat)
        self.renderer = renderer
        self.app = app
        # Use a timer to rerender as fast as possible
        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.setInterval(0)
        self.timer.timeout.connect(self.render_vr)
        # Accept keyboard events
        self.setFocusPolicy(Qt.StrongFocus)

    def __enter__(self):
        "setup for RAII using 'with' keyword"
        return self

    def __exit__(self, type_arg, value, traceback):
        "cleanup for RAII using 'with' keyword"
        self.dispose_gl()

    def initializeGL(self):
        if self.renderer is not None:
            self.renderer.init_gl()
        self.timer.start()

    def paintGL(self):
        "render scene one time"
        self.renderer.render_scene()
        self.swapBuffers()  # Seems OK even in single-buffer mode

    def render_vr(self):
        self.makeCurrent()
        self.paintGL()
        self.doneCurrent()
        self.timer.start()  # render again real soon now

    def disposeGL(self):
        if self.renderer is not None:
            self.makeCurrent()
            self.renderer.dispose_gl()
            self.doneCurrent()

    def keyPressEvent(self, event):
        "press ESCAPE to quit the application"
        key = event.key()
        if key == Qt.Key_Escape:
            self.app.quit()
Пример #17
0
class InputHandler(observable.Object):
  def __init__(self, port, target):
    observable.Object.__init__(self)
    # store the source port and the target to send data to
    self._port = port
    self._target = target
    # add an idle timer to check for input
    self._timer = QTimer()
    self._timer.setInterval(0)
    self._timer.timeout.connect(self.receive)
    self._timer.start()
  def destroy(self):
    self._timer.timeout.disconnect(self.receive)
    self._timer.stop()
  @property
  def port(self):
    return(self._port)
  @property
  def target(self):
    return(self._target)
  # check for input
  def receive(self, limit_time=True):
    # limit processing time to maintain responsiveness
    time_limit = time.time() + 0.100
    # wrap the target in a change block so each midi event doesn't waste a lot
    #  of time causing cascading changes
    target_and_refs = (self._target,)
    try:
      target_and_refs += self._target.model_refs
    except AttributeError: pass
    for model in target_and_refs:
      try:
        model.begin_change_block()
      except AttributeError: pass
    while (True):
      result = self._port.receive()
      if (result is None): break
      (data, msg_time) = result
      self.handle_message(data, msg_time)
      # handle at least one message per run, but limit overall processing time
      #  to keep the UI responsive, allowing the jackpatch buffer to handle 
      #  the backlog
      if ((limit_time) and (time.time() > time_limit)): break
    for model in target_and_refs:
      try:
        model.end_change_block()
      except AttributeError: pass
  # handle input, reimplement to pass data to the target
  def handle_message(data, time):
    pass
Пример #18
0
 def onLoopRequested(loopRequest):
     print 'l: ', l
     if l:
         l.pop()
         led.toggle(not led.isToggled())
     ledTimer = QTimer(toggleObject)
     ledTimer.setSingleShot(True)
     ledTimer.setInterval(200)
     ledTimer.timeout.connect(
         partial(
             loopRequest.completeRequest,
             True if l else False
         )
     )
     ledTimer.start()
     if not l: l.extend(range(20))
Пример #19
0
class WidgetLed(QWidget):

    def __init__(self, parent, colour='#000000'):
        QWidget.__init__(self, parent)
        self._colour = QColor(colour)

        self.setMinimumSize(20, 20)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self._lit = False
        self._timer = QTimer(self)
        self._timer.setInterval(200)
        self._timer.timeout.connect(self.__flash_off)

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)

        colour = self._colour
        if not self._lit:
            colour = self._colour.darker(300)
        painter.setPen(QPen(Qt.black, 1))
        painter.setBrush(QBrush(colour))

        rect = event.rect()
        radius = min(rect.width(), rect.height()) / 3
        painter.drawEllipse(rect.center(), radius, radius)

        painter.end()

    def __flash_off(self):
        self._timer.stop()
        self._lit = False
        self.repaint()

    def flash(self):
        self._lit = True
        self._timer.start()
        self.repaint()

    def light(self, on):
        self._timer.stop()
        self._lit = on
        self.repaint()

    def set_colour(self, colour):
        self._colour = QColor(colour)
Пример #20
0
class WalletController(QObject):
    onError = Signal(unicode)
    onConnected = Signal(bool)
    onTxSent = Signal(bool)
    onBusy = Signal()
    onDoubleEncrypted = Signal()
    onBalance = Signal()
    onWalletUnlocked = Signal()
    onCurrentBalance = Signal()
    onCurrentLabel = Signal()
    onCurrentAddress = Signal()
    onCurrentDoubleEncrypted = Signal()
    onCurrentPassKey = Signal()
    onCurrentWatchOnly = Signal()

    def __init__(self,):
        QObject.__init__(self,)
        self.thread = None
        self._balance = '<b>0.00</b>000000'
        self._wallet = Wallet()
        self._walletUnlocked = False
        self.settings = Settings()
        self.addressesModel = AddressesModel()
        self.transactionsModel = TransactionsModel()
        self.timer = QTimer(self)
        self.timer.setInterval(900000)  # 15 min update
        self.timer.timeout.connect(self.update)
        self.timer.start()

        if self.settings.storePassKey:
            self._currentPassKey = self.settings.passKey
            try:
                self.unlockWallet(self._currentPassKey)
            except:
                self.onError.emit('Stored pass phrase is invalid')
        else:
            self._currentPassKey = None
        self._currentAddressIndex = 0

    @Slot(unicode)
    def newAddr(self, doubleKey):
        try:
            self._wallet.createAddr(doubleKey)
            self.storeWallet()
            self.update()
        except (WrongPassword, DataError), err:
            self.onError.emit(unicode(err))
Пример #21
0
class _VideoComponentEditor(_LaserComponentEditor):
    """
    """
    playTimer = Any
    fps = Int
    stop_timer = Event

    def init(self, parent):
        """
        Finishes initializing the editor by creating the underlying toolkit
        widget.

        """
        super(_VideoComponentEditor, self).init(parent)

        self.playTimer = QTimer(self.control)
        # self.playTimer.timeout.connect(self.update)
        self.control.connect(self.playTimer, SIGNAL('timeout()'), self.update)

        if self.value.fps:
            self.playTimer.setInterval(1000 / float(self.value.fps))
        self.playTimer.start()
        self.value.on_trait_change(self.stop, 'closed_event')

        self.value.on_trait_change(self._update_fps, 'fps')
        self.sync_value('stop_timer', 'stop_timer', mode='from')

    def _update_fps(self):
        if self.value.fps:
            self.playTimer.setInterval(1000 / float(self.value.fps))

    def stop(self):
        print 'VideoComponentEditor stop'
        try:
            self.playTimer.stop()
        except RuntimeError:
            pass

    def update(self):
        if self.control:
            # invoke_in_main_thread(self.value.request_redraw)
            self.value.request_redraw()

    def _stop_timer_fired(self):
        print 'VideoComponentEditor stopping playTimer'
        self.playTimer.stop()
Пример #22
0
class demo(QApplication):
    "Simple application for testing OpenGL rendering"

    def __init__(self, number=1):
        QApplication.__init__(self, sys.argv)
        self.setApplicationName("SphereTest")
        self.mainWindow = QMainWindow()
        self.gl_widget = proPixx480_1440test()
        self.mainWindow.setCentralWidget(self.gl_widget)
        self.mainWindow.setGeometry(
            QtGui.QDesktopWidget().availableGeometry(1))
        self.mainWindow.showFullScreen()
        self.curr_time = time.time()
        self.timer = QTimer()
        self.timer.setInterval(0)
        self.timer.timeout.connect(self.gl_widget.update)
        self.timer.start()
        self.timer2 = QTimer()
        self.timer2.setInterval(3000)
        self.timer2.timeout.connect(self.printFrames)
        self.timer2.start()
        self.gl_widget.mode = number
        self.gl_widget.mouseDoubleClickEvent = lambda x: self.mainWindow.close(
        )
        self.previous_time = 0
        self.previous_total = 0

        my_device = PROPixx()
        if number is 0:  # 480 Hz
            my_device.setDlpSequencerProgram('QUAD4X')
        else:  # 1440 Hz
            my_device.setDlpSequencerProgram('QUAD12X')
        my_device.updateRegisterCache()

        sys.exit(self.exec_())  # Start Qt main loop

    def printFrames(self):

        time_ela = self.gl_widget.time - self.curr_time
        new_time = time_ela - self.previous_time
        self.previous_time = time_ela
        new_frames = self.gl_widget.frame_number - self.previous_total
        self.previous_total = self.gl_widget.frame_number
        print "There have been %d frames in %f seconds, so %f FPS" % (
            new_frames, new_time, new_frames / float(new_time))
class Render(QWebView):
    def __init__(self, url, filename, image_crop, translate_page, parent=None):
        super(Render, self).__init__(parent)
        self.image_crop = image_crop
        self.fileName = time.strftime("%Y%m%d%H%M%S",
                                      time.localtime()) + "_test.jpg"
        self.finished = False

        # Settings
        s = self.page().settings()
        s.setAttribute(QWebSettings.AutoLoadImages, True)
        s.setAttribute(QWebSettings.PluginsEnabled, True)
        s.setAttribute(QWebSettings.JavascriptEnabled, True)
        s.setAttribute(QWebSettings.JavaEnabled, False)
        s.setAttribute(QWebSettings.JavascriptCanOpenWindows, False)
        s.setAttribute(QWebSettings.DeveloperExtrasEnabled, True)

        #self.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.page().mainFrame().setScrollBarPolicy(Qt.Vertical,
                                                   Qt.ScrollBarAlwaysOff)

        self.timerScreen = QTimer()
        self.timerScreen.setInterval(10000)
        self.timerScreen.setSingleShot(True)
        self.timerScreen.timeout.connect(self.takeScreenshot)

        self.loadFinished.connect(self.timerScreen.start)
        self.load(QUrl(url))

    @Slot(QNetworkReply)
    def takeScreenshot(self):
        [x, y, width, height] = self.image_crop
        frame = self.page().mainFrame()
        size = frame.contentsSize()
        size.setWidth(1000)
        size.setHeight(2000)
        self.page().setViewportSize(size)
        image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        frame.render(painter)
        painter.end()
        image1 = image.copy(x, y, width, height)
        image1.save(self.fileName)
        self.finished = True
Пример #24
0
class _VideoComponentEditor(_LaserComponentEditor):
    """
    """

    playTimer = Any
    fps = Int
    stop_timer = Event

    def init(self, parent):
        """
        Finishes initializing the editor by creating the underlying toolkit
        widget.

        """
        super(_VideoComponentEditor, self).init(parent)

        self.playTimer = QTimer(self.control)
        self.playTimer.timeout.connect(self.update)
        if self.value.fps:
            self.playTimer.setInterval(1000 / self.value.fps)
        self.playTimer.start()
        self.value.on_trait_change(self.stop, "closed_event")

        self.value.on_trait_change(self._update_fps, "fps")
        self.sync_value("stop_timer", "stop_timer", mode="both")

    def _update_fps(self):
        if self.value.fps:
            self.playTimer.setInterval(1000 / self.value.fps)

    def stop(self):
        try:
            self.playTimer.stop()
        except RuntimeError:
            del self.playTimer

    def update(self):
        if self.control:
            self.value.draw_valid = False
            self.control.repaint()

    def _stop_timer_fired(self):
        print "VideoComponentEditor stopping playTimer"
        self.playTimer.stop()
Пример #25
0
class WidgetLed(QWidget):
    def __init__(self, parent, colour='#000000'):
        QWidget.__init__(self, parent)
        self._colour = QColor(colour)

        self.setMinimumSize(10, 10)

        self._lit = False
        self._timer = QTimer(self)
        self._timer.setInterval(200)
        self._timer.timeout.connect(self.__flashOff)

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)

        if self._lit:
            self._colour.setAlphaF(1)
        else:
            self._colour.setAlphaF(.25)
        painter.setPen(QPen(self._colour, 1))
        painter.setBrush(QBrush(self._colour))

        rect = event.rect()
        radius = min(rect.width(), rect.height()) / 3
        painter.drawEllipse(rect.center(), radius, radius)

        painter.end()

    def __flashOff(self):
        self._timer.stop()
        self._lit = False
        self.repaint()

    def flash(self):
        self._lit = True
        self._timer.start()
        self.repaint()

    def light(self, on):
        self._timer.stop()
        self._lit = on
        self.repaint()
Пример #26
0
class _CameraEditor(Editor):
    timer = Instance(QTimer)
    swap = False

    def init(self, parent):
        self.control = self._create_control(parent)

    def update_editor(self):
        self._setup_loop()

    def dispose(self):
        self.timer.stop()

    def _setup_loop(self):
        self.timer = QTimer(self.control)
        self.timer.timeout.connect(self._update)
        if self.factory.fps:
            self.timer.setInterval(1000 / self.factory.fps)
        self.timer.start()

    def _update(self):
        # w, h = self.control.width(), self.control.height()
        # img = self.value.get_image_data(size=(w, h))
        img = self.value.get_image_data()
        if img is not None:
            s = img.shape
            if s:
                im = QImage(img, s[1], s[0], QImage.Format_RGB32)
                # im = QImage(img, s[1], s[0], QImage.Format_RGB16)
                if self.swap:
                    im = QImage.rgbSwapped(im)

                pix = QPixmap.fromImage(im)
                self.control.setPixmap(pix)

    def _create_control(self, parent):
        label = QLabel()
        width, height = self.item.width, self.item.height
        if self.item.width != -1.0:
            label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            label.setFixedWidth(abs(width))
            label.setFixedHeight(abs(height))
        return label
Пример #27
0
class _CameraEditor(Editor):
    timer = Instance(QTimer)
    swap = False

    def init(self, parent):
        self.control = self._create_control(parent)

    def update_editor(self):
        self._setup_loop()

    def dispose(self):
        self.timer.stop()

    def _setup_loop(self):
        self.timer = QTimer(self.control)
        self.timer.timeout.connect(self._update)
        if self.factory.fps:
            self.timer.setInterval(1000 / self.factory.fps)
        self.timer.start()

    def _update(self):
        # w, h = self.control.width(), self.control.height()
        # img = self.value.get_image_data(size=(w, h))
        img = self.value.get_image_data()
        if img is not None:
            s = img.shape
            if s:
                im = QImage(img, s[1], s[0], QImage.Format_RGB32)
                # im = QImage(img, s[1], s[0], QImage.Format_RGB16)
                if self.swap:
                    im = QImage.rgbSwapped(im)

                pix = QPixmap.fromImage(im)
                self.control.setPixmap(pix)

    def _create_control(self, parent):
        label = QLabel()
        width, height = self.item.width, self.item.height
        if self.item.width != -1.0:
            label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            label.setFixedWidth(abs(width))
            label.setFixedHeight(abs(height))
        return label
class Render(QWebView):
    def __init__(self, url, filename, image_crop, translate_page, parent=None):
        super(Render, self).__init__(parent)
        self.image_crop = image_crop
        self.fileName = time.strftime("%Y%m%d%H%M%S",time.localtime()) +"_test.jpg" 
        self.finished = False

        # Settings
        s = self.page().settings()
        s.setAttribute(QWebSettings.AutoLoadImages, True)
        s.setAttribute(QWebSettings.PluginsEnabled, True)
        s.setAttribute(QWebSettings.JavascriptEnabled, True)
        s.setAttribute(QWebSettings.JavaEnabled, False)
        s.setAttribute(QWebSettings.JavascriptCanOpenWindows, False)
        s.setAttribute(QWebSettings.DeveloperExtrasEnabled, True)    

        #self.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)

        self.timerScreen = QTimer()
        self.timerScreen.setInterval(10000)
        self.timerScreen.setSingleShot(True)
        self.timerScreen.timeout.connect(self.takeScreenshot)

        self.loadFinished.connect(self.timerScreen.start)
        self.load(QUrl(url)) 

    @Slot(QNetworkReply)           
    def takeScreenshot(self):        
        [x,y,width,height] = self.image_crop
        frame = self.page().mainFrame()
        size = frame.contentsSize()
        size.setWidth(1000)
        size.setHeight(2000)
        self.page().setViewportSize(size)
        image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        frame.render(painter)
        painter.end()
        image1 = image.copy(x,y,width,height)
        image1.save(self.fileName)
        self.finished = True
Пример #29
0
 def _create_timer(self, interval, single_shot, handler):
     timer = QTimer()
     timer.setInterval(1000 * interval)
     timer.setSingleShot(single_shot)
     self._timers.add(timer)
     wref = weakref.ref(timer)
     def callback():
         timer = wref()
         if single_shot and timer:
             timer.stop()
             self._timers.discard(timer)
         self._processor.submit(handler)
     timer.timeout.connect(callback)
     def cancel():
         timer = wref()
         if timer:
             timer.stop()
             self._timers.discard(timer)
     handler.cancel_callback = cancel
     timer.start()
     return timer
Пример #30
0
class QtOneSecondTimer(OneSecondTimer):
    """
    Concrete implementation of the timer based on Qt classes
    """

    def __init__(self):
        OneSecondTimer.__init__(self)
        self.__timer = QTimer()
        self.__timer.setInterval(1000)
        self.__timer.setSingleShot(False)
        self.__timer.timeout.connect(self._timerElapsed)

    def start(self):
        """Start the timer"""
        self.__timer.start()

    def _timerElapsed(self):
        """Process notification from the timer"""
        self.elapsed.fire()

    def stop(self):
        """Stop the timer"""
        self.__timer.stop()
Пример #31
0
    class MainWindow(QWidget):
        def __init__(self, grid, U):
            assert isinstance(U, Communicable)
            super(MainWindow, self).__init__()

            U = U.data

            layout = QVBoxLayout()

            plotBox = QHBoxLayout()
            plot = GlumpyPatchWidget(self, grid, vmin=np.min(U), vmax=np.max(U), bounding_box=bounding_box, codim=codim)
            bar = ColorBarWidget(self, vmin=np.min(U), vmax=np.max(U))
            plotBox.addWidget(plot)
            plotBox.addWidget(bar)
            layout.addLayout(plotBox)

            if len(U) == 1:
                plot.set(U.ravel())
            else:
                plot.set(U[0])

                hlayout = QHBoxLayout()

                self.slider = QSlider(Qt.Horizontal)
                self.slider.setMinimum(0)
                self.slider.setMaximum(len(U) - 1)
                self.slider.setTickPosition(QSlider.TicksBelow)
                hlayout.addWidget(self.slider)

                lcd = QLCDNumber(m.ceil(m.log10(len(U))))
                lcd.setDecMode()
                lcd.setSegmentStyle(QLCDNumber.Flat)
                hlayout.addWidget(lcd)

                layout.addLayout(hlayout)

                hlayout = QHBoxLayout()

                toolbar = QToolBar()
                self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self)
                self.a_play.setCheckable(True)
                self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self)
                self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self)
                self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward), 'Step Back', self)
                self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self)
                self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self)
                self.a_loop.setCheckable(True)
                toolbar.addAction(self.a_play)
                toolbar.addAction(self.a_rewind)
                toolbar.addAction(self.a_toend)
                toolbar.addAction(self.a_step_backward)
                toolbar.addAction(self.a_step_forward)
                toolbar.addAction(self.a_loop)
                hlayout.addWidget(toolbar)

                self.speed = QSlider(Qt.Horizontal)
                self.speed.setMinimum(0)
                self.speed.setMaximum(100)
                hlayout.addWidget(QLabel('Speed:'))
                hlayout.addWidget(self.speed)

                layout.addLayout(hlayout)

                self.timer = QTimer()
                self.timer.timeout.connect(self.update_solution)

                self.slider.valueChanged.connect(self.slider_changed)
                self.slider.valueChanged.connect(lcd.display)
                self.speed.valueChanged.connect(self.speed_changed)
                self.a_play.toggled.connect(self.toggle_play)
                self.a_rewind.triggered.connect(self.rewind)
                self.a_toend.triggered.connect(self.to_end)
                self.a_step_forward.triggered.connect(self.step_forward)
                self.a_step_backward.triggered.connect(self.step_backward)

                self.speed.setValue(50)

            self.setLayout(layout)
            self.plot = plot
            self.U = U

        def slider_changed(self, ind):
            self.plot.set(self.U[ind])

        def speed_changed(self, val):
            self.timer.setInterval(val * 20)

        def update_solution(self):
            ind = self.slider.value() + 1
            if ind >= len(self.U):
                if self.a_loop.isChecked():
                    ind = 0
                else:
                    self.a_play.setChecked(False)
                    return
            self.slider.setValue(ind)

        def toggle_play(self, checked):
            if checked:
                if self.slider.value() + 1 == len(self.U):
                    self.slider.setValue(0)
                self.timer.start()
            else:
                self.timer.stop()

        def rewind(self):
            self.slider.setValue(0)

        def to_end(self):
            self.a_play.setChecked(False)
            self.slider.setValue(len(self.U) - 1)

        def step_forward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() + 1
            if ind == len(self.U) and self.a_loop.isChecked():
                ind = 0
            if ind < len(self.U):
                self.slider.setValue(ind)

        def step_backward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() - 1
            if ind == -1 and self.a_loop.isChecked():
                ind = len(self.U) - 1
            if ind >= 0:
                self.slider.setValue(ind)
Пример #32
0
class Loader(QMainWindow):
    def __init__(self, parent=None):
        super(Loader, self).__init__(parent)

        self.initUI()

    def updateDeviceList(self):
        self.statusBar().showMessage("Device list updating...",
                                     timeout=STATUS_BAR_TIMEOUT)
        self.deviceListWidget.updateList()
        self.statusBar().showMessage("Device list updated finished!",
                                     timeout=STATUS_BAR_TIMEOUT)

    def getFileName(self, ext):
        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')
        # if fname[0]:
        #     f = open(fname[0], 'r')

        #     with f:
        #         data = f.read()
        #         self.textEdit.setText(data)

    def initUI(self):

        # textEdit = QTextEdit()
        # self.setCentralWidget(textEdit)

        # self.setStyleSheet("QGroupBox {  border: 1px solid gray; padding: 5px;}");

        # Action to quit program
        exitAction = QAction(QIcon(None), 'Quit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        # # Action to update device list
        # self.refreshAction = QAction(QIcon('img/reload.png'), 'Refresh', self)
        # self.refreshAction.setShortcut('F5')
        # self.refreshAction.setStatusTip('Refresh list of connected devices.')
        # self.refreshAction.triggered.connect(self.updateDeviceList)

        # Action to show program information
        helpAction = QAction(QIcon(None), 'Help', self)
        helpAction.setShortcut('F1')
        helpAction.triggered.connect(self.showHelpDialog)

        # Action to help
        aboutAction = QAction(QIcon(None), 'About', self)
        aboutAction.triggered.connect(self.showAboutDialog)

        self.statusBar()

        # Add the file menu
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        # fileMenu.addAction(self.refreshAction)
        fileMenu.addAction(exitAction)
        fileMenu = menubar.addMenu('&Help')
        fileMenu.addAction(helpAction)
        fileMenu.addAction(aboutAction)

        # # Add the toolbar
        # toolbar = self.addToolBar('Exit')
        # # toolbar.addAction(self.refreshAction)
        # toolbar.setMovable(False)

        # Add the main windows widgets
        self.deviceListWidget = DeviceList(self.programDeviceHandler,
                                           self.infoDeviceHandler,
                                           self.resetDeviceHandler)
        self.fileSelectorWidget = FileSelector()

        self.setStyleSheet("""
            QStatusBar {
                border-top: 1px solid #CCC;
            }
            QToolBar {
                border-top: 1px solid #DDD;
                border-bottom: 1px solid #CCC;
            }
        """)

        gbox = QGroupBox("Connected USB devices:")
        gboxLayout = QVBoxLayout()
        gboxLayout.addWidget(self.deviceListWidget)
        gbox.setLayout(gboxLayout)

        self.refreshEvent = QTimer()
        self.refreshEvent.setInterval(1250)
        self.refreshEvent.timeout.connect(self.USBUpdate)
        self.refreshEvent.start()

        layout = QVBoxLayout()
        layout.addWidget(self.fileSelectorWidget)
        layout.addWidget(gbox)
        self.setCentralWidget(QWidget())
        self.centralWidget().setLayout(layout)

        self.setMinimumSize(620, 700)
        self.setMaximumWidth(620)
        self.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint
                            | Qt.WindowCloseButtonHint)

        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('keyplus layout and firmware loader')
        self.show()

    def abort_update(self, target_device):
        try:
            target_device.close()
        except:
            pass

        self.deviceListWidget.updateList()

    def abort_update2(self):
        self.deviceListWidget.updateList()

    @Slot(str)
    def programDeviceHandler(self, device_path):
        target_device = self.tryOpenDevicePath(device_path)

        if target_device == None:
            self.abort_update(target_device)
            return

        programmingMode = self.fileSelectorWidget.getProgramingInfo()

        if is_bootloader_device(
                target_device
        ) and programmingMode != FileSelector.ScopeFirmware:
            error_msg_box("The device's bootloader is running. "
                          "Choose 'Update Firmware' from the drop down box "
                          "to flash new firmware, or reset it to use to run "
                          "the currently loaded firmware (if any).")
            self.abort_update(target_device)
            return

        if programmingMode == FileSelector.ScopeLayout:
            target_device.close()
            kb = self.tryOpenDevicePath2(device_path)

            if kb == None:
                return

            self.statusBar().showMessage("Started updating layout",
                                         timeout=STATUS_BAR_TIMEOUT)

            layout_file = self.fileSelectorWidget.getLayoutFile()

            if layout_file == '':
                error_msg_box("No layout file given.")
                return

            try:
                kp_layout = KeyplusLayout()
                warnings = []
                kp_layout.from_yaml_file(layout_file, warnings=warnings)
                device_target = kb.get_device_target()
                settings_data = kp_layout.build_settings_section(device_target)
                layout_data = kp_layout.build_layout_section(device_target)
            except (KeyplusError, IOError) as err:
                error_msg_box(str(err))
                return

            print('#' * 80)
            print("settings_data:", type(settings_data), settings_data)
            print('#' * 80)
            print("layout_data:", type(layout_data), layout_data)
            print('#' * 80)
            hexdump.hexdump(bytes(settings_data))
            hexdump.hexdump(bytes(layout_data))

            with kb:
                old_name = copy.copy(kb.name)
                kb.update_settings_section(settings_data, keep_rf=True)
                kb.update_layout_section(layout_data)
                if old_name != kb.name:
                    kb.reset(reset_type=RESET_TYPE_HARDWARE)
                    needs_label_update = True
                else:
                    kb.reset(reset_type=RESET_TYPE_SOFTWARE)
                    needs_label_update = False

            if needs_label_update:
                for widget in self.deviceListWidget.deviceWidgets:
                    try:
                        widget.updateLabel()
                    except easyhid.HIDException:
                        pass

            if warnings != []:
                error_msg_box(
                    "The device was programmed successfully, but some "
                    "non-critical errors were encountered:\n" +
                    "\n".join([str(warn) for warn in warnings]),
                    title="Warnings",
                )

            self.statusBar().showMessage("Finished updating layout",
                                         timeout=STATUS_BAR_TIMEOUT)
        elif programmingMode == FileSelector.ScopeDevice:
            target_device.close()
            kb = self.tryOpenDevicePath2(device_path)
            if kb == None:
                return

            layout_file = self.fileSelectorWidget.getRFLayoutFile()
            rf_file = self.fileSelectorWidget.getRFFile()
            target_id = self.fileSelectorWidget.getTargetID()

            self.statusBar().showMessage("Started updating RF settings",
                                         timeout=STATUS_BAR_TIMEOUT)

            if layout_file == '':
                error_msg_box("No layout file given.")
                self.abort_update(target_device)
                return
            elif rf_file == '':
                error_msg_box("No RF settings file given.")
                self.abort_update(target_device)
                return
            elif target_id == None:
                error_msg_box("No device id file given.")
                self.abort_update(target_device)
                return

            try:
                kp_layout = KeyplusLayout()
                warnings = []
                kp_layout.from_yaml_file(layout_file,
                                         rf_file,
                                         warnings=warnings)
                device_target = kb.get_device_target()
                device_target.device_id = target_id
                settings_data = kp_layout.build_settings_section(device_target)
                layout_data = kp_layout.build_layout_section(device_target)
            except (KeyplusError, IOError) as err:
                error_msg_box(str(err))
                self.abort_update(target_device)
                return

            with kb:
                old_name = copy.copy(kb.name)
                kb.update_settings_section(settings_data, keep_rf=False)
                kb.update_layout_section(layout_data)
                if old_name != kb.name:
                    kb.reset(reset_type=RESET_TYPE_HARDWARE)
                    needs_label_update = True
                else:
                    kb.reset(reset_type=RESET_TYPE_SOFTWARE)
                    needs_label_update = False

            if needs_label_update:
                for widget in self.deviceListWidget.deviceWidgets:
                    try:
                        widget.updateLabel()
                    except easyhid.HIDException:
                        pass

            if warnings != []:
                error_msg_box(
                    "The device was programmed successfully, but some "
                    "non-critical errors were encountered:\n" +
                    "\n".join([str(warn) for warn in warnings]),
                    title="Warnings",
                )

            self.statusBar().showMessage("Finished updating RF settings",
                                         timeout=STATUS_BAR_TIMEOUT)

        elif programmingMode == FileSelector.ScopeFirmware:
            fw_file = self.fileSelectorWidget.getFirmwareFile()

            self.statusBar().showMessage("Starting update firmware",
                                         timeout=STATUS_BAR_TIMEOUT)

            if fw_file == '':
                error_msg_box("No firmware file given.")
            else:

                if is_xusb_bootloader_device(target_device):
                    self.program_xusb_boot_firmware_hex(target_device, fw_file)
                elif is_kp_boot_device(target_device):
                    self.program_kp_boot_32u4_firmware_hex(
                        target_device, fw_file)
                elif is_keyplus_device(target_device):
                    try:
                        serial_num = target_device.serial_number
                        boot_vid, boot_pid = protocol.enter_bootloader(
                            target_device)

                        self.bootloaderProgramTimer = QTimer()
                        self.bootloaderProgramTimer.setInterval(3000)
                        self.bootloaderProgramTimer.setSingleShot(True)
                        self.bootloaderProgramTimer.timeout.connect(
                            lambda: self.programFirmwareHex(
                                boot_vid, boot_pid, serial_num, fw_file))
                        self.bootloaderProgramTimer.start()
                    except (easyhid.HIDException,
                            protocol.KBProtocolException):
                        error_msg_box(
                            "Programming hex file failed: '{}'".format(
                                fw_file))
                else:
                    error_msg_box("This bootloader is currently unsupported")
        else:
            try:
                target_device.close()
            except:
                pass
            raise Exception("Unimplementend programming mode")

    def programFirmwareHex(self, boot_vid, boot_pid, serial_num, file_name):
        device = None

        for i in range(1):
            en = easyhid.Enumeration(vid=boot_vid, pid=boot_pid).find()

            # Look for devices with matching serial_num number
            for dev in en:
                if dev.serial_number == serial_num:
                    device = dev
                    break

            # if a device was found with matching vid:pid, but it doesn't have
            # a matching serial_num number, then assume that the bootloader/firmware
            # doesn't set the serial_num number to the same value, so just program
            # the first matching device
            if len(en) != 0:
                device = en[0]
                break

        if device == None:
            error_msg_box("Couldn't connect to the device's bootloader")
            return
        else:
            if self.tryOpenDevice(device): return

            self.program_xusb_boot_firmware_hex(device, file_name)
        self.statusBar().showMessage("Finished updating firmware",
                                     timeout=STATUS_BAR_TIMEOUT)

    def program_xusb_boot_firmware_hex(self, device, file_name):
        try:
            xusbboot.write_hexfile(device, file_name)
        except xusbboot.BootloaderException as err:
            error_msg_box("Error programming the bootloader to hex file: " +
                          str(err))
        finally:
            device.close()

    def program_kp_boot_32u4_firmware_hex(self, device, file_name):
        try:
            device.close()
            boot_dev = kp_boot_32u4.BootloaderDevice(device)
            with boot_dev:
                boot_dev.write_flash_hex(file_name)
                boot_dev.reset_mcu()
        except Exception as err:
            error_msg_box("Error programming the bootloader to hex file: " +
                          str(err))

    def tryOpenDevicePath2(self, device_path):
        try:
            print(device_path)
            device = easyhid.Enumeration().find(path=device_path)[0]
            return KeyplusKeyboard(device)
        except Exception as err:
            msg_box(
                description="Failed to open device! Check it is still present "
                "and you have permission to write to it. ErrorMsg: {}".format(
                    err),
                title="USB Device write error")
            traceback.print_exc(file=sys.stderr)
            return None

    def tryOpenDevicePath(self, device_path):
        try:
            device = easyhid.Enumeration().find(path=device_path)[0]
            device.open()
            return device
        except:
            msg_box(
                description="Failed to open device! Check it is still present "
                "and you have permission to write to it.",
                title="USB Device write error")
            return None

    def tryOpenDevice(self, device):
        try:
            device.open()
            return False
        except:
            msg_box(
                description="Failed to open device! Check it is still present "
                "and you have permission to write to it.",
                title="USB Device write error")
            return True

    @Slot(str)
    def resetDeviceHandler(self, device_path):
        device = self.tryOpenDevicePath(device_path)
        if device == None: return

        if is_keyplus_device(device):
            protocol.reset_device(device)
        elif is_xusb_bootloader_device(device):
            xusbboot.reset(device)
        elif is_kp_boot_device(device):
            device.close()
            dev = kp_boot_32u4.BootloaderDevice(device)
            with dev:
                dev.reset_mcu()
        elif is_nrf24lu1p_bootloader_device(device):
            print("TODO: reset: ", device_path, file=sys.stderr)
        else:
            print("Can't reset device: ", device_path, file=sys.stderr)

    @Slot(str)
    def infoDeviceHandler(self, device_path):
        device = self.tryOpenDevicePath(device_path)
        if device == None: return

        settingsInfo = protocol.get_device_info(device)
        firmwareInfo = protocol.get_firmware_info(device)
        rfInfo = protocol.get_rf_info(device)
        if firmwareInfo.has_at_least_version('0.2.2'):
            errorInfo = protocol.get_error_info(device)
        else:
            errorInfo = None
        device.close()

        def ms_str(x):
            return "{}ms".format(x)

        def us_str(x):
            return "{0:.1f}µs".format(x / 255 * 48.0)

        header = ["Attribute", "Value"]

        device_settings = [
            ("Device ID", settingsInfo.id),
            ("Device name", settingsInfo.device_name_str()),
            ("Device serial number", device.serial_number),
            ("Last layout update", settingsInfo.timestamp_str()),
            ("Default report mode", settingsInfo.default_report_mode_str()),
            ("Matrix scan mode", settingsInfo.scan_mode_str()),
            ("Matrix columns", settingsInfo.col_count),
            ("Matrix rows", settingsInfo.row_count),
            ("Key debounce press time",
             ms_str(settingsInfo.debounce_time_press)),
            ("Key debounce release time",
             ms_str(settingsInfo.debounce_time_release)),
            ("Key press trigger time",
             ms_str(settingsInfo.trigger_time_press)),
            ("Key release trigger time",
             ms_str(settingsInfo.trigger_time_release)),
            ("Key discharge idle time",
             us_str(settingsInfo.parasitic_discharge_delay_idle)),
            ("Key discharge debouncing time",
             us_str(settingsInfo.parasitic_discharge_delay_debouncing)),
            ("Settings stored CRC", hex(settingsInfo.crc)),
            ("Settings computed CRC", hex(settingsInfo.computed_crc)),
            ("USB", (settingsInfo.has_usb()
                     and firmwareInfo.has_fw_support_usb())),
            ("I2C", (settingsInfo.has_i2c()
                     and firmwareInfo.has_fw_support_i2c())),
            ("nRF24 wireless", (settingsInfo.has_nrf24()
                                and firmwareInfo.has_fw_support_nrf24())),
            ("Unifying mouse", (settingsInfo.has_unifying_mouse()
                                and firmwareInfo.has_fw_support_unifying())),
            ("Bluetooth", (settingsInfo.has_bluetooth()
                           and firmwareInfo.has_fw_support_bluetooth())),
            ("RF pipe0", binascii.hexlify(rfInfo.pipe0).decode('ascii')),
            ("RF pipe1", binascii.hexlify(rfInfo.pipe1).decode('ascii')),
            ("RF pipe2", "{:02x}".format(rfInfo.pipe2)),
            ("RF pipe3", "{:02x}".format(rfInfo.pipe3)),
            ("RF pipe4", "{:02x}".format(rfInfo.pipe4)),
            ("RF pipe5", "{:02x}".format(rfInfo.pipe5)),
            ("RF channel", str(rfInfo.channel)),
            ("RF auto retransmit count", str(rfInfo.arc)),
            ("RF data rate", protocol.data_rate_to_str(rfInfo.data_rate)),
        ]

        firmware_settings = [
            ("Firmware version",
             "{}.{}.{}".format(firmwareInfo.version_major,
                               firmwareInfo.version_minor,
                               firmwareInfo.version_patch)),
            ("Firmware build date",
             str(datetime.datetime.fromtimestamp(firmwareInfo.timestamp))),
            ("Firmware git hash", "{:08x}".format(firmwareInfo.git_hash)),
            ("Microcontroller",
             chip_id.get_chip_name_from_id(firmwareInfo.chip_id)),
            ("Board ID", hex(firmwareInfo.board_id)),
            ("Internal scan method",
             firmwareInfo.get_interal_scan_method_as_str()),
            ("Layout storage size", firmwareInfo.layout_flash_size),
            ("Bootloader VID", "{:04x}".format(firmwareInfo.bootloader_vid)),
            ("Bootloader PID", "{:04x}".format(firmwareInfo.bootloader_pid)),
            ("Support scanning", firmwareInfo.has_fw_support_scanning()),
            ("Support scanning col to row",
             firmwareInfo.has_fw_support_scanning_col_row()),
            ("Support scanning row to col",
             firmwareInfo.has_fw_support_scanning_row_col()),
            ("Media keys", firmwareInfo.has_fw_support_key_media()),
            ("Mouse keys", firmwareInfo.has_fw_support_key_mouse()),
            ("Layer keys", firmwareInfo.has_fw_support_key_layers()),
            ("Sticky keys", firmwareInfo.has_fw_support_key_sticky()),
            ("Tap keys", firmwareInfo.has_fw_support_key_tap()),
            ("Hold keys", firmwareInfo.has_fw_support_key_hold()),
            ("Support 6KRO", firmwareInfo.has_fw_support_6kro()),
            ("Support NKRO", firmwareInfo.has_fw_support_key_hold()),
            ("Support indicator LEDs",
             firmwareInfo.has_fw_support_led_indicators()),
            ("Support LED backlighting",
             firmwareInfo.has_fw_support_led_backlighting()),
            ("Support ws2812 LEDs", firmwareInfo.has_fw_support_led_ws2812()),
            ("Support USB", firmwareInfo.has_fw_support_usb()),
            ("Support nRF24 wireless", firmwareInfo.has_fw_support_nrf24()),
            ("Support Unifying", firmwareInfo.has_fw_support_unifying()),
            ("Support I2C", firmwareInfo.has_fw_support_i2c()),
            ("Support Bluetooth", firmwareInfo.has_fw_support_bluetooth()),
        ]

        if errorInfo:
            error_codes = []
            for code in errorInfo.get_error_codes():
                error_codes.append((errorInfo.error_code_to_name(code), code))
        else:
            error_codes = [
                ('Error codes require firmware version 0.2.2 or greater', )
            ]

        self.info_window = DeviceInformationWindow(
            self,
            header,
            device_settings,
            firmware_settings,
            error_codes,
        )

        self.info_window.exec_()

        self.deviceListWidget.updateList()

    def USBUpdate(self):
        self.deviceListWidget.updateList()

    def showAboutDialog(self):
        QMessageBox.about(self, "About keyplus Loader", """
The keyplus layout and firmware loader.
""")

    def showHelpDialog(self):
        QMessageBox.about(
            self, "keyplus Loader Help", """
This is the layout and firmware loader for the keyplus keyboard firmware.

The layout files are *.yaml files. For documentation and examples see here: TODO

The rf files are *.yaml files. For documentation and examples see here: TODO

The firmware loader accepts *.hex files. For the latest keyplus firmware see here: TODO

""")
Пример #33
0
class Sync(QObject):

    deleteServerFile = Signal((str, ))
    deleteLocalFile = Signal((str, ))
    downloadFile = Signal((str, ))
    uploadFile = Signal((str, ))
    checkServer = Signal()
    checkLocal = Signal()
    statusChanged = Signal((str, ))

    def __init__(self, host, ssl, parent=None):
        super(Sync, self).__init__(parent)

        self.server = ServerWatcher(host, ssl, self)

        self.preloaedActions = []
        self.doPreemptive = empty_db()
        self.connected = False
        self.firstScan = True

    def setLocalDir(self, localdir):
        if not os.path.exists(localdir):
            # Creates the directory if it doesn't already exists.
            os.makedirs(localdir)
        self.local = LocalWatcher(localdir)
        self.server.setLocalDir(localdir)

        self.local.moveToThread(self.thread())
        self.local.setParent(self)

    def connections(self):
        if not self.connected:
            self.connected = True
            self.server.fileAdded.connect(self.onAdded)
            self.server.fileChanged.connect(self.onChanged)
            self.server.fileDeleted.connect(self.onDeleted)

            self.local.fileAdded.connect(self.onAdded)
            self.local.fileChanged.connect(self.onChanged)
            self.local.fileDeleted.connect(self.onDeleted)

            self.deleteLocalFile.connect(self.local.deleteFile)
            self.deleteServerFile.connect(self.server.onDelete)
            self.downloadFile.connect(self.server.onDownload)
            self.uploadFile.connect(self.server.onUpload)

    @Slot()
    def initQueue(self):
        self.actionQueue = ActionQueue()

        self.actionTimer = QTimer()
        self.actionTimer.setInterval(1)
        self.actionTimer.timeout.connect(self.takeAction)

        self.actionTimer.start()

    @Slot()
    def takeAction(self):
        self.actionTimer.stop()

        if self.doPreemptive:
            # Preemptive check is a bit of a workaround to deal with
            # initial unexpected conditions: database file is gone
            self.doPreemptive = False
            self.server.preemptiveCheck = True
            self.local.fileAdded.connect(self.server.added)
            self.local.checkout()
            self.server.checkout()
            self.local.fileAdded.disconnect(self.server.added)
            self.server.preemptiveCheck = False
            for action in self.server.preemptiveActions:
                self.actionQueue.add(action)

        # After preemptive check, it is safe to do the connections
        # for normal operations
        self.connections()

        serverActionCount = 0
        localActionCount = 0
        for action in self.actionQueue:
            if action is not None:
                print 'Next action: %s' % action
                path = action.path
                do = action.action
                location = action.location

                if location == FileAction.LOCAL and (do == FileAction.UPLOAD \
                   or do == FileAction.DELETE):
                    if not engine_tools.file_exists_local(path):
                        # File no longer exists at the time of processing.
                        # Maybe it was temporary or a quick rename.
                        # So we ignore it
                        print "Ignored action on " + path + ": File doesn't exist on local."
                        continue

                if do == FileAction.UPLOAD:
                    self.uploadFile.emit(path)
                    localActionCount += 1
                elif do == FileAction.DOWNLOAD:
                    self.downloadFile.emit(path)
                    serverActionCount += 1
                elif do == FileAction.DELETE:
                    with File.fromPath(path) as deleted_file:
                        # `action.location` attribute only makes sense when deciding
                        # whether to delete a file on the server or local.
                        if location == FileAction.LOCAL:
                            localpath = self.local.localFromServer(path)
                            self.deleteLocalFile.emit(localpath)
                            deleted_file.inlocal = False
                            localActionCount += 1

                        elif location == FileAction.SERVER:
                            self.deleteServerFile.emit(path)
                            deleted_file.inserver = False
                            serverActionCount += 1

        self.actionQueue.clear()

        # Scan server for file changes
        self.statusChanged.emit('Scanning remote files for changes')
        self.server.checkout()

        if self.firstScan:
            # First do a full scan to check for offline changes.
            # From there we will rely on real time notifications watchdog.
            self.firstScan = False
            self.statusChanged.emit('Scanning local files for changes')
            self.local.checkout()
            self.local.startObserver()
            # Si Added
            # Since its the first scan, we should also
            # set the timer interval
            self.actionTimer.setInterval(5000)
        self.cleanSync()

        # Si Added
        # Set check interval intelligently.
        # If there's no activity there, wait longer.
        # Since if there's just no usage, then
        # no reason to take up CPU cycles.
        tempInterval = 0
        if serverActionCount + localActionCount > 0:
            tempInterval = 5000
        else:
            tempInterval = 1000 * 10

        self.actionTimer.start()

    @Slot()
    def cleanSync(self):
        """
        Removes entries from the database for deleted files
        """

        session = Session()
        session.query(File).filter(File.inserver == False).filter(
            File.inlocal == False).delete(synchronize_session=False)
        session.commit()
        self.statusChanged.emit('Sync completed. Waiting for changes')

    @Slot(str, str, bool)
    def onChanged(self, location, serverpath, skipDeltaCheck):
        changed_file = File.fromPath(serverpath)
        action = None

        #if not changed_file.servermdate:
        # Probably a local added event that also
        # spawned a modified event.
        #return

        file_name_only = os.path.basename(serverpath)
        if engine_tools.isTemporaryFile(file_name_only):
            print 'File ' + serverpath + ' ignored since it is a temporary file'
            return

        print 'File ' + serverpath + ':'

        if changed_file.servermdate == None:
            mydiff = "** File Not in Server **"
            edit_time = "(not in server)"
        else:
            ttt = (changed_file.localmdate -
                   changed_file.servermdate).total_seconds()
            mydiff = str(ttt)
            edit_time = str(changed_file.servermdate)

        print 'Changed here %s, there %s delta %s' % (changed_file.localmdate,
                                                      edit_time, mydiff)

        try:
            if changed_file.inserver:
                diff = changed_file.timeDiff()

                MY_TOLERANCE = 10

                if skipDeltaCheck == False and abs(diff) < MY_TOLERANCE:
                    return

            if location == FileAction.SERVER:
                if changed_file.inlocal:
                    if changed_file.localmdate < changed_file.servermdate:
                        action = FileAction(serverpath, FileAction.DOWNLOAD,
                                            FileAction.LOCAL)
                else:
                    action = FileAction(serverpath, FileAction.DOWNLOAD,
                                        FileAction.LOCAL)

            elif location == FileAction.LOCAL:
                if changed_file.inserver:
                    try:
                        if changed_file.servermdate < changed_file.localmdate:
                            action = FileAction(serverpath, FileAction.UPLOAD,
                                                FileAction.SERVER)
                    except:
                        print 'Error:', changed_file, changed_file.servermdate, changed_file.localmdate

                else:
                    action = FileAction(serverpath, FileAction.UPLOAD,
                                        FileAction.SERVER)

            if action is not None:
                self.actionQueue.add(action)
        except:
            info = traceback.format_exception(*sys.exc_info())
            for i in info:
                sys.stderr.write(i)

    @Slot(str, str)
    def onAdded(self, location, serverpath):

        file_name_only = os.path.basename(serverpath)
        if engine_tools.isTemporaryFile(file_name_only):
            print 'File ' + serverpath + ' was created but ignored since it is a temporary file'
            return

        added_file = File.fromPath(serverpath)
        action = None

        if location == FileAction.SERVER and not added_file.inlocal:
            action = FileAction(serverpath, FileAction.DOWNLOAD,
                                FileAction.LOCAL)
        elif location == FileAction.LOCAL and not added_file.inserver:
            action = FileAction(serverpath, FileAction.UPLOAD,
                                FileAction.SERVER)

        if action is not None:
            self.actionQueue.add(action)

    @Slot(str, str)
    def onDeleted(self, location, serverpath):

        # NOTE: For temporary files, the current action is to delete it.
        # Reason 1: We need to remove it from the database.
        # Reason 2: If somehow there is a temporary file
        # there on the other side, then it makes sense to delete it.

        deleted_file = File.fromPath(serverpath)
        action = None

        if location == FileAction.SERVER:
            if deleted_file.inlocal:
                action = FileAction(serverpath, FileAction.DELETE,
                                    FileAction.LOCAL)
        elif location == FileAction.LOCAL:
            if deleted_file.inserver:
                action = FileAction(serverpath, FileAction.DELETE,
                                    FileAction.SERVER)

        if action is not None:
            self.actionQueue.add(action)
Пример #34
0
 def repaintTimer(self):
     q = self.q
     ret = QTimer(q)
     ret.setInterval(200)
     ret.timeout.connect(q.repaint)
     return ret
Пример #35
0
        """
        print('~~~~ Pure Python method called')
        self.windowTitle()  # generate exception


app = QApplication([])
app.setQuitOnLastWindowClosed(False)

lineEdit = LineEdit()
lineEdit.deleteLater()

if USE_SINGLESHOT:
    #QTimer.singleShot(1000, lineEdit.clear)
    #QTimer.singleShot(1000, lineEdit.purePythonMethod)
    QTimer.singleShot(1000, lineEdit.selectAll)  # pure C++ method
else:
    timer = QTimer(None)
    timer.setSingleShot(True)
    timer.setInterval(1000)
    timer.start()

    #timer.timeout.connect(lineEdit.clear)
    #timer.timeout.connect(lineEdit.purePythonMethod)
    timer.timeout.connect(lineEdit.selectAll)  # pure C++ method

QTimer.singleShot(2000, app.quit)

app.exec_()

print('~~~~ Application exited')
Пример #36
0
class RunnerDialog(QDialog):

    options_added = Signal(Options)
    options_running = Signal(Options)
    options_simulated = Signal(Options)
    options_error = Signal(Options, Exception)
    results_saved = Signal(Results, str)
    results_error = Signal(Results, Exception)

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Runner')
        self.setMinimumWidth(750)

        # Runner
        self._runner = None

        self._running_timer = QTimer()
        self._running_timer.setInterval(500)

        # Widgets
        self._dlg_progress = QProgressDialog()
        self._dlg_progress.setRange(0, 100)
        self._dlg_progress.setModal(True)
        self._dlg_progress.hide()

        lbl_outputdir = QLabel("Output directory")
        self._txt_outputdir = DirBrowseWidget()

        max_workers = cpu_count() #@UndefinedVariable
        lbl_workers = QLabel('Number of workers')
        self._spn_workers = QSpinBox()
        self._spn_workers.setRange(1, max_workers)
        self._spn_workers.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        lbl_max_workers = QLabel('(max: %i)' % max_workers)

        self._chk_overwrite = QCheckBox("Overwrite existing results in output directory")
        self._chk_overwrite.setChecked(True)

        self._lbl_available = QLabel('Available')
        self._lst_available = QListView()
        self._lst_available.setModel(_AvailableOptionsListModel())
        self._lst_available.setSelectionMode(QListView.SelectionMode.MultiSelection)

        tlb_available = QToolBar()
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        tlb_available.addWidget(spacer)
        act_open = tlb_available.addAction(getIcon("document-open"), "Open")
        act_open.setShortcut(QKeySequence.Open)
        tlb_available.addSeparator()
        act_remove = tlb_available.addAction(getIcon("list-remove"), "Remove")
        act_clear = tlb_available.addAction(getIcon("edit-clear"), "Clear")

        self._btn_addtoqueue = QPushButton(getIcon("go-next"), "")
        self._btn_addtoqueue.setToolTip("Add to queue")
        self._btn_addtoqueue.setEnabled(False)

        self._btn_addalltoqueue = QPushButton(getIcon("go-last"), "")
        self._btn_addalltoqueue.setToolTip("Add all to queue")
        self._btn_addalltoqueue.setEnabled(False)

        self._lbl_options = QLabel('Queued/Running/Completed')
        self._tbl_options = QTableView()
        self._tbl_options.setModel(_StateOptionsTableModel())
        self._tbl_options.setItemDelegate(_StateOptionsItemDelegate())
        self._tbl_options.setSelectionMode(QListView.SelectionMode.NoSelection)
        self._tbl_options.setColumnWidth(1, 60)
        self._tbl_options.setColumnWidth(2, 80)
        header = self._tbl_options.horizontalHeader()
        header.setResizeMode(0, QHeaderView.Interactive)
        header.setResizeMode(1, QHeaderView.Fixed)
        header.setResizeMode(2, QHeaderView.Fixed)
        header.setResizeMode(3, QHeaderView.Stretch)

        self._btn_start = QPushButton(getIcon("media-playback-start"), "Start")

        self._btn_cancel = QPushButton("Cancel")
        self._btn_cancel.setEnabled(False)

        self._btn_close = QPushButton("Close")

        self._btn_import = QPushButton("Import")
        self._btn_import.setEnabled(False)

        # Layouts
        layout = QVBoxLayout()

        sublayout = QGridLayout()
        sublayout.addWidget(lbl_outputdir, 0, 0)
        sublayout.addWidget(self._txt_outputdir, 0, 1)
        sublayout.addWidget(lbl_workers, 1, 0)

        subsublayout = QHBoxLayout()
        subsublayout.addWidget(self._spn_workers)
        subsublayout.addWidget(lbl_max_workers)
        sublayout.addLayout(subsublayout, 1, 1)
        layout.addLayout(sublayout)

        sublayout.addWidget(self._chk_overwrite, 2, 0, 1, 3)

        sublayout = QGridLayout()
        sublayout.setColumnStretch(0, 1)
        sublayout.setColumnStretch(2, 3)
        sublayout.addWidget(self._lbl_available, 0, 0)
        sublayout.addWidget(self._lst_available, 1, 0)
        sublayout.addWidget(tlb_available, 2, 0)

        subsublayout = QVBoxLayout()
        subsublayout.addStretch()
        subsublayout.addWidget(self._btn_addtoqueue)
        subsublayout.addWidget(self._btn_addalltoqueue)
        subsublayout.addStretch()
        sublayout.addLayout(subsublayout, 1, 1)

        sublayout.addWidget(self._lbl_options, 0, 2)
        sublayout.addWidget(self._tbl_options, 1, 2)
        layout.addLayout(sublayout)

        sublayout = QHBoxLayout()
        sublayout.addStretch()
        sublayout.addWidget(self._btn_import)
        sublayout.addWidget(self._btn_start)
        sublayout.addWidget(self._btn_cancel)
        sublayout.addWidget(self._btn_close)
        layout.addLayout(sublayout)

        self.setLayout(layout)

        # Signal
        self._running_timer.timeout.connect(self._onRunningTimer)

        act_open.triggered.connect(self._onOpen)
        act_remove.triggered.connect(self._onRemove)
        act_clear.triggered.connect(self._onClear)

        self._btn_addtoqueue.released.connect(self._onAddToQueue)
        self._btn_addalltoqueue.released.connect(self._onAddAllToQueue)
        self._btn_start.released.connect(self._onStart)
        self._btn_cancel.released.connect(self._onCancel)
        self._btn_close.released.connect(self._onClose)
        self._btn_import.released.connect(self._onImport)

        self.options_added.connect(self._onOptionsAdded)
        self.options_running.connect(self._onOptionsRunning)
        self.options_simulated.connect(self._onOptionsSimulated)
        self.options_error.connect(self._onOptionsError)
        self.results_error.connect(self._onResultsError)

        # Defaults
        settings = get_settings()
        section = settings.add_section('gui')
        if hasattr(section, 'outputdir'):
            self._txt_outputdir.setPath(section.outputdir)
        if hasattr(section, 'maxworkers'):
            self._spn_workers.setValue(int(section.maxworkers))
        if hasattr(section, 'overwrite'):
            state = True if section.overwrite.lower() == 'true' else False
            self._chk_overwrite.setChecked(state)

    def _onDialogProgressProgress(self, progress, status):
        self._dlg_progress.setValue(progress * 100)
        self._dlg_progress.setLabelText(status)

    def _onDialogProgressCancel(self):
        self._dlg_progress.hide()
        if self._options_reader_thread is None:
            return
        self._options_reader_thread.cancel()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()

    def _onDialogProgressException(self, ex):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        messagebox.exception(self, ex)

    def _onRunningTimer(self):
        self._tbl_options.model().reset()

    def _onOpen(self):
        settings = get_settings()
        curdir = getattr(settings.gui, 'opendir', os.getcwd())

        filepath, namefilter = \
            QFileDialog.getOpenFileName(self, "Open", curdir,
                                        'Options [*.xml] (*.xml)')

        if not filepath or not namefilter:
            return
        settings.gui.opendir = os.path.dirname(filepath)

        if not filepath.endswith('.xml'):
            filepath += '.xml'

        self._options_reader_thread = _OptionsReaderWrapperThread(filepath)
        self._dlg_progress.canceled.connect(self._onDialogProgressCancel)
        self._options_reader_thread.resultReady.connect(self._onOpened)
        self._options_reader_thread.progressUpdated.connect(self._onDialogProgressProgress)
        self._options_reader_thread.exceptionRaised.connect(self._onDialogProgressException)
        self._options_reader_thread.start()

        self._dlg_progress.reset()
        self._dlg_progress.show()

    def _onOpened(self, options):
        self._dlg_progress.hide()
        self._options_reader_thread.quit()
        self._options_reader_thread.wait()
        self._options_reader_thread = None

        try:
            self._lst_available.model().addOptions(options)
        except Exception as ex:
            messagebox.exception(self, ex)

    def _onRemove(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            model.popOptions(row)

    def _onClear(self):
        self._lst_available.model().clearOptions()

    def _onAddToQueue(self):
        selection = self._lst_available.selectionModel().selection().indexes()
        if len(selection) == 0:
            QMessageBox.warning(self, "Queue", "Select an options")
            return

        model = self._lst_available.model()
        for row in sorted(map(methodcaller('row'), selection), reverse=True):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onAddAllToQueue(self):
        model = self._lst_available.model()
        for row in reversed(range(0, model.rowCount())):
            options = model.options(row)
            try:
                self._runner.put(options)
            except Exception as ex:
                messagebox.exception(self, ex)
                return

    def _onStart(self):
        outputdir = self._txt_outputdir.path()
        if not outputdir:
            QMessageBox.critical(self, 'Start', 'Missing output directory')
            return
        max_workers = self._spn_workers.value()
        overwrite = self._chk_overwrite.isChecked()
        self.start(outputdir, overwrite, max_workers)

    def _onCancel(self):
        self.cancel()

    def _onClose(self):
        if self._runner is not None:
            self._runner.close()
        self._running_timer.stop()
        self.close()

    def _onImport(self):
        list_options = self._lst_available.model().listOptions()
        if not list_options:
            return

        # Select options
        dialog = _OptionsSelector(list_options)
        if not dialog.exec_():
            return
        options = dialog.options()

        # Start importer
        outputdir = self._runner.outputdir
        max_workers = self._runner.max_workers
        importer = LocalImporter(outputdir, max_workers)

        importer.start()
        importer.put(options)

        self._dlg_progress.show()
        try:
            while importer.is_alive():
                if self._dlg_progress.wasCanceled():
                    importer.cancel()
                    break
                self._dlg_progress.setValue(importer.progress * 100)
        finally:
            self._dlg_progress.hide()

    def _onOptionsAdded(self, options):
        logging.debug('runner: optionsAdded')
        self._tbl_options.model().addOptions(options)

    def _onOptionsRunning(self, options):
        logging.debug('runner: optionsRunning')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsSimulated(self, options):
        logging.debug('runner: optionsSimulated')
        self._tbl_options.model().resetOptions(options)

    def _onOptionsError(self, options, ex):
        logging.debug('runner: optionsError')
        self._tbl_options.model().resetOptions(options)

    def _onResultsError(self, results, ex):
        logging.debug('runner: resultsError')
        self._tbl_options.model().reset()

    def closeEvent(self, event):
        if self.is_running():
            message = 'Runner is running. Do you want to continue?'
            answer = QMessageBox.question(self, 'Runner', message,
                                          QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                event.ignore()
                return

        self.cancel()
        self._dlg_progress.close()

        settings = get_settings()
        section = settings.add_section('gui')

        path = self._txt_outputdir.path()
        if path:
            section.outputdir = path
        section.maxworkers = str(self._spn_workers.value())
        section.overwrite = str(self._chk_overwrite.isChecked())

        settings.write()

        event.accept()

    def addAvailableOptions(self, options):
        self._lst_available.model().addOptions(options)

    def removeAvailableOptions(self, options):
        self._lst_available.model().removeOptions(options)

    def clearAvailableOptions(self):
        self._lbl_available.model().clearOptions()

    def start(self, outputdir, overwrite, max_workers):
        self._runner = LocalRunner(outputdir=outputdir,
                                   overwrite=overwrite,
                                   max_workers=max_workers)

        self._tbl_options.setModel(_StateOptionsTableModel(self._runner))

        self._spn_workers.setEnabled(False)
        self._txt_outputdir.setEnabled(False)
        self._chk_overwrite.setEnabled(False)
        self._btn_addtoqueue.setEnabled(True)
        self._btn_addalltoqueue.setEnabled(True)
        self._btn_start.setEnabled(False)
        self._btn_cancel.setEnabled(True)
        self._btn_close.setEnabled(False)
        self._btn_import.setEnabled(True)

        self._runner.options_added.connect(self.options_added.emit)
        self._runner.options_running.connect(self.options_running.emit)
        self._runner.options_simulated.connect(self.options_simulated.emit)
        self._runner.options_error.connect(self.options_error.emit)
        self._runner.results_saved.connect(self.results_saved.emit)
        self._runner.results_error.connect(self.results_error.emit)

        self._running_timer.start()
        self._runner.start()

    def cancel(self):
        if self._runner is None:
            return
        self._runner.cancel()
        self._running_timer.stop()

        self._runner.options_added.disconnect(self.options_added.emit)
        self._runner.options_running.disconnect(self.options_running.emit)
        self._runner.options_simulated.disconnect(self.options_simulated.emit)
        self._runner.options_error.disconnect(self.options_error.emit)
        self._runner.results_saved.disconnect(self.results_saved.emit)
        self._runner.results_error.disconnect(self.results_error.emit)

        self._runner = None

        self._spn_workers.setEnabled(True)
        self._txt_outputdir.setEnabled(True)
        self._chk_overwrite.setEnabled(True)
        self._btn_addtoqueue.setEnabled(False)
        self._btn_addalltoqueue.setEnabled(False)
        self._btn_start.setEnabled(True)
        self._btn_cancel.setEnabled(False)
        self._btn_close.setEnabled(True)
        self._btn_import.setEnabled(False)

    def is_running(self):
        return self._runner is not None and self._runner.is_alive()
Пример #37
0
class SpiderTab(QWidget):
  """Has handlers for spider data and events. It houses the results table of the
     spider, controls for the spider and progress indication
     It implicitly conforms to IEventHandler interface"""
  TIMER_CHECK_INTERVAL = 3000
  favicon_received = Signal(str) # send the url or path to the handler, which should be the tab widget
  stop_spider_signal = Signal(int)
  became_current = Signal(bool) # tell the table it has become active. it's an interesting property for producers!
  
  def __init__(self, parent=None, **kwargs):
    super(SpiderTab, self).__init__(parent)
    self._event_queue = None
    self._data_queue = None
    self._engine = None
    self._favicon_received = False
    self._spider_id = None
    self._item_count = 0
    self.setContextMenuPolicy(Qt.ContextMenuPolicy.DefaultContextMenu)
    self.initInterface(kwargs)
    self._context_menu = None
    self._setupContextMenu()
    self.became_current.connect(self._set_table_activity)
    self._queue_check_timer = QTimer()
    self._queue_check_timer.setInterval(self.TIMER_CHECK_INTERVAL)
    self._queue_check_timer.timeout.connect(self._checkQueues)
    self._queue_check_timer.start()
    
  def initInterface(self, kwargs):
    layout = QGridLayout()
    self._data_table = SearchTable(name=kwargs.get("name"))
    self._progress_spider = QProgressBar()
    self._label_count = QLabel(self.tr("0 items scraped"))
    # make it a busy indicator. you don't know when it'll finish 
    self._progress_spider.setMinimum(0); self._progress_spider.setMaximum(0)
    self._progress_spider.setTextVisible(False)
    self._btn_stop_spider = QPushButton(self.tr("Stop Spider"))
    self._btn_stop_spider.clicked.connect(self.stop_spider)
    row = 0; col = 0;
    layout.addWidget(self._data_table, row, col, 1, 4)
    row += 1;
    layout.addWidget(self._progress_spider, row, col, 1, 1)
    col += 1
    layout.addWidget(self._label_count, row, col, 1, 2)
    col += 2
    layout.addWidget(self._btn_stop_spider, row, col, 1, 1)
    self.setLayout(layout)
    
  def _setupContextMenu(self):
    from visualscrape.lib.data import ActionStore
    self._context_menu = QMenu(self)
    # get the export action from the action store
    action_store = ActionStore.get_instance()
    for action in action_store:
      if action.get_name() == "export":
        export_action = action
        break
    self._context_menu.addAction(export_action)
    
  def export_table(self):
    export_dialog = ExportDialog()
    export_dialog.exec_()
    export_info = export_dialog.data()
    if export_info:
      data = self._data_table.get_visible_data()
      FileExporter.export(data, self._data_table.name.lower(), export_info.location, export_info.format)
  
  def set_event_queue(self, eq):
    self._event_queue = eq
    
  def set_data_queue(self, dq):
    self._data_queue = dq
    
  def stop_spider(self):
    if self._spider_id is None: # do not stop the the spider before receiving data
      pass
    else:
      if self._queue_check_timer.isActive():
        confirm_stop = QMessageBox(self)
        confirm_stop.setIcon(QMessageBox.Warning)
        confirm_stop.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        confirm_stop.setText(self.tr("Scraping process still running"))
        confirm_stop.setDetailedText(self.tr("Are you sure you want to stop it?"))
        confirm_stop.setWindowTitle(self.tr("Spider still running"))
        ret = confirm_stop.exec_()
        if ret == QMessageBox.Yes:
          self.stop_spider_signal.emit(self._spider_id)
          return True
        else: return False # I won't whip you if you stop it accidentally
      else: return True # already over
      
  def configure_searchlineedit(self, lineEdit):
    self._data_table.configure_search_lineedit(lineEdit)
    
  def _checkQueues(self):
    while not self._event_queue.empty():
      event = self._event_queue.get(block=False, timeout=0)
      if isinstance(event, SpiderClosed):
        self._queue_check_timer.stop()
        self._progress_spider.setMinimum(0)
        self._progress_spider.setMaximum(100)
        self._progress_spider.setValue(100)
        self._btn_stop_spider.setEnabled(False)
    while not self._data_queue.empty():
      item = self._data_queue.get(block=False, timeout=0)
      if not self._favicon_received: # the first item on the data queue should be the favicon
        favicon_data = item["images"][0]
        self.favicon_received.emit(favicon_data["path"]) # note that icons are not guaranteed to have a path. Not everybody wants to save images
        self._favicon_received = True
        self._spider_id = item["_id"]
      else:
        item.pop("_id") # the table has nothing to do with spider ids
        self._data_table.addItem(item)
      self._item_count += 1
      self._label_count.setText(self.tr("{0:n} items scraped".format(self._item_count)))
      
  def _set_table_activity(self, state):
    self._data_table.set_active(state)
Пример #38
0
 def searchTimer(self):
     ret = QTimer(self.q)
     ret.setInterval(3000)
     ret.timeout.connect(self._search)
     ret.setSingleShot(True)
     return ret
Пример #39
0
class WalletController(QObject):
    onError = Signal(unicode)
    onConnected = Signal(bool)
    onTxSent = Signal(bool)
    onBusy = Signal()
    onDoubleEncrypted = Signal()
    onBalance = Signal()
    onFiatBalance = Signal()
    onWalletUnlocked = Signal()
    onCurrentBalance = Signal()
    onCurrentFiatBalance = Signal()
    onCurrentLabel = Signal()
    onCurrentAddress = Signal()
    onCurrentDoubleEncrypted = Signal()
    onCurrentPassKey = Signal()
    onCurrentWatchOnly = Signal()

    def __init__(self,):
        QObject.__init__(self,)
        self.thread = None
        self._balance = '<b>0.00</b>000000'
        self._fiatSymbol = u'€'
        self._fiatRate = 0
        self._fiatBalance = u'0 €'
        self._wallet = Wallet()
        self._wallet.onNewTransaction.connect(self.notifyNewTx)
        self._walletUnlocked = False
        self.settings = Settings()
        self.addressesModel = AddressesModel()
        self.transactionsModel = TransactionsModel()
        self.timer = QTimer(self)
        self.timer.setInterval(900000)  # 15 min update
        self.timer.timeout.connect(self.update)
        self.timer.start()

        if self.settings.storePassKey:
            self._currentPassKey = self.settings.passKey
            try:
                self.unlockWallet(self._currentPassKey)
            except:
                self.onError.emit('Stored pass phrase is invalid')
        else:
            self._currentPassKey = None
        self._currentAddressIndex = 0

    def on_event_data_received(self, *args):
        print 'BitPurse received DATA:', args

    def notifyNewTx(self, address, datas, amount):
        from eventfeed import EventFeedService, EventFeedItem
        service = EventFeedService('BitPurse',
                                   'BitPurse',
                                   self.on_event_data_received)
        item = EventFeedItem(
            '/usr/share/icons/hicolor/80x80/apps/bitpurse.png',
            'BitPurse')
        item.set_body('New transaction on address %s : %f BTC'
                      % (address, amount / float(10 ** 8)))
        # item.set_custom_action(self.notifyCallback)
        service.add_item(item)

    @Slot(unicode)
    def newAddr(self, doubleKey):
        try:
            self._wallet.createAddr(doubleKey)
            self.storeWallet()
            self.update()
        except (WrongPassword, DataError), err:
            self.onError.emit(unicode(err))
Пример #40
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.setFixedSize(960, 640)
        #不会出现对toolbar的隐藏
        self.toolBar.toggleViewAction().setVisible(False)
        self.finishingLayout()
        self.setupValue()
        self.setupSignal()
        self.setupAction(config=False,
                         start=False,
                         reset=False,
                         result=False,
                         printer=False,
                         back=False)
        self.setShow(1)
        self.setShow(3)

    def setupValue(self):
        self.__action = {
            "config": False,
            "start": False,
            "reset": False,
            "result": False,
            "print": False,
            "back": False,
            "exit": True
        }
        self.color_sheet = [
            '#0000ff', '#ff0000', '#ffff00', '#00ff40', '#00ffff', '#0080c0',
            '#8080c0', '#ff00ff', '#800000', '#ff8000', '#008040', '#800080',
            'black'
        ]
        self.lcd_group = [
            self.lcd_window.press_lcd1, self.lcd_window.press_lcd2,
            self.lcd_window.press_lcd3, self.lcd_window.press_lcd4,
            self.lcd_window.press_lcd5, self.lcd_window.press_lcd6,
            self.lcd_window.digital_lcd1, self.lcd_window.digital_lcd2,
            self.lcd_window.digital_lcd3, self.lcd_window.digital_lcd4,
            self.lcd_window.speed_lcd, self.lcd_window.acceleration_lcd,
            self.lcd_window.shift_lcd
        ]
        self.chk_group = [
            self.lcd_window.press_chk1, self.lcd_window.press_chk2,
            self.lcd_window.press_chk3, self.lcd_window.press_chk4,
            self.lcd_window.press_chk5, self.lcd_window.press_chk6,
            self.lcd_window.digital_chk1, self.lcd_window.digital_chk2,
            self.lcd_window.digital_chk3, self.lcd_window.digital_chk4,
            self.lcd_window.speed_chk, self.lcd_window.acceleration_chk,
            self.lcd_window.shift_chk
        ]
        self.tcp_link = TcpLink()
        #比例转换系数1,5,10
        self.scaleRegion = (40, 10, 5, 2, 1)
        self.scaleFactor = [10, 10, 10, 10, 10, 10]
        self.lines_data = [None] * 14
        self.report = {}
        self.report['PRESS'] = {}
        self.report['DIGITAL'] = {}
        self.ST_flag = False
        self.init_press = 0

    def setupSignal(self):
        self.connect(self.action_exit, SIGNAL("triggered()"), self.actionExit)
        self.connect(self.action_config, SIGNAL("triggered()"),
                     self.actionConfig)
        self.connect(self.action_start, SIGNAL("triggered()"),
                     self.actionStart)
        self.connect(self.action_reset, SIGNAL("triggered()"),
                     self.actionReset)
        self.connect(self.action_result, SIGNAL("triggered()"),
                     self.actionResult)
        self.connect(self.action_print, SIGNAL("triggered()"),
                     self.actionPrint)
        self.connect(self.action_back, SIGNAL("triggered()"), self.actionBack)
        self.connect(self.action_read_report, SIGNAL("triggered()"),
                     self.actionReadReport)
        self.connect(self.notice_window.default_part.connect_button,
                     SIGNAL("clicked()"), self.connectButtonClicked)
        self.connect(self.notice_window.default_part.read_file_button,
                     SIGNAL("clicked()"), self.readFileButtonClicked)
        self.notice_window.current_press.ready_button.clicked.connect(
            self.readyButtonClicked)
        self.lcd_window.st_transfer.clicked.connect(self.setShiftTimeChange)
        #不能在外界直接操作GUI只能采用信号槽方式
        self.tcp_link.signal_tips.connect(self.notice_window.setLblNotice)
        self.tcp_link.signal_noticeText.connect(
            self.notice_window.setNoticeText)
        self.tcp_link.signal_progressBar.connect(self.notice_window.setValue)
        self.tcp_link.signal_lcd.connect(self.setPress6LCDValue)
        self.tcp_link.signal_trigger.connect(self.actionStart)
        self.tcp_link.signal_result.connect(self.connectResult)
        self.tcp_link.signal_timeout.connect(self.dataTimeout)
        #右侧LCD 显示
        self.curve_window.lcd_signal.connect(self.lcdDisplay)
        for i in self.chk_group:
            i.toggled.connect(self.lcdCheck)
        #数据收集阶段定时器,根据具体情况删减
        self.draw_timer = QTimer(self)
        self.connect(self.draw_timer, SIGNAL("timeout()"), self.waitDraw)

    def finishingLayout(self):
        self.left_layout = QVBoxLayout()
        self.right_layout = QHBoxLayout()
        self.notice_window = NoticeWidget(self)
        self.curve_window = CurveWidget(self)
        self.left_layout.addWidget(self.curve_window)
        self.left_layout.addWidget(self.notice_window)
        self.curve_window.hide()
        self.widget_container.setLayout(self.left_layout)
        self.explain_window = Explain(self)
        self.configuration_window = Configuration(self)
        self.lcd_window = LCDGroup(self)
        self.right_layout.addWidget(self.explain_window)
        self.right_layout.addWidget(self.configuration_window)
        self.right_layout.addWidget(self.lcd_window)
        self.configuration_window.hide()
        self.lcd_window.hide()
        self.frame_container.setLayout(self.right_layout)

    def setShow(self, flag):
        """flag must a int"""
        if flag == 1:
            self.curve_window.hide()
            self.notice_window.show()
            self.notice_window.update()
        elif flag == 2:
            #print self.notice_window.geometry()
            self.notice_window.hide()
            self.curve_window.show()
            self.curve_window.update()
            #print self.curve_window.geometry()
            #print self.widget_container.geometry()
        elif flag == 3:
            self.explain_window.show()
            self.explain_window.update()
            self.configuration_window.hide()
            self.lcd_window.hide()
        elif flag == 4:
            self.explain_window.hide()
            self.configuration_window.show()
            self.configuration_window.update()
            self.lcd_window.hide()
        elif flag == 5:
            self.explain_window.hide()
            self.configuration_window.hide()
            self.lcd_window.show()
            self.lcd_window.update()

    def setupAction(self, **kwargs):
        """
        kwargs = {"config":False,"start":False,"reset":False,"result":False,"print":False,"back":False,
                    "exit":False}
        """
        for i in kwargs.keys():
            self.__action[i] = kwargs[i]
        self.action_config.setEnabled(self.__action["config"])
        self.action_start.setEnabled(self.__action["start"])
        self.action_reset.setEnabled(self.__action["reset"])
        self.action_result.setEnabled(self.__action["result"])
        self.action_print.setEnabled(self.__action["printer"])
        self.action_back.setEnabled(self.__action["back"])
        self.action_exit.setEnabled(self.__action["exit"])

    def actionOrder(self, order):
        if order == 'init':
            self.setupAction(config=False,
                             start=False,
                             reset=False,
                             result=False,
                             printer=False,
                             back=False)
            self.setShow(1)
            self.setShow(3)
            self.notice_window.setShow(1)
            self.notice_window.reset()
            self.notice_window.setLblNotice(u"点击[检测连接(Ctrl+Alt+L)]与下位机建立通信连接\
                                 \n点击[读取文档(Ctrl+Alt+R)]读取已保存的数据文档")
            self.action_back.setText(u"首页/断开")
        elif order == 'config':
            self.setupAction(config=True, back=True)
            self.notice_window.setShow(2)
            self.setShow(1)
            self.setShow(4)
            self.notice_window.reset()
            self.notice_window.setLblNotice(u"点击[参数设置(F1)]对要进行测量的项目进行相关参数的设置\n"
                                            u"点击[断开连接(F7)]断开与下位机的通信")
            self.action_back.setText(u"断开连接")
        elif order == 'ready':
            self.setupAction(config=False, reset=True)
            self.setShow(1)
            self.setShow(4)
            self.notice_window.setShow(3)
            self.notice_window.setLblNotice(u"点击[准备测试(Ctrl+Alt+R)]进入测量\n"
                                            u"点击[复位(F3)]对配置信息进行重新配置")
        elif order == 'reset':
            self.setupAction(config=True,
                             start=False,
                             reset=False,
                             result=False,
                             printer=False)
            self.notice_window.setShow(2)
            self.setShow(1)
            self.setShow(4)
            self.notice_window.setLblNotice(u"点击[参数设置(F1)]对要进行测量的项目进行相关参数的设置\
                                 \n点击[断开连接(F7)]断开与下位机的通信")
            self.notice_window.setNoticeText(u"对下次测试进行重新配置")
        elif order == 'trigger':
            self.notice_window.setShow(2)
            self.notice_window.setLblNotice(u'此时请勿进行其他操作,若要停止测试请点击[复位(F3)]')
            self.notice_window.setNoticeText(u'等待触发......')
        elif order == 'start':
            self.setupAction(start=True)
            self.notice_window.setShow(2)
            self.notice_window.setLblNotice(
                u'点击[开始(F2)]进行测量,若要重新测试请点击[复位(F3)]')
            self.notice_window.setNoticeText(u'手动触发方式')
        elif order == 'draw':
            self.setupAction(result=True, printer=True)
        elif order == 'tips':
            pass
        elif order == 'read':
            self.setShow(2)
            self.setShow(5)
            self.setupAction(back=True, result=True)
            self.action_back.setText(u"返回首页")

    def actionConfig(self):
        """根据配置对话框的内容获取相关参数"""
        config_dialog = ConfigDialog(self.tcp_link.getLineState)
        config_dialog.show()
        config_dialog.exec_()
        if config_dialog.getPassFlag():
            self.group_digital = [(i[0].text(), i[1].isChecked())
                                  for i in config_dialog.group_digital]
            self.group_press = [(i[0].text(), i[1].isChecked(),
                                 i[2].currentIndex())
                                for i in config_dialog.group_press]
            self.group_speed_trigger = [
                config_dialog.speed_chk.isChecked(),
                config_dialog.trigger_combo.currentIndex()
            ]
            #测试项目,项目名称,测试人员,测试日期
            self.groupNPTInfo = [
                config_dialog.testProject.currentIndex(),
                config_dialog.projectName_edit.text(),
                config_dialog.person_edit.text(),
                config_dialog.time_edit.text()
            ]
            #测试时长
            self.measure_time = config_dialog.measureTime
            #测试距离
            self.measure_distance = config_dialog.measureDistance
            #set默认通道
            self.default_press = config_dialog.default_press.currentIndex()
            #设置默认膛压通道
            self.notice_window.setDefault(self.default_press)
            self.default_digital = config_dialog.default_digital.currentIndex()
            self.tcp_link.setPressChannel(self.default_press)
            self.tcp_link.setDigitalChannel(self.default_digital)
            self.tcp_link.setThresholdPress(config_dialog.threshold_press)
            self.tcp_link.setCalibration(config_dialog.calibration)
            self.tcp_link.setSpeedFactor(self.groupNPTInfo[0])
            #需要绘制的坐标系
            self.exist_axis = []
            #需要调整宽度的坐标系
            axis_num = []
            for i, j in enumerate(self.group_press):
                if j[1]:
                    self.exist_axis.append(i)
                    axis_num.append((i, j[2]))
                    self.scaleFactor[i] = self.scaleRegion[j[2]]
                    #if j[0]:
                    #self.report['PRESS'][i] = j[0]
                    #else:
                    #self.report['PRESS'][i] = u'通道%d' %(i + 1)
                else:
                    self.scaleFactor[i] = 0
                    #self.report['PRESS'][i] = None
            for i, j in enumerate(self.group_digital):
                if j[1]:
                    self.exist_axis.append(i + 6)
                    #if j[0]:
                    #self.report['DIGITAL'][i] = j[0]
                    #else:
                    #self.report['DIGITAL'][i] = '通道%d' %(i + 1)
                #else:
                #self.report['DIGITAL'][i] = None
            if self.group_speed_trigger[0]:
                self.exist_axis.extend([10, 11, 12])
                if self.groupNPTInfo[0] == 0:
                    axis_num.append((12, 1))
                else:
                    axis_num.append((12, 4))
            self.tcp_link.setFactor(self.scaleFactor[:])
            #print self.scaleFactor
            self.curve_window.produceAxis(self.exist_axis[:])
            for i in (axis_num):
                self.curve_window.setTicker(i[0], i[1])
            #开始根据配置获取需求值并显示当前压力
            self.tcp_link.setTestFlag(False)
            self.tcp_link.setCurrentFlag(True)
            #报告关键值
            #序列号
            self.report['SERIAL'] = self.groupNPTInfo[1]
            _test_type = [u'鱼雷', u'诱饵']
            self.report['TYPE'] = _test_type[self.groupNPTInfo[0]]
            _trigger = [u'自动触发', u'手动触发', u'外触发']
            self.report['TRIGGER'] = _trigger[
                self.group_speed_trigger[1]]  #触发方式
            self.report['PERSON'] = self.groupNPTInfo[2]  #测试人员
            self.report['DATE'] = self.groupNPTInfo[3]  #测试日期
            self.tcp_link.setCurrentFlag(True)
            self.actionOrder('ready')
            #print self.measure_distance
        self.configuration_window.readConfig()

    def actionStart(self):
        #print 'start'
        self.lcd_window.check([i[1] for i in self.group_press],
                              [i[1] for i in self.group_digital],
                              self.group_speed_trigger[0])
        #print self.group_speed_trigger[0]
        self.tcp_link.setTriggerFlag(False)
        self.tcp_link.setClearFlag(False)
        self.setupAction(start=False)
        self.notice_window.reset()
        self.setShow(1)
        self.notice_window.setLblNotice(u'正在接收数据中,若想停止测量可直接点击[复位(F3)]终止本次测量')
        self.notice_window.setShow(2)
        self.notice_window.setNoticeText(u'系统正在测量,请等待......')
        self.notice_window.setValue(1)
        self.draw_count = 0
        self.draw_timer.start(100)
        self.draw_timer.setInterval(100)

    def waitDraw(self):
        self.draw_count += 0.1
        value = 100 / (self.measure_time) * self.draw_count
        self.notice_window.setValue(value)
        if self.draw_count >= self.measure_time:
            self.draw()

    def draw(self):
        #关闭时间
        self.tcp_link.setClearFlag(True)
        self.draw_timer.stop()
        self.notice_window.setNoticeText(u'数据接收完毕,处理中......')

        data = self.tcp_link.getData()
        #若无数据直接返回
        if not data:
            self.actionReset()
            return
        #print len(data), 'total data'
        speed_data = data[15::16]
        self.handle = HandleData(speed_data, self.measure_distance)
        length = len(speed_data)
        #开始运动点num
        num = self.handle.getStartTime()
        shift = self.handle.shift()
        if self.groupNPTInfo[0] == 0:
            speed_out = self.handle.getOutTime(shift)
        else:
            speed_out = self.handle.getStopTime(shift, self.measure_distance)
        #所截取数据的长度
        right_limit = speed_out + 100
        if right_limit > length:
            right_limit = speed_out + 1
        if self.group_speed_trigger[0]:
            x_data = [(i - num) * 5E-4 for i in range(length)]
        else:
            x_data = [i * 5E-4 for i in range(length)]
        self.lines_data[0] = x_data[:right_limit]
        #print self.exist_axis
        for i in range(10):
            y_data = data[i::16]
            self.lines_data[i + 1] = y_data[:right_limit]
            if i < 6:
                if i in self.exist_axis:
                    #不同测试类型取值不同
                    if self.groupNPTInfo[0] == 0:

                        _value = y_data[int(self.measure_time * 2000)]
                        #_value = max(y_data)
                        self.report['PRESS'][i + 1] = '%0.2f' % _value
                        if i == self.default_press:
                            self.report['PRESS'][
                                i + 1] = '%0.2f' % (_value - self.init_press)
                            self.handle.setChamberPressure(
                                self.lines_data[i + 1], self.init_press)
                    else:
                        # _value = y_data[speed_out]
                        _value = y_data[int(self.measure_time * 2000)]
                        self.report['PRESS'][i + 1] = '%0.2f' % _value
                    self.curve_window.drawLine2D(self.exist_axis.index(i),
                                                 self.lines_data[0],
                                                 self.lines_data[i + 1],
                                                 self.color_sheet[i])
                else:
                    self.report['PRESS'][i + 1] = '--'
            else:
                if i in self.exist_axis:
                    begin = self.handle.bleedTime(y_data)
                    #dead = length - begin
                    #self.report['DIGITAL'][i - 5] = ('%0.2f' %(begin*5E-4), '%0.2f' %(dead*5E-4))
                    self.report['DIGITAL'][i - 5] = '%0.1f' % (begin * 5E-4)
                    self.curve_window.drawLine2D(self.exist_axis.index(i),
                                                 self.lines_data[0],
                                                 self.lines_data[i + 1],
                                                 self.color_sheet[i])
                else:
                    self.report['DIGITAL'][i - 5] = ('--')
        self.lines_data[11] = speed_data[:right_limit]
        #加速度
        acceleration = self.handle.acceleration()
        self.lines_data[12] = acceleration[:right_limit]
        self.lines_data[13] = shift[:right_limit]
        if 10 in self.exist_axis:
            self.report['SPEED'] = '%0.1f' % speed_data[speed_out]
            self.curve_window.drawLine2D(self.exist_axis.index(10),
                                         self.lines_data[0],
                                         self.lines_data[11],
                                         self.color_sheet[10])
            self.report['ACCELERATION'] = '%0.1f' % acceleration[speed_out]
            self.curve_window.drawLine2D(self.exist_axis.index(11),
                                         self.lines_data[0],
                                         self.lines_data[12],
                                         self.color_sheet[11])
            self.curve_window.drawLine2D(self.exist_axis.index(12),
                                         self.lines_data[0],
                                         self.lines_data[13],
                                         self.color_sheet[12])
        else:
            self.report['SPEED'] = '--'
            self.report['ACCELERATION'] = '--'
        #图像填充全屏
        self.curve_window.setXFull(self.lines_data[0][0],
                                   self.lines_data[0][-1])
        #延迟时间
        self.report['DELAY'] = '%0.1f' % (num * 5E-4)
        #发射时间
        self.report['SHOOT'] = '%0.1f' % (speed_out * 5E-4)
        #flag = self.report['DIGITAL'].get(self.default_digital + 1, ('--', '--'))
        if self.group_digital[self.default_digital][1]:
            begin, dead = self.handle.getStartClock(
                data[6 + self.default_digital::16])
            #print begin, dead
            #泄放阀开启时间
            self.report['OPEN'] = '%0.1f' % (begin * 5E-4)
            #泄放阀开启时机
            self.report['BLEED'] = '%0.1f' % shift[dead]
        else:
            self.report['OPEN'] = '--'
            self.report['BLEED'] = '--'
        now_time = datetime.datetime.now()
        file_path = now_time.strftime("%Y%m%d%H%M%S")
        if self.groupNPTInfo[0] == 0:
            filename = u'鱼雷' + self.groupNPTInfo[1] + file_path
        else:
            filename = u'诱饵' + self.groupNPTInfo[1] + file_path
        #self.tempHTML(self.group_press, self.group_digital, './template/'+'image.png')
        self.tempPicture("./template/" + "image.png")
        self.saveReport('./report/' + filename + '.pdf')
        self.saveFile('./DigitalSheet/' + filename + '.csv')
        self.curve_window.updateDraw()
        self.curve_window._init_View()
        self.notice_window.setValue(100)
        self.setShow(2)
        self.setShow(5)
        self.actionOrder('draw')

    def tempPicture(self, filename):
        directory = os.path.dirname(filename)
        if not os.path.isdir(directory):
            os.makedirs(directory)
        self.curve_window.canvas.print_figure(filename, dpi=300)

    def saveReport(self, filename):
        directory = os.path.dirname(filename)
        if not os.path.isdir(directory):
            os.makedirs(directory)
        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOrientation(QPrinter.Landscape)
        printer.setPageSize(QPrinter.A4)
        printer.setOutputFileName(filename)
        if filename:
            self.print_(printer)

    def print_(self, printer):
        painter = QPainter(printer)
        pageRect = printer.pageRect()
        w = pageRect.width() * 0.85
        h = pageRect.height()
        painter.drawPixmap(0, 0, w, h, './template/image.png')

        sansFont = QFont("Helvetica", 10)
        painter.setFont(sansFont)
        fm = QFontMetrics(sansFont)
        height = fm.height() + 10
        vmargin = 40

        x0 = w + 1
        y = 25
        width = fm.width(u"测试编号") + 25
        x1 = x0 + width
        painter.drawText(x0, y, u"报告编号")
        painter.drawText(x1, y, self.report['SERIAL'])

        y += height
        painter.drawText(x0, y, u"测试类型")
        painter.drawText(x1, y, self.report['TYPE'])

        y += height
        painter.drawText(x0, y, u"触发方式")
        painter.drawText(x1, y, self.report['TRIGGER'])

        y += height
        painter.drawText(x0, y, u"测试人员")
        painter.drawText(x1, y, self.report['PERSON'])

        y += height
        painter.drawText(x0, y, u"测试日期")
        painter.drawText(x1, y, self.report['DATE'])

        y += vmargin
        width = fm.width(u"通道1") + 50
        x1 = x0 + width
        space = 0
        painter.drawText(x0 + 20, y, u"压力通道(Mpa)")
        for i, j in enumerate(self.group_press):
            if j[1]:
                y += height
                if j[0]:
                    painter.drawText(x0, y, j[0])
                else:
                    painter.drawText(x0, y, '通道%d'.decode("utf-8") % (i + 1))
                painter.drawText(x1, y, self.report['PRESS'][i + 1])
            else:
                space += height

        y += (vmargin + space)
        width = fm.width(u"通道计量1") + 15
        x1 = x0 + width
        #x2 = x1 + width
        painter.drawText(x0 + 20, y, u"数字量计时通道(s)")
        y += height
        painter.drawText(x0, y, u"通道")
        painter.drawText(x1, y, u"开启时间")
        #painter.drawText(x2, y, u"关闭")
        space = 0
        for i, j in enumerate(self.group_digital):
            if j[1]:
                y += height
                if j[0]:
                    painter.drawText(x0, y, j[0])
                else:
                    painter.drawText(x0, y, '通道%d'.decode("utf-8") % (i + 1))
                painter.drawText(x1, y, self.report['DIGITAL'][i + 1][0])
                #painter.drawText(x2, y, self.report['DIGITAL'][i + 1][1])
            else:
                space += height

        y += (vmargin + space)
        width = fm.width(u"出管速度(m/s)") + 25
        x1 = x0 + width
        painter.drawText(x0, y, u"加速度(g)")
        painter.drawText(x1, y, self.report['ACCELERATION'])

        y += height
        painter.drawText(x0, y, u"出管速度(m/s)")
        painter.drawText(x1, y, self.report['SPEED'])

        y += height
        painter.drawText(x0, y, u"延迟时间(s)")
        painter.drawText(x1, y, self.report['DELAY'])

        y += height
        painter.drawText(x0, y, u"发射时间(s)")
        painter.drawText(x1, y, self.report['SHOOT'])

        y += height
        painter.drawText(x0, y, u"发射深度(s)")
        painter.drawText(x1, y, self.report['DEEP'])

        width = fm.width(u"泄放装置泄放时间(s)") + 5
        y += height
        painter.drawText(x0, y, u"泄放阀开启时机(m)")
        x1 = x0 + width
        painter.drawText(x1, y, self.report['BLEED'])

        y += height
        painter.drawText(x0, y, u"泄放阀开启时间(s)")
        x1 = x0 + width + 1
        painter.drawText(x1, y, self.report['OPEN'])

    def saveFile(self, filename):
        directorys = os.path.dirname(filename)
        if not os.path.isdir(directorys):
            os.makedirs(directorys)
        if not os.path.isfile(filename):
            try:
                file = open(filename, 'w')
            except Exception, e:
                file.close()
                return
            press = '&'.join([self.report['PRESS'][i] for i in range(1, 7)])
            digital = '&'.join(
                [self.report['DIGITAL'][i] for i in range(1, 5)])
            bleed_value = '&'.join([self.report['OPEN'], self.report['BLEED']])
            #20131216对保存的数据进行修改
            datapool = [
                'startest', self.report['SERIAL'], self.report['TYPE'],
                self.report['TRIGGER'], self.report['PERSON'],
                self.report['DATE'], press, digital,
                self.report['ACCELERATION'], self.report['SPEED'],
                self.report['DELAY'], self.report['SHOOT'], bleed_value,
                self.report['DEEP']
            ]
            saveString = self.setText(','.join(datapool))
            #print saveString
            file.write(saveString)
            file.write('\n')
            datapool = []

            datapool.append('0')
            for i in range(6):
                datapool.append('%d' % self.group_press[i][2])
            for i in range(4):
                datapool.append('0')
            datapool.append('0')
            datapool.append('0')
            if self.groupNPTInfo[0] == 0:
                datapool.append('1')
            else:
                datapool.append('4')
            saveString = ','.join(['%s' % i for i in datapool])
            file.write(saveString)
            file.write('\n')
            datapool = []

            datapool.append(True)
            datapool.extend([chk[1] for chk in self.group_press])
            datapool.extend([chk[1] for chk in self.group_digital])
            datapool.extend([self.group_speed_trigger[0] for i in range(3)])
            saveString = ','.join(['%s' % i for i in datapool])
            file.write(saveString)
            file.write('\n')
            datapool = []

            for i, j in enumerate(self.lines_data[0]):
                for k in range(14):
                    datapool.append(self.lines_data[k][i])
                saveString = ','.join(['%s' % v for v in datapool])
                file.write(saveString)
                file.write('\n')
                datapool = []
            file.close()
Пример #41
0
class VideoMediaView(MediaView):
    def __init__(self, media, parent):
        super(VideoMediaView, self).__init__(media, parent)
        self._widget = QWidget(parent)
        self._process = QProcess(self._widget)
        self._process.setObjectName('%s-process' % self.objectName())
        self._std_out = []
        self._errors = []
        self._stopping = False
        self._mute = False
        if 'mute' in self._options:
            self._mute = bool(int(self._options['mute']))

        self._widget.setGeometry(media['_geometry'])
        self.connect(self._process, SIGNAL("error()"), self._process_error)
        self.connect(self._process, SIGNAL("finished()"), self.stop)
        self.connect(self._process, SIGNAL("readyReadStandardOutput()"),
                     self.__grep_std_out)
        self.set_default_widget_prop()

        self._stop_timer = QTimer(self)
        self._stop_timer.setSingleShot(True)
        self._stop_timer.setInterval(1000)
        self._stop_timer.timeout.connect(self._force_stop)

    @Slot()
    def _force_stop(self):
        os.kill(self._process.pid(), signal.SIGTERM)
        self._stopping = False
        if not self.is_started():
            self.started_signal.emit()
        super(VideoMediaView, self).stop()

    @Slot(object)
    def _process_error(self, err):
        self._errors.append(err)
        self.stop()

    @Slot()
    def play(self):
        self._finished = 0
        path = "%s/%s" % (self._save_dir, self._options['uri'])
        self._widget.show()
        args = [
            '-slave', '-identify', '-input',
            'nodefault-bindings:conf=/dev/null', '-wid',
            str(int(self._widget.winId())), path
        ]
        if self._mute:
            args += ['-ao', 'null']

        self._process.start('mplayer', args)
        self._stop_timer.start()

    @Slot()
    def stop(self, delete_widget=False):
        if self._stopping or self.is_finished():
            return False
        self._stop_timer.start()
        self._stopping = True
        if self._process.state() == QProcess.ProcessState.Running:
            self._process.write("quit\n")
            self._process.waitForFinished(50)
            self._process.close()

        super(VideoMediaView, self).stop(delete_widget)
        self._stopping = False
        self._stop_timer.stop()
        return True

    @Slot()
    def __grep_std_out(self):
        lines = self._process.readAllStandardOutput().split("\n")
        for line in lines:
            if not line.isEmpty():
                if line.startsWith("Starting playback"):
                    self._widget.raise_()
                    self._play_timer.start()
                    self.started_signal.emit()
                    self._stop_timer.stop()
                else:
                    part = line.split("=")
                    if 'ID_LENGTH' == part[0]:
                        if float(
                                self._duration
                        ) > 0:  # user set the video duration manually.
                            self._play_timer.setInterval(
                                int(1000 * float(self._duration)))
                        else:  # use duration found by mplayer.
                            self._play_timer.setInterval(
                                int(1000 * float(part[1])))
Пример #42
0
class Plot2DDataWidget(QWidget):
    def __init__(self,parent=None,measdata=[[1,3,2],[3,5,7]],header=["index","prime numbers"],SymbolSize=10,linecolor='y',pointcolor='b',title='Plot Window'):
        # This class derivates from a Qt MainWindow so we have to call
        # the class builder ".__init__()"
        #QMainWindow.__init__(self)
        QWidget.__init__(self)
        # "self" is now a Qt Mainwindow, then we load the user interface
        # generated with QtDesigner and call it self.ui
        self.ui = Plot2DDataWidget_Ui.Ui_Plot2DData()
        # Now we have to feed the GUI building method of this object (self.ui)
        # with a Qt Mainwindow, but the widgets will actually be built as children
        # of this object (self.ui)
        self.ui.setupUi(self)
        self.setWindowTitle(title)
        self.x_index=0
        self.y_index=0
        self.curve=self.ui.plot_area.plot(pen=linecolor)
        self.curve.setSymbolBrush(pointcolor)
        self.curve.setSymbol('o')
        self.curve.setSymbolSize(SymbolSize)
        
        self.parent=parent
        self.measdata=measdata
        self.header=header
        self.update_dropdown_boxes(header)
        
        self.update_plot_timer = QTimer()
        self.update_plot_timer.setSingleShot(True) #The timer would not wait for the completion of the task otherwise
        self.update_plot_timer.timeout.connect(self.autoupdate)

        if self.ui.auto_upd.isChecked():self.autoupdate()
            
    def update_timer_timeout(self,msec):
        self.update_plot_timer.setInterval(msec)
        
    def updateX(self,value):
        self.x_index=value
        #self.update_plot() #that was the bug
        #This created a loop because update_plot called check_connection
        #which called update_dropdown_boxes, which cleared the x_axis_box
        #which triggered a call to updateX
        
    def updateY(self,value):
        self.y_index=value
        #self.update_plot()
        
    def change_line_color(self,color=None):
        if color==None:color=QColorDialog.getColor()
        if color.isValid():
            self.curve.setPen(color)
            
    def change_point_color(self,color=None):
        if color==None:color=QColorDialog.getColor()
        if color.isValid():
            self.curve.setSymbolBrush(color)
            
    def change_symbol_size(self,value):
        self.curve.setSymbolSize(value)

    def check_connection(self,state=1):
        """check if the pointer to the Master dataset to display (self.measdata in Main.py) has changed"""
        if state and hasattr(self.parent,"measdata"):
            if self.parent.measdata!=self.measdata:self.measdata=self.parent.measdata
            if self.parent.current_header!=self.header:self.update_dropdown_boxes(self.parent.current_header)
            #print "Reestablishing connection"
    
    def autoupdate(self,state=1):
        if state:
            self.update_plot()
            self.update_plot_timer.start(self.ui.refresh_rate.value()*1000)#The value must be converted to milliseconds
        else:
            self.update_plot_timer.stop()
            
    def update_plot(self):
        """plot the data columns selected in the drop-down menu boxes"""
        if self.ui.autoconnect.isChecked():self.check_connection()
        if self.x_index!=-1 and self.y_index!=-1 and self.measdata[self.x_index]!=[] and self.measdata[self.y_index]!=[]:            
            self.curve.setData(self.measdata[self.x_index],self.measdata[self.y_index])
    
    def update_dropdown_boxes(self,header):
        """Update the drop-down boxes that select the content of the plot"""
        self.ui.x_axis_box.clear()
        self.ui.x_axis_box.addItems(header) 
        self.ui.y_axis_box.clear()
        self.ui.y_axis_box.addItems(header)
        self.header=header
Пример #43
0
class _CompletionList(QListView):
    """Completion list widget
    """
    closeMe = pyqtSignal()
    itemSelected = pyqtSignal(int)
    tabPressed = pyqtSignal()
    
    _MAX_VISIBLE_ROWS = 20  # no any technical reason, just for better UI
    
    _ROW_MARGIN = 6
    
    def __init__(self, qpart, model):
        QListView.__init__(self, qpart.viewport())
        self.setItemDelegate(HTMLDelegate(self))
        
        self._qpart = qpart
        self.setFont(qpart.font())
        
        self.setCursor(QCursor(Qt.PointingHandCursor))
        self.setFocusPolicy(Qt.NoFocus)
        
        self.setModel(model)
        
        self._selectedIndex = -1
        
        # if cursor moved, we shall close widget, if its position (and model) hasn't been updated
        self._closeIfNotUpdatedTimer = QTimer()
        self._closeIfNotUpdatedTimer.setInterval(200)
        self._closeIfNotUpdatedTimer.setSingleShot(True)

        self._closeIfNotUpdatedTimer.timeout.connect(self._afterCursorPositionChanged)
        
        qpart.installEventFilter(self)
        
        qpart.cursorPositionChanged.connect(self._onCursorPositionChanged)
        
        self.clicked.connect(lambda index: self.itemSelected.emit(index.row()))
        
        self.updateGeometry()
        self.show()
        
        qpart.setFocus()
    
    def __del__(self):
        """Without this empty destructor Qt prints strange trace
            QObject::startTimer: QTimer can only be used with threads started with QThread
        when exiting
        """
        pass
    
    def del_(self):
        """Explicitly called destructor.
        Removes widget from the qpart
        """
        self._closeIfNotUpdatedTimer.stop()
        self._qpart.removeEventFilter(self)
        self._qpart.cursorPositionChanged.disconnect(self._onCursorPositionChanged)
        
        # if object is deleted synchronously, Qt crashes after it on events handling
        QTimer.singleShot(0, lambda: self.setParent(None))

    def sizeHint(self):
        """QWidget.sizeHint implementation
        Automatically resizes the widget according to rows count
        
        FIXME very bad algorithm. Remove all this margins, if you can
        """
        width = max([self.fontMetrics().width(word) \
                        for word in self.model().words])
        width = width * 1.4  # FIXME bad hack. invent better formula
        width += 30  # margin
        
        # drawn with scrollbar without +2. I don't know why
        rowCount = min(self.model().rowCount(), self._MAX_VISIBLE_ROWS)
        height = (self.sizeHintForRow(0) * rowCount) + self._ROW_MARGIN

        return QSize(width, height)

    def minimumHeight(self):
        """QWidget.minimumSizeHint implementation
        """
        return self.sizeHintForRow(0) + self._ROW_MARGIN

    def _horizontalShift(self):
        """List should be plased such way, that typed text in the list is under
        typed text in the editor
        """
        strangeAdjustment = 2  # I don't know why. Probably, won't work on other systems and versions
        return self.fontMetrics().width(self.model().typedText()) + strangeAdjustment

    def updateGeometry(self):
        """Move widget to point under cursor
        """
        WIDGET_BORDER_MARGIN = 5
        SCROLLBAR_WIDTH = 30  # just a guess
        
        sizeHint = self.sizeHint()
        width = sizeHint.width()
        height = sizeHint.height()

        cursorRect = self._qpart.cursorRect()
        parentSize = self.parentWidget().size()
        
        spaceBelow = parentSize.height() - cursorRect.bottom() - WIDGET_BORDER_MARGIN
        spaceAbove = cursorRect.top() - WIDGET_BORDER_MARGIN
        
        if height <= spaceBelow or \
           spaceBelow > spaceAbove:
            yPos = cursorRect.bottom()
            if height > spaceBelow and \
               spaceBelow > self.minimumHeight():
                height = spaceBelow
                width = width + SCROLLBAR_WIDTH
        else:
            if height > spaceAbove and \
               spaceAbove > self.minimumHeight():
                height = spaceAbove
                width = width + SCROLLBAR_WIDTH
            yPos = max(3, cursorRect.top() - height)

        xPos = cursorRect.right() - self._horizontalShift()
        
        if xPos + width + WIDGET_BORDER_MARGIN > parentSize.width():
            xPos = max(3, parentSize.width() - WIDGET_BORDER_MARGIN - width)
        
        self.setGeometry(xPos, yPos, width, height)
        self._closeIfNotUpdatedTimer.stop()
    
    def _onCursorPositionChanged(self):
        """Cursor position changed. Schedule closing.
        Timer will be stopped, if widget position is being updated
        """
        self._closeIfNotUpdatedTimer.start()

    def _afterCursorPositionChanged(self):
        """Widget position hasn't been updated after cursor position change, close widget
        """
        self.closeMe.emit()

    def eventFilter(self, object, event):
        """Catch events from qpart
        Move selection, select item, or close themselves
        """
        if event.type() == QEvent.KeyPress and event.modifiers() == Qt.NoModifier:
            if event.key() == Qt.Key_Escape:
                self.closeMe.emit()
                return True
            elif event.key() == Qt.Key_Down:
                if self._selectedIndex + 1 < self.model().rowCount():
                    self._selectItem(self._selectedIndex + 1)
                return True
            elif event.key() == Qt.Key_Up:
                if self._selectedIndex - 1 >= 0:
                    self._selectItem(self._selectedIndex - 1)
                return True
            elif event.key() in (Qt.Key_Enter, Qt.Key_Return):
                if self._selectedIndex != -1:
                    self.itemSelected.emit(self._selectedIndex)
                    return True
            elif event.key() == Qt.Key_Tab:
                self.tabPressed.emit()
                return True
        elif event.type() == QEvent.FocusOut:
            self.closeMe.emit()

        return False

    def _selectItem(self, index):
        """Select item in the list
        """
        self._selectedIndex = index
        self.setCurrentIndex(self.model().createIndex(index, 0))
Пример #44
0
class QtReactor(posixbase.PosixReactorBase):
    implements(IReactorFDSet)

    def __init__(self):
        self._reads = {}
        self._writes = {}
        self._notifiers = {}
        self._timer = QTimer()
        self._timer.setSingleShot(True)
        QObject.connect(self._timer, SIGNAL("timeout()"), self.iterate)

        if QCoreApplication.instance() is None:
            # Application Object has not been started yet
            self.qApp=QCoreApplication([])
            self._ownApp=True
        else:
            self.qApp = QCoreApplication.instance()
            self._ownApp=False
        self._blockApp = None
        posixbase.PosixReactorBase.__init__(self)


    def _add(self, xer, primary, type):
        """
Private method for adding a descriptor from the event loop.

It takes care of adding it if new or modifying it if already added
for another state (read -> read/write for example).
"""
        if xer not in primary:
            primary[xer] = TwistedSocketNotifier(None, self, xer, type)


    def addReader(self, reader):
        """
Add a FileDescriptor for notification of data available to read.
"""
        self._add(reader, self._reads, QSocketNotifier.Read)


    def addWriter(self, writer):
        """
Add a FileDescriptor for notification of data available to write.
"""
        self._add(writer, self._writes, QSocketNotifier.Write)


    def _remove(self, xer, primary):
        """
Private method for removing a descriptor from the event loop.

It does the inverse job of _add, and also add a check in case of the fd
has gone away.
"""
        if xer in primary:
            notifier = primary.pop(xer)
            notifier.shutdown()

        
    def removeReader(self, reader):
        """
Remove a Selectable for notification of data available to read.
"""
        self._remove(reader, self._reads)


    def removeWriter(self, writer):
        """
Remove a Selectable for notification of data available to write.
"""
        self._remove(writer, self._writes)


    def removeAll(self):
        """
Remove all selectables, and return a list of them.
"""
        rv = self._removeAll(self._reads, self._writes)
        return rv


    def getReaders(self):
        return self._reads.keys()


    def getWriters(self):
        return self._writes.keys()


    def callLater(self,howlong, *args, **kargs):
        rval = super(QtReactor,self).callLater(howlong, *args, **kargs)
        self.reactorInvocation()
        return rval


    def reactorInvocation(self):
        self._timer.stop()
        self._timer.setInterval(0)
        self._timer.start()
        

    def _iterate(self, delay=None, fromqt=False):
        """See twisted.internet.interfaces.IReactorCore.iterate.
"""
        self.runUntilCurrent()
        self.doIteration(delay, fromqt)

    iterate = _iterate

    def doIteration(self, delay=None, fromqt=False):
        'This method is called by a Qt timer or by network activity on a file descriptor'
        
        if not self.running and self._blockApp:
            self._blockApp.quit()
        self._timer.stop()
        delay = max(delay, 1)
        if not fromqt:
            self.qApp.processEvents(QEventLoop.AllEvents, delay * 1000)
        if self.timeout() is None:
            timeout = 0.1
        elif self.timeout() == 0:
            timeout = 0
        else:
            timeout = self.timeout()
        self._timer.setInterval(timeout * 1000)
        self._timer.start()


    def runReturn(self, installSignalHandlers=True):
        self.startRunning(installSignalHandlers=installSignalHandlers)
        self.reactorInvocation()


    def run(self, installSignalHandlers=True):
        if self._ownApp:
            self._blockApp = self.qApp
        else:
            self._blockApp = QEventLoop()
        self.runReturn()
        self._blockApp.exec_()
Пример #45
0
class Fight(QObject):
    def __init__(self, mw):
        super().__init__()

        self._mw = mw

        # Кнопка "Отнять у слабого"
        self._css_path_button_fight = "div[class='button-big btn f1']"

        # Кнопка поедания Сникерса
        self._css_path_button_snikers = 'div[onclick*=snikers]'

        # Кнопка использования Тонуса
        self._css_path_button_use_tonus = 'div[onclick*=tonus]'

        # Таймер для ожидания загрузки страницы с выбором противника
        self._timer_enemy_load = QTimer()
        self._timer_enemy_load.setInterval(333)
        self._timer_enemy_load.timeout.connect(self._check_enemy_load)

        # Таймер для поиска противника
        self._timer_next_enemy = QTimer()
        self._timer_next_enemy.setInterval(1000)
        self._timer_next_enemy.setSingleShot(True)
        self._timer_next_enemy.timeout.connect(self._next_enemy)

        # Информация о противнике: имя, уровень, url
        self.enemy_name = None
        self.enemy_level = None
        self.enemy_url = None

        # Выигрыш / проигрыш. Если проигрыш, self.is_winner будет равен False
        self.received_money = None

        # True если победили мы, False если противник и None если ничья
        self.is_winner = None

        # Минимальная разница в уровне с противником. Эта величина вычитается из текущего уровня персонажа.
        self.min_diff_levels = 0

        # Максимальная разница в уровне с противником. Эта величина добавляется к текущему уровню персонажа.
        # Нельзя нападать на противника, у которого уровень больше трех от нашего
        self.max_diff_levels = 3

    # Сигнал вызывается, когда противник на странице найден -- например, страница загрузилась
    _enemy_load_finished = Signal()

    # Сигнал вызывается, когда противник подходит для нападения
    _enemy_found = Signal()

    def is_ready(self):
        """Возвращает True, если вызов метода run будет иметь смысл -- можем напасть, иначе False."""

        try:
            # TODO: для того, чтобы метод self.fight.is_ready() работал правильно, текущим адресом должны
            # быть Закоулки -- метод has_snikers, используемый в is_ready работает только в Закоулках
            # Идем в Закоулки
            self._mw.alley()

            # TODO: рефакторинг с self._timeout_fight()
            if self._timeout_fight() is not None:
                logger.info('Напасть можно будет через %s секунд.', self._timeout_fight())

            logger.info('self._timeout_fight() = %s.', self._timeout_fight())
            logger.info('self.has_snickers() = %s.', self.has_snickers())
            logger.info('self.is_ready() = %s.', self._timeout_fight() is None or self.has_snickers())

            # True, если таймер закончился или есть Сникерс
            return self._timeout_fight() is None or self.has_snickers()

        except MoswarClosedError:
            raise

        except Exception as e:
            raise MoswarBotError(e)

        return False

    def _timeout_fight(self):
        """Функция возвращает количество оставшихся секунд до возможности напасть.
        Если секунд осталось 0 или меньше 0, то вернется None."""

        for timeout in self._mw.doc.findAll('[id*=timeout]'):
            timer = timeout.attribute('timer')
            if timer and 'alley' in timeout.attribute('href'):
                timer = int(timer)
                return timer if timer > 0 else None

    def run(self):
        """Функция для нападения на игроков.

        Ищем слабого горожанина (заброшенного персонажа) -- не нужно привлекать внимание к боту.
        Уровень противника в пределах нашего +/- 1
        """

        try:
            if self._mw._used:
                logger.warn('Бот в данный момент занят процессом "%s". Выхожу из функции.', self._mw._used_process)
                return

            self._mw._used_process = "Нападение на игроков"
            logger.debug('Выполняю задание "%s".', self._mw._used_process)

            self._mw.alley()

            # TODO: оптимиизровать использование сникерсов -- если они есть, сразу использовать и нападать и так,
            # пока не будут потрачены все

            if not self.is_ready():
                logger.debug('Нападать еще нельзя.')
                return

            self._mw._used = True

            # TODO: если есть тонус, использовать, чтобы сразу напасть
            # TODO: флаг на разрешение использования тонуса, чтобы сразу напасть
            # self.use_tonus()

            # Если не получилось съесть Сникерс, восстанавливаем по старинке
            if not self.eat_snickers():
                if self._mw.current_hp() < self._mw.max_hp():
                    self._mw.restore_hp.run()

            logger.debug('Нажимаю на кнопку "Отнять у слабого".')
            # TODO: в одном из запусков дальше этой строки, похоже дело не пошло, возможно, страница с кнопкой
            # не прогрузилась

            # Кликаем на кнопку "Отнять у слабого"
            self._mw.click_tag(self._css_path_button_fight)

            # Если не нашли подходящего противника, смотрим следующего
            if not self._check_enemy():
                self._timer_next_enemy.start()

                # Ожидаем пока противник не будет найден
                loop = QEventLoop()
                self._enemy_found.connect(loop.quit)
                loop.exec_()

            logger.debug('Нападаем на "%s" [%s]: %s.', self.enemy_name, self.enemy_level, self.enemy_url)

            # Кликаем на кнопку "Напасть"
            self._mw.click_tag('.button-fight a')

            # Перемотка битвы
            forward = '#controls-forward'

            # Ждем пока после клика прогрузится страница и появится элемент
            Waitable(self._mw).wait(forward)

            # Перематываем бой
            self._mw.click_tag(forward)

            # Обрабатываем результаты боя
            self.handle_results()

        except MoswarClosedError:
            raise

        except Exception as e:
            raise MoswarBotError(e)

        finally:
            self._mw._used = False

    def name_winner(self):
        """Функция возвращает имя победителя в драке."""

        try:
            name = self._mw.doc.findFirst('.result div').toPlainText()
            name = name.replace('Победитель:', '')
            name = name[:name.rindex('[')]
            return name.strip()
        except Exception as e:
            raise MoswarElementIsMissError(e)

    def handle_results(self):
        """Обработка результата боя."""

        result = '.result'

        # Ждем пока после клика прогрузится страница и появится элемент
        Waitable(self._mw).wait(result)

        # Найдем элемент, в котором будут все результаты боя
        result = self._mw.doc.findFirst(result)

        if 'Ничья!' in result.toPlainText():
            self.is_winner = None
            self.received_money = 0
            logger.debug('Результат боя: Ничья.')
            return

        # Проверим по именам кто победил
        self.is_winner = self._mw.name() == self.name_winner()

        tugriki = result.findFirst('.tugriki').toPlainText().replace(',', '')
        tugriki = int(tugriki)
        self.received_money = tugriki

        # Сначала покажем выигранные монет и опыт, потом все остальное. Список используется для того, чтобы
        # порядок вывода результата боя был в порядке добавления элементов в этот список
        result_item_keys = ['Монеты', 'Опыт']

        result_dict = {
            'Монеты': tugriki,
            'Опыт': result.findFirst('.expa').toPlainText(),
        }

        neft = result.findFirst('.neft')
        if not neft.isNull():
            result_item_keys.append('Нефть')
            result_dict['Нефть'] = int(neft.toPlainText())

        # Искры не всегда будут -- обычно перед праздниками они появляются
        sparkles = result.findFirst('.sparkles')
        if not sparkles.isNull():
            result_item_keys.append('Искры')
            result_dict['Искры'] = sparkles.toPlainText()

        for img in result.findAll('.object-thumb'):
            obj = img.findFirst('img').attribute('alt')
            count = img.findFirst('.count').toPlainText()

            result_dict[obj] = count
            result_item_keys.append(obj)

        result_list = list()
        for key in result_item_keys:
            result_list.append('  {}: {}'.format(key, result_dict[key]))

        result_str = 'Результат боя:'
        if not self.is_winner:
            result_str += ' Бой проигран. Вся награда достается противнику.'

        result_str += '\n'
        result_str += '\n'.join(result_list)

        logger.debug(result_str)

    # TODO: работает только в Закоулках
    def has_tonus(self):
        """Функция возвратит True, если можно использовать Тонус для сброса таймера, иначе False."""

        button = self._mw.doc.findFirst(self._css_path_button_use_tonus)
        return not button.isNull()

    def use_tonus(self):
        """Функция для использования Тонуса, для сброса таймаута между драками.
        Возвращает True, если получилось, иначе False."""

        if self.has_tonus():
            logger.debug('Использую Тонус.')
            self._mw.click_tag(self._css_path_button_use_tonus)

            # TODO: если Тонуса будет не хватать, то появится окошко с предложением восстановить за плату

            # Ждем пока после клика прогрузится страница и появится элемент
            Waitable(self._mw).wait(self._css_path_button_use_tonus)
            return True

        return False

    # TODO: работает только в Закоулках
    def has_snickers(self):
        """Функция возвратит True, если можно съесть Сникерс, иначе False."""

        button = self._mw.doc.findFirst(self._css_path_button_snikers)
        return not button.isNull()

    def eat_snickers(self):
        """Функция для съедания Сникерса. Возвращает True, если получилось съесть, иначе False."""

        if self.has_snickers():
            logger.debug('Съедаю сникерс.')
            self._mw.click_tag(self._css_path_button_snikers)

            # Ждем пока после клика прогрузится страница и появится элемент
            Waitable(self._mw).wait(self._css_path_button_fight)
            return True

        return False

    def _check_enemy_load(self):
        """Функция для ожидания загрузки страницы с выбором противника."""

        enemy = self._mw.doc.findFirst('.fighter2')

        # Если нашли элемент, описывающий противника
        if not enemy.isNull():
            self._enemy_load_finished.emit()
            self._timer_enemy_load.stop()

    def _check_enemy(self):
        """Функция ищет противника на текущей странице и проверяет его тип и уровень.
        Возвращает True если нашелся подходящий противник, иначе False.

        """

        self._timer_enemy_load.start()

        loop = QEventLoop()
        self._enemy_load_finished.connect(loop.quit)
        loop.exec_()

        enemy = self._mw.doc.findFirst('.fighter2')

        # Определим тип противника -- нам нужен горожанин (нпс)
        is_npc = enemy.findFirst('.npc')
        is_npc = not is_npc.isNull()

        # Узнаем уровень противника
        level = enemy.findFirst('.level')
        level = level.toPlainText()
        level = level.replace('[', '').replace(']', '')
        level = int(level)

        # Гиперссылка на профиль противника
        a = enemy.findFirst('a')

        # Имя противника
        name = a.toPlainText()

        # Адрес противника
        url = urljoin(self._mw.moswar_url, a.attribute('href'))

        my_level = self._mw.level()

        # TODO: добавить ограничение на количество попыток найти гражданина, перед тем как напасть на игрока

        # Проверяем, что уровень противника находится в пределе диапазона
        check_level = my_level - self.min_diff_levels <= level <= my_level + self.max_diff_levels

        found = is_npc and check_level
        if found:
            self.enemy_name = name
            self.enemy_level = level
            self.enemy_url = url

        return found

    def _next_enemy(self):
        """Функция для поиска следующего противника."""

        logger.debug('Ищем следующего противника.')

        # Кликаем на кнопку "Искать другого"
        self._mw.click_tag(".button-search a")

        # Если нашли противника
        if self._check_enemy():
            self._enemy_found.emit()
            self._timer_next_enemy.stop()
        else:
            # Ищем дальше
            self._timer_next_enemy.start()
Пример #46
0
class OverviewModel(QAbstractItemModel):
    def __init__(self, db, parent=None):
        """Creates a new instance of OverviewModel.
        The OverviewModel is used to display all trains for the selected
        travel connection."""
        super(OverviewModel, self).__init__(parent)
        self._db = db
        self._columnHeaders = [
                self.tr("From"),
                self.tr("To"),
                self.tr("Date"),
                self.tr("Departure"),
                self.tr("Product"),
                self.tr("Delay"),
                self.tr("Comment")]
        self._rescanTimer = QTimer(self)
        self._rescanTimer.setInterval(10000)
        self._rescanTimer.timeout.connect(self._rescan)
        self._rescanTimer.start()
        self._trains = []
        self._trainFilter = None
        self._rescan()

    def _rescan(self):
        """Scans the database for changes and rebuilds the model."""
        t = self._db.getTrainsFiltered(self._trainFilter)
        self._trains = []
        for x in t:
            self._trains.append(x)
        self.reset()

    def setFilter(self, f):
        """Sets the TrainFilter to be used."""
        self._trainFilter = f
        f.filterChanged.connect(self._rescan)

    def rowCount(self, parent=QModelIndex()):
        """Returns the row count."""
        return len(self._trains)

    def columnCount(self, parent=QModelIndex()):
        """Returns the column count."""
        return len(self._columnHeaders)

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        """Returns the header data for the given column."""
        if role == Qt.DisplayRole and section >= 0\
                and section < self.columnCount():
            return self._columnHeaders[section]
        return None

    def data(self, index, role=Qt.DisplayRole):
        """Returns the data stored under the tgiven role for the item
        referred by the index."""
        if (not role == Qt.DisplayRole and not role == Qt.DecorationRole)\
                or not index.isValid():
            return None

        c = index.column()
        train = self._trains[index.row()]
        if role == Qt.DisplayRole:
            if c == 0:
                return train.start()
            if c == 1:
                return train.end()
            if c == 2:
                return train.date()
            elif c == 3:
                return train.departure()
            elif c == 4:
                return train.product()
            elif c == 5:
                return train.delay() if not train.delay() is None else\
                        self.tr("On Time")
            elif c == 6:
                return train.comment()
        else:
            if c == 5 and not train.delay() is None:
                return QColor(255, 0, 0)
        return None

    def index(self, row, column, parent=QModelIndex()):
        """Creates a new index based on given row and column"""
        if column >= 0 and column < self.columnCount():
            return self.createIndex(row, column, None)
        return QModelIndex()

    def parent(self, index):
        """Always returns QModelIndex() because there is no parent/child
        relationship."""
        return QModelIndex()

    def getTrains(self):
        """Gets all trains that match the current filter."""
        return self._db.getTrainsFiltered(self._trainFilter)

    def getTrainsAsList(self):
        """Returns all trains for the current connection as a list."""
        l = []
        for t in self.getTrains():
            l.append(t)
        return l
Пример #47
0
class WalletController(QObject):
    onError = Signal(unicode)
    onConnected = Signal(bool)
    onTxSent = Signal(bool)
    onBusy = Signal()
    onDoubleEncrypted = Signal()
    onBalance = Signal()
    onWalletUnlocked = Signal()
    onCurrentBalance = Signal()
    onCurrentLabel = Signal()
    onCurrentAddress = Signal()
    onCurrentDoubleEncrypted = Signal()
    onCurrentPassKey = Signal()

    def __init__(self,):
        QObject.__init__(self,)
        self.thread = None
        self._balance = '<b>0.00</b>000000'
        self._wallet = Wallet()
        self._walletUnlocked = False
        self.settings = Settings()
        self.addressesModel = AddressesModel()
        self.transactionsModel = TransactionsModel()
        self.timer = QTimer(self)
        self.timer.setInterval(900000)  # 15 min update
        self.timer.timeout.connect(self.update)
        self.timer.start()

        if self.settings.storePassKey:
            self._currentPassKey = self.settings.passKey
            try:
                self.unlockWallet(self._currentPassKey)
            except:
                self.onError.emit('Stored pass phrase is invalid')
        else:
            self._currentPassKey = None
        self._currentAddressIndex = 0

    @Slot()
    def newAddr(self):
        self._wallet.createAddr()
        self.storeWallet()
        self.update()

    @Slot(result=bool)
    def walletExists(self,):
        if not os.path.exists(os.path.join(
                os.path.expanduser('~'),
                '.bitpurse.wallet')):
            return False
        return True

    @Slot(unicode)
    def createWallet(self, passKey):
        self._currentPassKey = passKey
        self._walletUnlocked = True
        self._wallet.createAddr()
        self._wallet.store(passKey)
        self.update()

    def storeWallet(self):
        self._wallet.store(self._currentPassKey)
        self.addressesModel.setData(self._wallet.getActiveAddresses())

    def getCurrentPassKey(self):
        return self._currentPassKey

    def setCurrentPassKey(self, value):
        self._currentPassKey = value
        self.settings.currentPassKey = value
        self.onCurrentPassKey.emit()

    def getCurrentBalance(self):
        try:
            return prettyPBitcoin(self._wallet.addresses[
                self._currentAddressIndex].balance)
        except IndexError:
            return prettyPBitcoin(0)

    def getCurrentLabel(self):
        try:
            return self._wallet.addresses[
                self._currentAddressIndex].label
        except IndexError:
            return ''

    def getCurrentAddress(self):
        try:
            return self._wallet.addresses[
                self._currentAddressIndex].addr
        except IndexError:
            return ''

    def getCurrentDoubleEncrypted(self):
        try:
            return self._wallet.addresses[self._currentAddressIndex] \
                .doubleEncrypted
        except IndexError:
            return False

    @Slot()
    def exportWithShareUI(self):
        import dbus
        import urllib
	import shutil
	shutil.copyfile(os.path.join(os.path.expanduser('~'),
                        '.bitpurse.wallet'),
			os.path.join(os.path.expanduser('~'),
			'MyDocs',                        
			'bitpurse.wallet'))
        bus = dbus.SessionBus()        
        shareService = bus.get_object('com.nokia.ShareUi', '/')        
        share = shareService.get_dbus_method('share', 'com.nokia.maemo.meegotouch.ShareUiInterface')
        description = urllib.quote('BitPurse Wallet')
        title = urllib.quote('BitPurse Wallet')
        link = os.path.join(os.path.expanduser('~'),
	       'MyDocs',                        
	       'bitpurse.wallet')
        item = '%s'%link
        share([item,])

    @Slot(unicode, unicode, unicode)
    def importFromBlockchainInfoWallet(self, guid, key, skey):
        if self.thread:
            if self.thread.isAlive():
                self.onError.emit(
                    u'Please wait, a communication is already in progress')
        self.thread = threading.Thread(None,
                                       self._importFromBlockchainInfoWallet,
                                       None, (guid, key, skey))
        self.thread.start()

    @Slot(unicode, unicode, unicode)
    def importFromPrivateKey(self, privateKey,
                             label='Undefined', doubleKey=''):
        try:
            self._wallet.importFromPrivateKey(self._currentPassKey,
                                              privateKey,
                                              label,
                                              doubleKey)
            self.storeWallet()
            self.onError.emit('Key imported')
            self.update()
        except Exception, err:
            print err
            import traceback
            traceback.print_exc()
            self.onError.emit(unicode(err))
Пример #48
0
class Sync(QObject):
    
    deleteServerFile = Signal((str,))
    deleteLocalFile = Signal((str,))
    downloadFile = Signal((str,))
    uploadFile = Signal((str,))
    checkServer = Signal()
    checkLocal = Signal()
    statusChanged = Signal((str,))

    def __init__(self, host, ssl, parent=None):
        super(Sync, self).__init__(parent)

        self.server = ServerWatcher(host, ssl, self)
        
        self.preloaedActions = []
        self.doPreemptive = empty_db()
        self.connected = False
        self.firstScan = True
        
    def setLocalDir(self, localdir):
        if not os.path.exists(localdir):
            # Creates the directory if it doesn't already exists.
            os.makedirs(localdir)
        self.local = LocalWatcher(localdir)
        self.server.setLocalDir(localdir)

        self.local.moveToThread(self.thread())
        self.local.setParent(self)
    
    def connections(self):
        if not self.connected:
            self.connected = True
            self.server.fileAdded.connect(self.onAdded)
            self.server.fileChanged.connect(self.onChanged)
            self.server.fileDeleted.connect(self.onDeleted)

            self.local.fileAdded.connect(self.onAdded)
            self.local.fileChanged.connect(self.onChanged)
            self.local.fileDeleted.connect(self.onDeleted)

            self.deleteLocalFile.connect(self.local.deleteFile)
            self.deleteServerFile.connect(self.server.onDelete)
            self.downloadFile.connect(self.server.onDownload)
            self.uploadFile.connect(self.server.onUpload)

    @Slot()
    def initQueue(self):
        self.actionQueue = ActionQueue()
        
        self.actionTimer = QTimer()
        self.actionTimer.setInterval(1)
        self.actionTimer.timeout.connect(self.takeAction)
        
        self.actionTimer.start()
    
    @Slot()
    def takeAction(self):
        self.actionTimer.stop()

        if self.doPreemptive:
            # Preemptive check is a bit of a workaround to deal with
            # initial unexpected conditions: database file is gone
            self.doPreemptive = False
            self.server.preemptiveCheck = True
            self.local.fileAdded.connect(self.server.added)
            self.local.checkout()
            self.server.checkout()
            self.local.fileAdded.disconnect(self.server.added)
            self.server.preemptiveCheck = False
            for action in self.server.preemptiveActions:
                self.actionQueue.add(action)
        
        # After preemptive check, it is safe to do the connections
        # for normal operations
        self.connections()

        serverActionCount = 0
        localActionCount = 0
        for action in self.actionQueue:
            if action is not None:
                print 'Next action: %s' % action 
                path = action.path
                do = action.action
                location = action.location
                
                if location == FileAction.LOCAL and (do == FileAction.UPLOAD \
                   or do == FileAction.DELETE):
                    if not engine_tools.file_exists_local(path):
                        # File no longer exists at the time of processing.
                        # Maybe it was temporary or a quick rename.
                        # So we ignore it
                        print "Ignored action on " + path + ": File doesn't exist on local."
                        continue
                    
                
                if do == FileAction.UPLOAD:
                    self.uploadFile.emit(path)
                    localActionCount += 1
                elif do == FileAction.DOWNLOAD:
                    self.downloadFile.emit(path)
                    serverActionCount += 1
                elif do == FileAction.DELETE:
                    with File.fromPath(path) as deleted_file:
                        # `action.location` attribute only makes sense when deciding
                        # whether to delete a file on the server or local.
                        if location == FileAction.LOCAL:
                            localpath = self.local.localFromServer(path)
                            self.deleteLocalFile.emit(localpath)
                            deleted_file.inlocal = False
                            localActionCount += 1

                        elif location == FileAction.SERVER:
                            self.deleteServerFile.emit(path)
                            deleted_file.inserver = False
                            serverActionCount += 1
        
        self.actionQueue.clear()
        
        # Scan server for file changes
        self.statusChanged.emit('Scanning remote files for changes')
        self.server.checkout()
        
        if self.firstScan:
            # First do a full scan to check for offline changes.
            # From there we will rely on real time notifications watchdog.
            self.firstScan = False
            self.statusChanged.emit('Scanning local files for changes')
            self.local.checkout()
            self.local.startObserver()
            # Si Added
            # Since its the first scan, we should also
            # set the timer interval
            self.actionTimer.setInterval(5000)        
        self.cleanSync()

        # Si Added
        # Set check interval intelligently.
        # If there's no activity there, wait longer.
        # Since if there's just no usage, then
        # no reason to take up CPU cycles.
        tempInterval = 0
        if serverActionCount+localActionCount > 0:
            tempInterval = 5000
        else:
            tempInterval = 1000 * 10
        
        self.actionTimer.start()
            
    @Slot()
    def cleanSync(self):
        """
        Removes entries from the database for deleted files
        """
        
        session = Session()
        session.query(File).filter(File.inserver == False).filter(File.inlocal == False).delete(synchronize_session=False)
        session.commit()
        self.statusChanged.emit('Sync completed. Waiting for changes')

    @Slot(str, str, bool)
    def onChanged(self, location, serverpath, skipDeltaCheck):
        changed_file = File.fromPath(serverpath)
        action = None
        
        #if not changed_file.servermdate:
            # Probably a local added event that also
            # spawned a modified event.
            #return

        file_name_only = os.path.basename(serverpath)
        if engine_tools.isTemporaryFile(file_name_only):
            print 'File ' + serverpath + ' ignored since it is a temporary file'
            return
           
        print 'File ' + serverpath + ':'
        
        if changed_file.servermdate == None:
            mydiff = "** File Not in Server **"
            edit_time = "(not in server)"
        else:
            ttt = (changed_file.localmdate - changed_file.servermdate).total_seconds() 
            mydiff = str( ttt )
            edit_time = str(changed_file.servermdate)
        
        print 'Changed here %s, there %s delta %s' % (
                    changed_file.localmdate, edit_time, mydiff)
                    
        
        try:
            if changed_file.inserver:
                diff = changed_file.timeDiff()

                MY_TOLERANCE = 10
            
                if skipDeltaCheck == False and abs(diff) < MY_TOLERANCE:
                    return
            
            if location == FileAction.SERVER:
                if changed_file.inlocal:
                    if changed_file.localmdate < changed_file.servermdate:
                        action = FileAction(serverpath, FileAction.DOWNLOAD, FileAction.LOCAL)
                else:
                    action = FileAction(serverpath, FileAction.DOWNLOAD, FileAction.LOCAL)
           
            elif location == FileAction.LOCAL:
                if changed_file.inserver:
                    try:
                        if changed_file.servermdate < changed_file.localmdate:
                            action = FileAction(serverpath, FileAction.UPLOAD, FileAction.SERVER)
                    except:
                        print 'Error:', changed_file, changed_file.servermdate, changed_file.localmdate
                        
                else:
                    action = FileAction(serverpath, FileAction.UPLOAD, FileAction.SERVER)
                
            if action is not None:
                self.actionQueue.add(action)
        except:
            info = traceback.format_exception(*sys.exc_info())
            for i in info: sys.stderr.write(i)
            
    
    @Slot(str, str)
    def onAdded(self, location, serverpath):

        file_name_only = os.path.basename(serverpath)
        if engine_tools.isTemporaryFile(file_name_only):
            print 'File ' + serverpath + ' was created but ignored since it is a temporary file'
            return
        
        added_file = File.fromPath(serverpath)
        action = None
        
        if location == FileAction.SERVER and not added_file.inlocal:
            action = FileAction(serverpath, FileAction.DOWNLOAD, FileAction.LOCAL)
        elif location == FileAction.LOCAL and not added_file.inserver:
            action = FileAction(serverpath, FileAction.UPLOAD, FileAction.SERVER)
            
        if action is not None:
            self.actionQueue.add(action)
        
    @Slot(str, str)
    def onDeleted(self, location, serverpath):

        # NOTE: For temporary files, the current action is to delete it.
        # Reason 1: We need to remove it from the database.
        # Reason 2: If somehow there is a temporary file 
        # there on the other side, then it makes sense to delete it.
        
        deleted_file = File.fromPath(serverpath)
        action = None
        
        if location == FileAction.SERVER:
            if deleted_file.inlocal:
                action = FileAction(serverpath, FileAction.DELETE, FileAction.LOCAL)
        elif location == FileAction.LOCAL:
            if deleted_file.inserver:
                action = FileAction(serverpath, FileAction.DELETE, FileAction.SERVER)
        
        if action is not None:
            self.actionQueue.add(action)
Пример #49
0
class WalletController(QObject):
    onError = Signal(unicode)
    onConnected = Signal(bool)
    onTxSent = Signal(bool)
    onBusy = Signal()
    onDoubleEncrypted = Signal()
    onBalance = Signal()
    onFiatBalance = Signal()
    onWalletUnlocked = Signal()
    onCurrentBalance = Signal()
    onCurrentFiatBalance = Signal()
    onCurrentLabel = Signal()
    onCurrentAddress = Signal()
    onCurrentDoubleEncrypted = Signal()
    onCurrentPassKey = Signal()
    onCurrentWatchOnly = Signal()

    def __init__(self,):
        QObject.__init__(self,)
        self.thread = None
        self._balance = '<b>0.00</b>000000'
        self._fiatSymbol = u'€'
        self._fiatRate = 0
        self._fiatBalance = u'0 €'
        self._wallet = Wallet()
        self._wallet.onNewTransaction.connect(self.notifyNewTx)
        self._walletUnlocked = False
        self.settings = Settings()
        self.addressesModel = AddressesModel()
        self.transactionsModel = TransactionsModel()
        self.timer = QTimer(self)
        self.timer.setInterval(900000)  # 15 min update
        self.timer.timeout.connect(self.update)
        self.timer.start()

        if self.settings.storePassKey:
            self._currentPassKey = self.settings.passKey
            try:
                self.unlockWallet(self._currentPassKey)
            except:
                self.onError.emit('Stored pass phrase is invalid')
        else:
            self._currentPassKey = None
        self._currentAddressIndex = 0

    def on_event_data_received(self,*args):
        print 'BitPurse received DATA:', args
    
    
#    def notifyCallback(self):
#        print 'ohai! received something :)'
#        self.service.remove_items()
        
    def notifyNewTx(self, address, datas, amount):
        from eventfeed import EventFeedService, EventFeedItem
        service = EventFeedService('BitPurse',
                                   'BitPurse',
                                   self.on_event_data_received)
        item = EventFeedItem('/usr/share/icons/hicolor/80x80/apps/bitpurse.png',
                             'BitPurse')
        item.set_body('New transaction on address %s : %f BTC'
                      % (address, amount / float(10**8)))
        #item.set_custom_action(self.notifyCallback)
        service.add_item(item)
        
    @Slot(unicode)
    def newAddr(self, doubleKey):
        try:
            self._wallet.createAddr(doubleKey)
            self.storeWallet()
            self.update()
        except (WrongPassword, DataError), err:
            self.onError.emit(unicode(err))
Пример #50
0
 def resizeTimer(self):
     ret = QTimer(self.q)
     ret.setSingleShot(True)
     ret.setInterval(200)
     ret.timeout.connect(self.updateSize)
     return ret
Пример #51
0
        self.windowTitle()  # generate exception


app = QApplication([])
app.setQuitOnLastWindowClosed(False)

lineEdit = LineEdit()
lineEdit.deleteLater()


if USE_SINGLESHOT:
    #QTimer.singleShot(1000, lineEdit.clear)
    #QTimer.singleShot(1000, lineEdit.purePythonMethod)
    QTimer.singleShot(1000, lineEdit.selectAll)  # pure C++ method
else:
    timer = QTimer(None)
    timer.setSingleShot(True)
    timer.setInterval(1000)
    timer.start()

    #timer.timeout.connect(lineEdit.clear)
    #timer.timeout.connect(lineEdit.purePythonMethod)
    timer.timeout.connect(lineEdit.selectAll)  # pure C++ method


QTimer.singleShot(2000, app.quit)

app.exec_()

print('~~~~ Application exited')
Пример #52
0
    class PlotMainWindow(QWidget):
        """Base class for plot main windows."""

        def __init__(self, U, plot, length=1, title=None):
            super(PlotMainWindow, self).__init__()

            layout = QVBoxLayout()

            if title:
                title = QLabel('<b>' + title + '</b>')
                title.setAlignment(Qt.AlignHCenter)
                layout.addWidget(title)
            layout.addWidget(plot)

            plot.set(U, 0)

            if length > 1:
                hlayout = QHBoxLayout()

                self.slider = QSlider(Qt.Horizontal)
                self.slider.setMinimum(0)
                self.slider.setMaximum(length - 1)
                self.slider.setTickPosition(QSlider.TicksBelow)
                hlayout.addWidget(self.slider)

                lcd = QLCDNumber(m.ceil(m.log10(length)))
                lcd.setDecMode()
                lcd.setSegmentStyle(QLCDNumber.Flat)
                hlayout.addWidget(lcd)

                layout.addLayout(hlayout)

                hlayout = QHBoxLayout()

                toolbar = QToolBar()
                self.a_play = QAction(self.style().standardIcon(QStyle.SP_MediaPlay), 'Play', self)
                self.a_play.setCheckable(True)
                self.a_rewind = QAction(self.style().standardIcon(QStyle.SP_MediaSeekBackward), 'Rewind', self)
                self.a_toend = QAction(self.style().standardIcon(QStyle.SP_MediaSeekForward), 'End', self)
                self.a_step_backward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipBackward),
                                               'Step Back', self)
                self.a_step_forward = QAction(self.style().standardIcon(QStyle.SP_MediaSkipForward), 'Step', self)
                self.a_loop = QAction(self.style().standardIcon(QStyle.SP_BrowserReload), 'Loop', self)
                self.a_loop.setCheckable(True)
                toolbar.addAction(self.a_play)
                toolbar.addAction(self.a_rewind)
                toolbar.addAction(self.a_toend)
                toolbar.addAction(self.a_step_backward)
                toolbar.addAction(self.a_step_forward)
                toolbar.addAction(self.a_loop)
                if hasattr(self, 'save'):
                    self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self)
                    toolbar.addAction(self.a_save)
                    self.a_save.triggered.connect(self.save)
                hlayout.addWidget(toolbar)

                self.speed = QSlider(Qt.Horizontal)
                self.speed.setMinimum(0)
                self.speed.setMaximum(100)
                hlayout.addWidget(QLabel('Speed:'))
                hlayout.addWidget(self.speed)

                layout.addLayout(hlayout)

                self.timer = QTimer()
                self.timer.timeout.connect(self.update_solution)

                self.slider.valueChanged.connect(self.slider_changed)
                self.slider.valueChanged.connect(lcd.display)
                self.speed.valueChanged.connect(self.speed_changed)
                self.a_play.toggled.connect(self.toggle_play)
                self.a_rewind.triggered.connect(self.rewind)
                self.a_toend.triggered.connect(self.to_end)
                self.a_step_forward.triggered.connect(self.step_forward)
                self.a_step_backward.triggered.connect(self.step_backward)

                self.speed.setValue(50)

            elif hasattr(self, 'save'):
                hlayout = QHBoxLayout()
                toolbar = QToolBar()
                self.a_save = QAction(self.style().standardIcon(QStyle.SP_DialogSaveButton), 'Save', self)
                toolbar.addAction(self.a_save)
                hlayout.addWidget(toolbar)
                layout.addLayout(hlayout)
                self.a_save.triggered.connect(self.save)

            self.setLayout(layout)
            self.plot = plot
            self.U = U
            self.length = length

        def slider_changed(self, ind):
            self.plot.set(self.U, ind)

        def speed_changed(self, val):
            self.timer.setInterval(val * 20)

        def update_solution(self):
            ind = self.slider.value() + 1
            if ind >= self.length:
                if self.a_loop.isChecked():
                    ind = 0
                else:
                    self.a_play.setChecked(False)
                    return
            self.slider.setValue(ind)

        def toggle_play(self, checked):
            if checked:
                if self.slider.value() + 1 == self.length:
                    self.slider.setValue(0)
                self.timer.start()
            else:
                self.timer.stop()

        def rewind(self):
            self.slider.setValue(0)

        def to_end(self):
            self.a_play.setChecked(False)
            self.slider.setValue(self.length - 1)

        def step_forward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() + 1
            if ind == self.length and self.a_loop.isChecked():
                ind = 0
            if ind < self.length:
                self.slider.setValue(ind)

        def step_backward(self):
            self.a_play.setChecked(False)
            ind = self.slider.value() - 1
            if ind == -1 and self.a_loop.isChecked():
                ind = self.length - 1
            if ind >= 0:
                self.slider.setValue(ind)
Пример #53
0
class Loader(QMainWindow):
    def __init__(self, parent=None):
        super(Loader, self).__init__(parent)

        self.initUI()

    def updateDeviceList(self):
        self.statusBar().showMessage("Device list updating...",
                                     timeout=STATUS_BAR_TIMEOUT)
        self.deviceListWidget.updateList()
        self.statusBar().showMessage("Device list updated finished!",
                                     timeout=STATUS_BAR_TIMEOUT)

    def getFileName(self, ext):
        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')
        # if fname[0]:
        #     f = open(fname[0], 'r')

        #     with f:
        #         data = f.read()
        #         self.textEdit.setText(data)

    def initUI(self):

        # textEdit = QTextEdit()
        # self.setCentralWidget(textEdit)

        # self.setStyleSheet("QGroupBox {  border: 1px solid gray; padding: 5px;}");

        # Action to quit program
        exitAction = QAction(QIcon(None), 'Quit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        # # Action to update device list
        # self.refreshAction = QAction(QIcon('img/reload.png'), 'Refresh', self)
        # self.refreshAction.setShortcut('F5')
        # self.refreshAction.setStatusTip('Refresh list of connected devices.')
        # self.refreshAction.triggered.connect(self.updateDeviceList)

        # Action to show program information
        helpAction = QAction(QIcon(None), 'Help', self)
        helpAction.setShortcut('F1')
        helpAction.triggered.connect(self.showHelpDialog)

        # Action to help
        aboutAction = QAction(QIcon(None), 'About', self)
        aboutAction.triggered.connect(self.showAboutDialog)

        self.statusBar()

        # Add the file menu
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        # fileMenu.addAction(self.refreshAction)
        fileMenu.addAction(exitAction)
        fileMenu = menubar.addMenu('&Help')
        fileMenu.addAction(helpAction)
        fileMenu.addAction(aboutAction)

        # # Add the toolbar
        # toolbar = self.addToolBar('Exit')
        # # toolbar.addAction(self.refreshAction)
        # toolbar.setMovable(False)

        # Add the main windows widgets
        self.deviceListWidget = DeviceList(self.programDeviceHandler,
                                           self.infoDeviceHandler,
                                           self.resetDeviceHandler)
        self.fileSelectorWidget = FileSelector()

        self.setStyleSheet("""
            QStatusBar {
                border-top: 1px solid #CCC;
            }
            QToolBar {
                border-top: 1px solid #DDD;
                border-bottom: 1px solid #CCC;
            }
        """)

        gbox = QGroupBox("Connected USB devices:")
        gboxLayout = QVBoxLayout()
        gboxLayout.addWidget(self.deviceListWidget)
        gbox.setLayout(gboxLayout)

        self.refreshEvent = QTimer()
        self.refreshEvent.setInterval(1250)
        self.refreshEvent.timeout.connect(self.USBUpdate)
        self.refreshEvent.start()

        layout = QVBoxLayout()
        layout.addWidget(self.fileSelectorWidget)
        layout.addWidget(gbox)
        self.setCentralWidget(QWidget())
        self.centralWidget().setLayout(layout)

        self.setMinimumSize(620, 700)
        self.setMaximumWidth(620)
        self.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint
                            | Qt.WindowCloseButtonHint)

        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('keyplus layout and firmware loader')
        self.show()

    def process_layout(self, layout_json_obj, layout_file, device_id):
        try:
            settings_gen = layout.parser.SettingsGenerator(
                layout_json_obj, None)
            layout_data = settings_gen.gen_layout_section(device_id)
            settings_data = settings_gen.gen_settings_section(device_id)
            return layout_data, settings_data
        except (layout.parser.ParseError,
                layout.parser.ParseKeycodeError) as err:
            error_msg_box(str(err))
            self.statusBar().showMessage(
                'Error parsing "{}"'.format(layout_file),
                timeout=STATUS_BAR_TIMEOUT * 2)
            return None, None

    def abort_update(self, target_device):
        try:
            target_device.close()
        except:
            pass

        self.deviceListWidget.updateList()

    @Slot(str)
    def programDeviceHandler(self, device_path):
        target_device = self.tryOpenDevicePath(device_path)

        if target_device == None:
            self.abort_update(target_device)
            return

        programmingMode = self.fileSelectorWidget.getProgramingInfo()

        if is_bootloader_device(
                target_device
        ) and programmingMode != FileSelector.ScopeFirmware:
            error_msg_box(
                "Can only upload firmware while bootloader is running. "
                "Either reset it, or upload a firmware hex instead")
            self.abort_update(target_device)
            return

        if programmingMode == FileSelector.ScopeLayout:
            self.statusBar().showMessage("Started updating layout",
                                         timeout=STATUS_BAR_TIMEOUT)

            layout_file = self.fileSelectorWidget.getLayoutFile()

            if layout_file == '':
                error_msg_box("No layout file given.")
                self.abort_update(target_device)
                return
            else:
                pass

            layout_json_obj = None
            with open(layout_file) as file_obj:
                try:
                    layout_json_obj = yaml.safe_load(file_obj.read())
                except Exception as err:
                    error_msg_box("Syntax error in yaml file: " + str(err))
                    self.abort_update(target_device)
                    return

            device_info = protocol.get_device_info(target_device)
            layout_data, settings_data = self.process_layout(
                layout_json_obj, layout_file, device_info.id)
            if layout_data == None or settings_data == None:
                return

            protocol.update_layout_section(target_device, layout_data)
            protocol.update_settings_section(target_device,
                                             settings_data,
                                             keep_rf=True)
            protocol.reset_device(target_device)

            self.statusBar().showMessage("Finished updating layout",
                                         timeout=STATUS_BAR_TIMEOUT)
        elif programmingMode == FileSelector.ScopeDevice:
            layout_file = self.fileSelectorWidget.getRFLayoutFile()
            rf_file = self.fileSelectorWidget.getRFFile()
            target_id = self.fileSelectorWidget.getTargetID()

            self.statusBar().showMessage("Started updating RF settings",
                                         timeout=STATUS_BAR_TIMEOUT)

            if layout_file == '':
                error_msg_box("No layout file given.")
                self.abort_update(target_device)
                return
            elif rf_file == '':
                error_msg_box("No RF settings file given.")
                self.abort_update(target_device)
                return
            elif target_id == None:
                error_msg_box("No device id file given.")
                self.abort_update(target_device)
                return

            layout_json_obj = None
            rf_json_obj = None
            with open(layout_file) as file_obj:
                try:
                    layout_json_obj = yaml.safe_load(file_obj.read())
                except Exception as err:
                    error_msg_box("Syntax error in yaml file: " + str(err))
                    self.abort_update(target_device)
                    return
            with open(rf_file) as file_obj:
                try:
                    rf_json_obj = yaml.safe_load(file_obj.read())
                except Exception as err:
                    error_msg_box("Syntax error in yaml file: " + str(err))
                    self.abort_update(target_device)
                    return

            try:
                settings_gen = layout.parser.SettingsGenerator(
                    layout_json_obj, rf_json_obj)
            except ParseError as err:
                error_msg_box("Error Generating RF settings data: " + str(err))
                self.abort_update(target_device)
                return

            layout_data = settings_gen.gen_layout_section(target_id)
            settings_data = settings_gen.gen_settings_section(target_id)

            protocol.update_settings_section(target_device, settings_data)
            protocol.update_layout_section(target_device, layout_data)
            protocol.reset_device(target_device)

            self.statusBar().showMessage("Finished updating RF settings",
                                         timeout=STATUS_BAR_TIMEOUT)

        elif programmingMode == FileSelector.ScopeFirmware:
            fw_file = self.fileSelectorWidget.getFirmwareFile()

            self.statusBar().showMessage("Starting update firmware",
                                         timeout=STATUS_BAR_TIMEOUT)

            if fw_file == '':
                error_msg_box("No firmware file given.")
            else:

                if is_xusb_bootloader_device(target_device):
                    self.program_xusb_boot_firmware_hex(target_device, fw_file)
                elif is_keyplus_device(target_device):
                    try:
                        serial_num = target_device.serial_number
                        boot_vid, boot_pid = protocol.enter_bootloader(
                            target_device)

                        self.bootloaderProgramTimer = QTimer()
                        self.bootloaderProgramTimer.setInterval(3000)
                        self.bootloaderProgramTimer.setSingleShot(True)
                        self.bootloaderProgramTimer.timeout.connect(
                            lambda: self.programFirmwareHex(
                                boot_vid, boot_pid, serial_num, fw_file))
                        self.bootloaderProgramTimer.start()
                    except (easyhid.HIDException,
                            protocol.KBProtocolException):
                        error_msg_box(
                            "Programming hex file failed: '{}'".format(
                                fw_file))
        else:
            try:
                target_device.close()
            except:
                pass
            raise Exception("Unimplementend programming mode")

    def programFirmwareHex(self, boot_vid, boot_pid, serial_num, file_name):
        device = None

        for i in range(1):
            en = easyhid.Enumeration(vid=boot_vid, pid=boot_pid).find()

            # Look for devices with matching serial_num number
            for dev in en:
                if dev.serial_number == serial_num:
                    device = dev
                    break

            # if a device was found with matching vid:pid, but it doesn't have
            # a matching serial_num number, then assume that the bootloader/firmware
            # doesn't set the serial_num number to the same value, so just program
            # the first matching device
            if len(en) != 0:
                device = en[0]
                break

        if device == None:
            error_msg_box("Couldn't connect to the device's bootloader")
            return
        else:
            if self.tryOpenDevice(device): return

            self.program_xusb_boot_firmware_hex(device, file_name)
        self.statusBar().showMessage("Finished updating firmware",
                                     timeout=STATUS_BAR_TIMEOUT)

    def program_xusb_boot_firmware_hex(self, device, file_name):
        try:
            xusb_boot.write_hexfile(device, file_name)
        except xusb_boot.BootloaderException as err:
            error_msg_box("Error programming the bootloader to hex file: " +
                          str(err))
        finally:
            device.close()

    def tryOpenDevicePath(self, device_path):
        try:
            device = easyhid.Enumeration().find(path=device_path)[0]
            device.open()
            return device
        except:
            msg_box(
                description="Failed to open device! Check it is still present "
                "and you have permission to write to it.",
                title="USB Device write error")
            return None

    def tryOpenDevice(self, device):
        try:
            device.open()
            return False
        except:
            msg_box(
                description="Failed to open device! Check it is still present "
                "and you have permission to write to it.",
                title="USB Device write error")
            return True

    @Slot(str)
    def resetDeviceHandler(self, device_path):
        device = self.tryOpenDevicePath(device_path)
        if device == None: return

        if is_keyplus_device(device):
            protocol.reset_device(device)
        elif is_xusb_bootloader_device(device):
            xusb_boot.reset(device)
        elif is_nrf24lu1p_bootloader_device(device):
            print("TODO: reset: ", device_path, file=sys.stderr)
        else:
            print("Can't reset device: ", device_path, file=sys.stderr)

    @Slot(str)
    def infoDeviceHandler(self, device_path):
        device = self.tryOpenDevicePath(device_path)
        if device == None: return

        settingsInfo = protocol.get_device_info(device)
        firmwareInfo = protocol.get_firmware_info(device)
        rfInfo = protocol.get_rf_info(device)
        if firmwareInfo.has_at_least_version('0.2.2'):
            errorInfo = protocol.get_error_info(device)
        else:
            errorInfo = None
        device.close()

        header = ["Attribute", "Value"]
        device_settings = [
            ("Device ID", settingsInfo.id),
            ("Device name", settingsInfo.device_name_str()),
            ("Device serial number", device.serial_number),
            ("Last layout update", settingsInfo.timestamp_str()),
            ("Default report mode", settingsInfo.default_report_mode_str()),
            ("Matrix scan mode", settingsInfo.scan_mode_str()),
            ("Matrix columns", settingsInfo.col_count),
            ("Matrix rows", settingsInfo.row_count),
            ("Settings stored CRC", hex(settingsInfo.crc)),
            ("Settings computed CRC", hex(settingsInfo.computed_crc)),
            ("USB", not (settingsInfo.has_usb_disabled()
                         or not firmwareInfo.has_fw_support_usb())),
            ("I2C", not (settingsInfo.has_i2c_disabled()
                         or not firmwareInfo.has_fw_support_i2c())),
            ("nRF24 wireless",
             not (settingsInfo.has_nrf24_disabled()
                  or not firmwareInfo.has_fw_support_nrf24())),
            ("Unifying mouse",
             not (settingsInfo.has_unifying_mouse_disabled()
                  or not firmwareInfo.has_fw_support_unifying())),
            ("Bluetooth",
             not (settingsInfo.has_bluetooth_disabled()
                  or not firmwareInfo.has_fw_support_bluetooth())),
            ("RF pipe0", binascii.hexlify(rfInfo.pipe0).decode('ascii')),
            ("RF pipe1", binascii.hexlify(rfInfo.pipe1).decode('ascii')),
            ("RF pipe2", "{:02x}".format(rfInfo.pipe2)),
            ("RF pipe3", "{:02x}".format(rfInfo.pipe3)),
            ("RF pipe4", "{:02x}".format(rfInfo.pipe4)),
            ("RF pipe5", "{:02x}".format(rfInfo.pipe5)),
            ("RF channel", str(rfInfo.channel)),
            ("RF auto retransmit count", str(rfInfo.arc)),
            ("RF data rate", protocol.data_rate_to_str(rfInfo.data_rate)),
        ]

        firmware_settings = [
            ("Firmware version",
             "{}.{}.{}".format(firmwareInfo.version_major,
                               firmwareInfo.version_minor,
                               firmwareInfo.version_patch)),
            ("Firmware build date",
             str(datetime.datetime.fromtimestamp(firmwareInfo.timestamp))),
            ("Firmware git hash", "{:08x}".format(firmwareInfo.git_hash)),
            ("Layout storage size", firmwareInfo.layout_flash_size),
            ("Bootloader VID", "{:04x}".format(firmwareInfo.bootloader_vid)),
            ("Bootloader PID", "{:04x}".format(firmwareInfo.bootloader_pid)),
            ("Support scanning", firmwareInfo.has_fw_support_scanning()),
            ("Support scanning col to row",
             firmwareInfo.has_fw_support_scanning_col_row()),
            ("Support scanning row to col",
             firmwareInfo.has_fw_support_scanning_row_col()),
            ("Media keys", firmwareInfo.has_fw_support_key_media()),
            ("Mouse keys", firmwareInfo.has_fw_support_key_mouse()),
            ("Layer keys", firmwareInfo.has_fw_support_key_layers()),
            ("Sticky keys", firmwareInfo.has_fw_support_key_sticky()),
            ("Tap keys", firmwareInfo.has_fw_support_key_tap()),
            ("Hold keys", firmwareInfo.has_fw_support_key_hold()),
            ("Support 6KRO", firmwareInfo.has_fw_support_6kro()),
            ("Support NKRO", firmwareInfo.has_fw_support_key_hold()),
            ("Support indicator LEDs",
             firmwareInfo.has_fw_support_led_indicators()),
            ("Support LED backlighting",
             firmwareInfo.has_fw_support_led_backlighting()),
            ("Support ws2812 LEDs", firmwareInfo.has_fw_support_led_ws2812()),
            ("Support USB", firmwareInfo.has_fw_support_usb()),
            ("Support nRF24 wireless", firmwareInfo.has_fw_support_nrf24()),
            ("Support Unifying", firmwareInfo.has_fw_support_unifying()),
            ("Support I2C", firmwareInfo.has_fw_support_i2c()),
            ("Support Bluetooth", firmwareInfo.has_fw_support_bluetooth()),
        ]

        if errorInfo:
            error_codes = []
            for code in errorInfo.get_error_codes():
                error_codes.append((errorInfo.error_code_to_name(code), code))
        else:
            error_codes = [
                ('Error codes require firmware version 0.2.2 or greater', )
            ]

        self.info_window = DeviceInformationWindow(
            self,
            header,
            device_settings,
            firmware_settings,
            error_codes,
        )
        self.info_window.setModal(True)
        self.info_window.exec_()

        self.deviceListWidget.updateList()

    def USBUpdate(self):
        self.deviceListWidget.updateList()

    def showAboutDialog(self):
        QMessageBox.about(self, "About keyplus Loader", """
The keyplus layout and firmware loader.
""")

    def showHelpDialog(self):
        QMessageBox.about(
            self, "keyplus Loader Help", """
This is the layout and firmware loader for the keyplus keyboard firmware.

The layout files are *.yaml files. For documentation and examples see here: TODO

The rf files are *.yaml files. For documentation and examples see here: TODO

The firmware loader accepts *.hex files. For the latest keyplus firmware see here: TODO

""")
Пример #54
0
 def hoverTimer(self):
     ret = QTimer(self.q)
     ret.setInterval(400)
     ret.setSingleShot(False)
     ret.timeout.connect(self._hover)
     return ret
class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def starty(self):
        data = {
            'username': '******',
            'msg': 'Hi from Main Gui Thread',
            'random_number': 777,
            'thread_number': 1
        }

        # we convert the list into a string so the object is not connected in any way then mutate it over with ast
        downloader = SampleThread(str(data))
        downloader.data_send.connect(self.echo)

        self.thread_pool = QtCore.QThreadPool()
        self.thread_pool.setMaxThreadCount(1)
        self.thread_pool.start(downloader)

        self.timer = QTimer()
        self.timer.setInterval(10000)  #10 seconds
        self.timer.start()
        self.timer.timeout.connect(self.loop)  #call loop every 10 seconds

    def loop(self):
        #Do Gui updating stuff here such as displaying data
        print 'Main Gui Loop every 10 seconds'
        thread_count = str(self.thread_pool.activeThreadCount())
        self.console.addItem(thread_count)

    def initUI(self):
        '''Create GUI stuff here
        Random notes:
        QVBox = Vertical up/down
        QHBox = Horizonal left/right
        self.resize window height/width
        self.console this is our main widget to display data to the gui
        '''

        self.resize(550, 300)

        # QVBox = Vertical up/down
        layout = QtGui.QVBoxLayout()

        self.console = QtGui.QListWidget()
        layout.addWidget(self.console)
        self.console.addItem(
            "Very Basic Gui displaying thread usage using python 2.7/Pyside ")

        btn = QtGui.QPushButton('Button', self)
        btn.clicked.connect(self.starty)

        layout.addWidget(btn)

        self.setLayout(layout)

    def echo(self, payload):
        print 'hi from echo'
        texty = 'payload -> ' + str(payload)
        self.console.addItem(texty)
        self.console.scrollToBottom()  #scrolls down
Пример #56
0
class MapWidget(QGraphicsGeoMap):

    coordQueryResult = Signal(QGeoCoordinate)

    def __init__(self, manager):
        QGraphicsGeoMap.__init__(self, manager)

        self.coordQueryState = False
        self.panActive = False
        self.kineticTimer = QTimer()
        self.lastCircle = None
        self.lastMoveTime = None
        self.kineticPanSpeed = None
        self.panDecellerate = True
        self.remainingPan = QPointF()

        self.mouseHistory = deque([MouseHistoryEntry() for i in range(5)])

        self.kineticTimer.timeout.connect(self.kineticTimerEvent)
        self.kineticTimer.setInterval(KINETIC_PANNING_RESOLUTION)

    def setMouseClickCoordQuery(self, state):
        self.coordQueryState = state

    def mousePressEvent(self, event):
        self.setFocus()

        if event.button() == Qt.LeftButton:
            if event.modifiers() & Qt.ControlModifier:
                pass
            else:
                if self.coordQueryState:
                    self.coordQueryResult.emit(self.screenPositionToCoordinate(event.lastPos()))
                    return

                self.panActive = True

                self.kineticTimer.stop()
                self.kineticPanSpeed = QPointF()
                self.lastMoveTime = QTime.currentTime()

        event.accept()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            if self.panActive:
                self.panActive = False

                if not ENABLE_KINETIC_PANNING or self.lastMoveTime.msecsTo(QTime.currentTime()) > HOLD_TIME_THRESHOLD:
                    return

                self.kineticPanSpeed = QPointF()
                entriesConsidered = 0

                currentTime = QTime.currentTime()

                for entry in self.mouseHistory:
                    if not entry.time:
                        continue

                    if entry.time.msecsTo(currentTime) < HOLD_TIME_THRESHOLD:
                        self.kineticPanSpeed += entry.position
                        entriesConsidered += 1

                if entriesConsidered > 0:
                    self.kineticPanSpeed /= entriesConsidered

                self.lastMoveTime = currentTime

                self.kineticTimer.start()
                self.panDecellerate = True

        event.accept()

    def mouseMoveEvent(self, event):
        if event.modifiers() & Qt.ControlModifier:
            if self.lastCircle:
                self.lastCircle.setCenter(self.screenPositionToCoordinate(event.pos()))
        elif self.panActive:
            currentTime = QTime.currentTime()
            deltaTime = self.lastMoveTime.msecsTo(currentTime)

            delta = event.lastPos() - event.pos()

            if deltaTime > 0:
                self.kineticPanSpeed = delta / deltaTime

                self.mouseHistory.popleft()
                self.mouseHistory.append(MouseHistoryEntry(self.kineticPanSpeed, currentTime))

            self.panFloatWrapper(delta)

        event.accept()

    def kineticTimerEvent(self):

        currentTime = QTime.currentTime()

        deltaTime = self.lastMoveTime.msecsTo(currentTime)
        self.lastMoveTime = currentTime

        if self.panDecellerate:
            self.kineticPanSpeed *= pow(0.5, float(deltaTime / KINETIC_PANNING_HALFLIFE))

        scaledSpeed = self.kineticPanSpeed * deltaTime

        if self.kineticPanSpeed.manhattanLength() < KINETIC_PAN_SPEED_THRESHOLD:
            self.kineticTimer.stop()
            return
        self.panFloatWrapper(scaledSpeed)

    def panFloatWrapper(self, delta):

        self.remainingPan += delta
        move = self.remainingPan.toPoint()
        self.pan(move.x(), move.y())
        self.remainingPan -= move

    def mouseDoubleClickEvent(self, event):

        self.setFocus()

        self.pan(event.lastPos().x() - self.size().width() / 2.0, event.lastPos().y() - self.size().height() / 2.0)

        if self.zoomLevel() < self.maximumZoomLevel():
            self.setZoomLevel(self.zoomLevel() + 1)

        event.accept()

    def keyPressEvent(self, event):

        if event.key() == Qt.Key_Minus:
            if self.zoomLevel() > self.minimumZoomLevel():
                self.setZoomLevel(self.zoomLevel() - 1)
        elif event.key() == Qt.Key_Plus:
            if self.zoomLevel() < self.maximumZoomLevel():
                self.setZoomLevel(self.zoomLevel() + 1)
        elif event.key() == Qt.Key_T:
            if self.mapType() == QGraphicsGeoMap.StreetMap:
                self.setMapType(QGraphicsGeoMap.SatelliteMapDay)
            elif self.mapType() == QGraphicsGeoMap.SatelliteMapDay:
                self.setMapType(QGraphicsGeoMap.StreetMap)

        event.accept()

    def wheelEvent(self, event):

        if event.delta() > 0:
            if self.zoomLevel() < self.maximumZoomLevel():
                self.setZoomLevel(self.zoomLevel() + 1)
        else:
            if self.zoomLevel() > self.minimumZoomLevel():
                self.setZoomLevel(self.zoomLevel() - 1)

        event.accept()
Пример #57
0
class QtReactor(posixbase.PosixReactorBase):
    implements(IReactorFDSet)

    def __init__(self):
        self._reads = {}
        self._writes = {}
        self._notifiers = {}
        self._timer = QTimer()
        self._timer.setSingleShot(True)
        QObject.connect(self._timer, SIGNAL("timeout()"), self.iterate)

        if QCoreApplication.instance() is None:
            # Application Object has not been started yet
            self.qApp = QCoreApplication([])
            self._ownApp = True
        else:
            self.qApp = QCoreApplication.instance()
            self._ownApp = False
        self._blockApp = None
        posixbase.PosixReactorBase.__init__(self)

    def _add(self, xer, primary, type):
        """
Private method for adding a descriptor from the event loop.

It takes care of adding it if new or modifying it if already added
for another state (read -> read/write for example).
"""
        if xer not in primary:
            primary[xer] = TwistedSocketNotifier(None, self, xer, type)

    def addReader(self, reader):
        """
Add a FileDescriptor for notification of data available to read.
"""
        self._add(reader, self._reads, QSocketNotifier.Read)

    def addWriter(self, writer):
        """
Add a FileDescriptor for notification of data available to write.
"""
        self._add(writer, self._writes, QSocketNotifier.Write)

    def _remove(self, xer, primary):
        """
Private method for removing a descriptor from the event loop.

It does the inverse job of _add, and also add a check in case of the fd
has gone away.
"""
        if xer in primary:
            notifier = primary.pop(xer)
            notifier.shutdown()

    def removeReader(self, reader):
        """
Remove a Selectable for notification of data available to read.
"""
        self._remove(reader, self._reads)

    def removeWriter(self, writer):
        """
Remove a Selectable for notification of data available to write.
"""
        self._remove(writer, self._writes)

    def removeAll(self):
        """
Remove all selectables, and return a list of them.
"""
        rv = self._removeAll(self._reads, self._writes)
        return rv

    def getReaders(self):
        return self._reads.keys()

    def getWriters(self):
        return self._writes.keys()

    def callLater(self, howlong, *args, **kargs):
        rval = super(QtReactor, self).callLater(howlong, *args, **kargs)
        self.reactorInvocation()
        return rval

    def reactorInvocation(self):
        self._timer.stop()
        self._timer.setInterval(0)
        self._timer.start()

    def _iterate(self, delay=None, fromqt=False):
        """See twisted.internet.interfaces.IReactorCore.iterate.
"""
        self.runUntilCurrent()
        self.doIteration(delay, fromqt)

    iterate = _iterate

    def doIteration(self, delay=None, fromqt=False):
        'This method is called by a Qt timer or by network activity on a file descriptor'

        if not self.running and self._blockApp:
            self._blockApp.quit()
        self._timer.stop()
        delay = max(delay, 1)
        if not fromqt:
            self.qApp.processEvents(QEventLoop.AllEvents, delay * 1000)
        if self.timeout() is None:
            timeout = 0.1
        elif self.timeout() == 0:
            timeout = 0
        else:
            timeout = self.timeout()
        self._timer.setInterval(timeout * 1000)
        self._timer.start()

    def runReturn(self, installSignalHandlers=True):
        self.startRunning(installSignalHandlers=installSignalHandlers)
        self.reactorInvocation()

    def run(self, installSignalHandlers=True):
        if self._ownApp:
            self._blockApp = self.qApp
        else:
            self._blockApp = QEventLoop()
        self.runReturn()
        self._blockApp.exec_()