def __init__(self, current_case): QWidget.__init__(self) self.__model = PlotCaseModel() self.__signal_mapper = QSignalMapper(self) self.__case_selectors = {} self.__case_selectors_order = [] layout = QVBoxLayout() add_button_layout = QHBoxLayout() self.__add_case_button = QToolButton() self.__add_case_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.__add_case_button.setText("Add case to plot") self.__add_case_button.setIcon(resourceIcon("ide/small/add")) self.__add_case_button.clicked.connect(self.addCaseSelector) add_button_layout.addStretch() add_button_layout.addWidget(self.__add_case_button) add_button_layout.addStretch() layout.addLayout(add_button_layout) self.__case_layout = QVBoxLayout() self.__case_layout.setMargin(0) layout.addLayout(self.__case_layout) self.addCaseSelector(disabled=True, current_case=current_case) layout.addStretch() self.setLayout(layout) self.__signal_mapper.mapped[QWidget].connect(self.removeWidget)
class ProviderToolBar(QToolBar): ''' Widget to display the vehicles/objects status and position ''' triggered = pyqtSignal(str) def __init__(self, parent=None): super(ProviderToolBar, self).__init__(parent) self.signalMapper = QSignalMapper(self) self.setMovable(True) self.setFloatable(True) self.upToDate = False self.actions = [] self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.signalMapper.mapped[str].connect(self.triggered) def createAction(self, provider): icon = QIcon(':/plugins/PosiView/ledgreen.png') icon.addFile(':/plugins/PosiView/ledgrey.png', QSize(), QIcon.Disabled, QIcon.Off) action = QAction(icon, provider.name, None) button = QToolButton() button.setDefaultAction(action) action.setEnabled(False) provider.deviceConnected.connect(action.setEnabled) provider.deviceDisconnected.connect(action.setDisabled) self.signalMapper.setMapping(action, provider.name) action.triggered.connect(self.signalMapper.map) self.addAction(action) self.actions.append(action)
def __init__(self, auth, conversation_id, settings, version, parent = None): QDialog.__init__(self, parent) self.ui = cg.Ui_Dialog() self.ui.setupUi(self) self.settings = settings self.auth = auth self.version = version # Initialize signal mappers for buttons and lists for buttons pointers self.context_buttons_mapper = QSignalMapper(self) self.context_buttons_list = [] self.destroy_buttons_mapper = QSignalMapper(self) self.destroy_buttons_list = [] self.redent_buttons_mapper = QSignalMapper(self) self.redent_buttons_list = [] self.like_buttons_mapper = QSignalMapper(self) self.like_buttons_list = [] self.dentid_buttons_mapper = QSignalMapper(self) self.dentid_buttons_list = [] self.ui.context.setSortingEnabled(True) self.ui.context.sortByColumn(2, Qt.DescendingOrder) for column in range(2, 6): self.ui.context.setColumnHidden(column, True) self.ui.context.setColumnWidth(0, 65) self.ui.context.itemActivated.connect(self.reply_to_dent) conversation = self.auth.get_conversation(conversation_id) self.list_handler = list_handler.List_Handler(self.callback) self.list_item = list_item.list_item() self.list_handler.add_data("conversation", conversation, self.settings["server"]) self.connect_buttons()
def __init__(self, parent=None, columns=4, buttonSize=None, iconSize=None, toolButtonStyle=Qt.ToolButtonTextUnderIcon): QFrame.__init__(self, parent) if buttonSize is not None: buttonSize = QSize(buttonSize) if iconSize is not None: iconSize = QSize(iconSize) self.__columns = columns self.__buttonSize = buttonSize or QSize(50, 50) self.__iconSize = iconSize or QSize(26, 26) self.__toolButtonStyle = toolButtonStyle self.__gridSlots = [] self.__buttonListener = ToolButtonEventListener(self) self.__buttonListener.buttonRightClicked.connect( self.__onButtonRightClick) self.__buttonListener.buttonEnter.connect(self.__onButtonEnter) self.__mapper = QSignalMapper() self.__mapper.mapped[QObject].connect(self.__onClicked) self.__setupUi()
def gTable(self): self.gtable = QTableWidget() self.gtable.setColumnCount(1) self.gtable.setRowCount(len(self.tables.tablesIdWriteMap)) self.gtable.setHorizontalHeaderItem( 0, QTableWidgetItem(QString("version"))) self.hlayout.addWidget(self.gtable) self.sigMapper = QSignalMapper(self) for id in self.tables.tablesIdWriteMap: wlist = self.tables.tablesIdWriteMap[id] cbox = QComboBox(self.gtable) self.connect(cbox, SIGNAL("activated(QString)"), self.sigMapper, SLOT("map()")) self.sigMapper.setMapping(cbox, id) l = [] for write in wlist: l.append(write) l.sort() l.reverse() for write in l: cbox.addItem(QString(hex(write))) self.gtable.setCellWidget(id, 0, cbox) self.gtable.setVerticalHeaderItem( id, QTableWidgetItem(QString(hex(id)))) self.connect(self.sigMapper, SIGNAL("mapped(int)"), self.viewTableUpdate) self.gtable.setMaximumWidth( self.gtable.columnWidth(0) + self.gtable.verticalHeader().sectionSize(0) + 30)
class PeriodicInstrumentController(NonBlockingInstrumentController): def __init__(self, instrument_config): NonBlockingInstrumentController.__init__(self, instrument_config) self.mapper = QSignalMapper() self.timers = [] def run(self): # create and start periodic timers for each command for i, command in enumerate(self.instr_cfg.operation_commands): self.log.debug("Creating timer for '{0}' command".format( command.name)) timer = QTimer() timer.timeout.connect(self.mapper.map) self.mapper.setMapping(timer, i) timer.start(command.param) self.timers.append(timer) self.mapper.mapped.connect(self.send_command) NonBlockingInstrumentController.run(self) def quit(self): for timer in self.timers: timer.stop() NonBlockingInstrumentController.quit(self) def send_command(self, num): self.new_command.emit(self.instr_cfg.operation_commands[num])
def contextMenuEvent(self, event): menu = QtGui.QMenu() last_pos = event.pos() cursor = self.cursorForPosition(last_pos) pos = cursor.positionInBlock() line = cursor.blockNumber() keywords = self.words_at_pos(line, pos) if len(keywords) > 0: keyword_mapper = QSignalMapper(self) actions = [] for keyword in keywords: action_text = "Copy \"%s\"" % keyword[0].meaning actions.append(QtGui.QAction(action_text, None)) # We can only send strings with the signal mapper, so pickle our data. data = pickle.dumps(keyword[0]) data = QtCore.QString.fromAscii(data) self.connect(actions[-1], QtCore.SIGNAL("triggered()"), keyword_mapper, QtCore.SLOT("map()")) keyword_mapper.setMapping(actions[-1], data) self.connect(keyword_mapper, QtCore.SIGNAL("mapped(QString)"), self.copy_keyword) menu.addActions(actions) menu.addSeparator() default_menu = self.createStandardContextMenu() menu.addActions(default_menu.actions()) menu.exec_(event.globalPos())
def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowFlags(Qt.Window) self._mdi_area = QMdiArea() self._mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self._mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setCentralWidget(self._mdi_area) # set the size of mid_area and DocumentViewManager based on the # screen size. screen = QDesktopWidget().availableGeometry() self._mdi_area.resize(screen.width() - 30, screen.height() - 80) self.resize(self._mdi_area.size()) self._mdi_area.subWindowActivated.connect(self.update_actions) self._viewer_mapper = QSignalMapper(self) self._viewer_mapper.mapped[QWidget].connect(self.set_active_sub_window) win_title = QApplication.translate( "DocumentViewManager", "Document Viewer" ) self.setWindowTitle(win_title) self.setUnifiedTitleAndToolBarOnMac(True) self.statusBar().showMessage( QApplication.translate( "DocumentViewManager", "Ready" ) ) self._doc_viewers = {} self._create_menu_actions() self.update_actions()
class LEDDialog(QDialog): rowwidth = 20 def __init__(self, strip, parent=None): super(LEDDialog,self).__init__(parent) self.strip = strip self.buttons = [] layout = QVBoxLayout() btnlayout = QGridLayout() self.btnmapper = QSignalMapper() for i in xrange(int(self.strip.config['nleds'])): p = QPushButton() p.setFixedWidth(40) p.setFlat(True) p.setAutoFillBackground(True) self.btnmapper.setMapping( p, i) p.clicked.connect( self.btnmapper.map) self.buttons += [[p,QColor()]] btnlayout.addWidget(p, i/self.rowwidth, i%self.rowwidth) self.btnmapper.mapped['int'].connect(self.chooseColor) layout.addLayout(btnlayout) ctrllayout = QHBoxLayout() p = QPushButton("Refresh") p.clicked.connect(self.refresh) ctrllayout.addWidget(p) p = QPushButton("Set") p.clicked.connect(self.set) ctrllayout.addWidget(p) p = QPushButton("Close") p.clicked.connect(self.close) ctrllayout.addWidget(p) layout.addLayout(ctrllayout) self.setLayout( layout) self.refresh() def refresh(self): tmp = self.strip.state() for i in xrange(len(self.buttons)): c = QColor(int(tmp[i*3+0]),int(tmp[i*3+1]),int(tmp[i*3+2])) pal = self.buttons[i][0].palette() pal.setBrush( QPalette.Button, QColor(c.red(),c.green(),c.blue())) self.buttons[i][0].setPalette(pal) self.buttons[i][1] = c def set(self): leds = [] for b,c in self.buttons: leds += [ c.red(), c.green(), c.blue() ] self.strip.setState(leds) time.sleep(0.1) self.refresh() def chooseColor(self, i): if not i < len(self.buttons): return initial = self.buttons[i][1] c = QColorDialog.getColor(initial,self) if initial == c: return pal = self.buttons[i][0].palette() pal.setBrush( QPalette.Button, QColor(c.red(),c.green(),c.blue())) self.buttons[i][0].setPalette(pal) self.buttons[i][1] = c
def _init_translators(self): translator_menu = QMenu(self) self._trans_widget_mgr = TranslatorWidgetManager(self) self._trans_signal_mapper = QSignalMapper(self) for trans_name, config in ValueTranslatorConfig.translators.iteritems(): trans_action = QAction( u'{}...'.format(trans_name), translator_menu ) self._trans_signal_mapper.setMapping(trans_action, trans_name) trans_action.triggered.connect(self._trans_signal_mapper.map) translator_menu.addAction(trans_action) if len(translator_menu.actions()) == 0: self.btn_add_translator.setEnabled(False) else: self.btn_add_translator.setMenu(translator_menu) self._trans_signal_mapper.mapped[str].connect(self._load_translator_dialog) self.btn_edit_translator.setEnabled(False) self.btn_delete_translator.setEnabled(False) self.btn_edit_translator.clicked.connect(self._on_edit_translator) self.btn_delete_translator.clicked.connect(self._on_delete_translator)
def __init__(self, parent, tester): """Construct a new dockwindow following the tester """ self.tester = tester QtGui.QDockWidget.__init__(self, tester.testname, parent) self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) if not self.widget(): self.setWidget(QtGui.QWidget(self)) vl = QtGui.QVBoxLayout(self.widget()) #self.widget().setLayout(vl) panel = QtGui.QFrame(self) vl.addWidget(panel) self.login = QtGui.QLineEdit(self) self.login.textEdited.connect(self.check_logpass) self.password = QtGui.QLineEdit(self) self.password.setEchoMode(QtGui.QLineEdit.Password) self.password.textEdited.connect(self.check_logpass) self.tests = [] fl = QtGui.QFormLayout(panel) fl.addRow('&Login:'******'&Password:',self.password) panel.setLayout(fl) panel = QtGui.QFrame(self) panel.setFrameShadow(QtGui.QFrame.Sunken) panel.setFrameShape(QtGui.QFrame.Panel) vl.addWidget(panel) vl2 = QtGui.QVBoxLayout(panel) signalmapper = QSignalMapper(self) signalmapper.mapped[int].connect(self.test) for i,test in enumerate(self.tester.tests): btn = QtGui.QPushButton("Test {}: {}".format(i+1,test.name),panel) btn.setStyleSheet(self.btn_default_stylesheet) btn.setEnabled(False) vl2.addWidget(btn) self.tests.append(btn) signalmapper.setMapping(btn,i) btn.clicked.connect(signalmapper.map) panel.setLayout(vl2) self.text = QtGui.QLabel("Enter your Coursera login and assignments password and push one of the test buttons above to run the test and submit the results to Coursera.") self.text.setWordWrap(True) vl.addWidget(self.text) self.text.setFrameShadow(QtGui.QFrame.Sunken) self.text.setFrameShape(QtGui.QFrame.Panel) self.text.setMargin(5) #vl.setStretch(2,1) vl.addStretch(1)
def _setup_self(self): """Sets up self.""" self.setObjectName(u'stackedWidget') self.openTabSignalMapper = QSignalMapper(self) self._build_widgets()
def __init__(self, parent=None): super(ProviderToolBar, self).__init__(parent) self.signalMapper = QSignalMapper(self) self.setMovable(True) self.setFloatable(True) self.upToDate = False self.actions = [] self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.signalMapper.mapped[str].connect(self.triggered)
def setupUi(self, nx, ny, keys): mapper = QSignalMapper() layout = QGridLayout(self) for ix in range(nx): for iy in range(ny): key = keys[iy * nx + ix] keyPb = QPushButton(self) keyPb.setFixedHeight(40) keyPb.setText(key[0]) keyPb.clicked.connect(mapper.map) layout.addWidget(keyPb, iy, ix) mapper.setMapping(keyPb, key[1]) mapper.mapped.connect(self.keyClicked) self.mapper = mapper
def __init__(self, current_case): QWidget.__init__(self) self.__model = PlotCaseModel() self.__signal_mapper = QSignalMapper(self) self.__case_selectors = {} self.__case_selectors_order = [] layout = QVBoxLayout() add_button_layout = QHBoxLayout() button = QPushButton(util.resourceIcon("ide/small/add"), "Add case to plot") button.clicked.connect(self.addCaseSelector) add_button_layout.addStretch() add_button_layout.addWidget(button) add_button_layout.addStretch() layout.addLayout(add_button_layout) self.__case_layout = QVBoxLayout() self.__case_layout.setMargin(0) layout.addLayout(self.__case_layout) self.addCaseSelector(disabled=True, current_case=current_case) layout.addStretch() self.setLayout(layout) self.__signal_mapper.mapped[QWidget].connect(self.removeWidget)
def _createToolbarAndConnect(self): """Create toolbar and connect tools.""" self.signalMapper = QSignalMapper(self) self._mToolbar = QToolBar(self) self._mToolbar.addAction(self.actionImport) self._mToolbar.addAction(self.actionSave) self._mToolbar.addSeparator() self._mToolbar.addAction(self.actionSelect) self._mToolbar.addAction(self.actionDeselect) self._mToolbar.addSeparator() self._mToolbar.addAction(self.actionDelete) self.actionSave.setEnabled(False) self.actionSelect.setEnabled(False) self.actionDeselect.setEnabled(False) self.actionDelete.setEnabled(False) self.toolbarLayout.insertWidget(0, self._mToolbar) self.connect(self.actionImport, SIGNAL("triggered()"), self.onLoad) self.connect(self.actionSave, SIGNAL("triggered()"), self.onSave) self.connect(self.actionSelect, SIGNAL("triggered()"), self.onSelect) self.connect(self.actionDeselect, SIGNAL("triggered()"), self.onDeselect) self.connect(self.actionDelete, SIGNAL("triggered()"), self.onDelete) self.connect(self.styleButton, SIGNAL("clicked()"), self.onStyle)
def __init__(self, parent=None, columns=4, buttonSize=None, iconSize=None, toolButtonStyle=Qt.ToolButtonTextUnderIcon): QFrame.__init__(self, parent) if buttonSize is not None: buttonSize = QSize(buttonSize) if iconSize is not None: iconSize = QSize(iconSize) self.__columns = columns self.__buttonSize = buttonSize or QSize(50, 50) self.__iconSize = iconSize or QSize(26, 26) self.__toolButtonStyle = toolButtonStyle self.__gridSlots = [] self.__buttonListener = ToolButtonEventListener(self) self.__buttonListener.buttonRightClicked.connect( self.__onButtonRightClick) self.__buttonListener.buttonEnter.connect( self.__onButtonEnter) self.__mapper = QSignalMapper() self.__mapper.mapped[QObject].connect(self.__onClicked) self.__setupUi()
def __init__ (self, parent, collections=None, songs=None, busName=None, busPath=None): SatyrObject.__init__ (self, parent, busName, busPath) self.configValues= ( ('collsNo', int, 0), ) self.loadConfig () self.signalMapper= QSignalMapper () self.collections= [] if songs is None: self.songs= [] self.count= 0 else: self.songs= songs self.count= len (songs) # if collections is not None we it means the may have changed if self.collsNo>0 and collections is None: logger.info ("loading collections from config", self.collsNo) for index in xrange (self.collsNo): collection= Collection (self, busName=busName, busPath="/collection_%04d" % index) self.append (collection) else: if collections is not None: for collection in collections: self.append (collection) self.signalMapper.mapped.connect (self.addSongs)
def __init__(self, current_case): QWidget.__init__(self) self.__model = PlotCaseModel() self.__signal_mapper = QSignalMapper(self) self.__case_selectors = {} self.__case_selectors_order = [] layout = QVBoxLayout() add_button_layout = QHBoxLayout() self.__add_case_button = QToolButton() self.__add_case_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.__add_case_button.setText("Add case to plot") self.__add_case_button.setIcon(resourceIcon("ide/small/add")) self.__add_case_button.clicked.connect(self.addCaseSelector) add_button_layout.addStretch() add_button_layout.addWidget(self.__add_case_button) add_button_layout.addStretch() layout.addLayout(add_button_layout) self.__case_layout = QVBoxLayout() self.__case_layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(self.__case_layout) self.addCaseSelector(disabled=True, current_case=current_case) layout.addStretch() self.setLayout(layout) self.__signal_mapper.mapped[QWidget].connect(self.removeWidget)
def __init__ (self, collaggr=None, songs=None, view=None): QAbstractTableModel.__init__ (self, view) # TODO: different delegate for editing tags: one with completion self.view_= view self.playlist= view.playlist self.edited= False if songs is None: self.collaggr= collaggr self.collections= self.collaggr.collections self.signalMapper= QSignalMapper () for collNo, collection in enumerate (self.collections): collection.newSongs.connect (self.signalMapper.map) self.signalMapper.setMapping (collection, collNo) self.signalMapper.mapped.connect (self.addRows) else: self.collaggr= CollectionAggregator (self, songs=songs) self.attrNames= ('artist', 'year', 'collection', 'diskno', 'album', 'trackno', 'title', 'length', 'filepath') self.headers= (u'Artist', u'Year', u'Collection', u'CD', u'Album', u'Track', u'Title', u'Length', u'Path') # FIXME: kinda hacky self.fontMetrics= QFontMetrics (KGlobalSettings.generalFont ()) # FIXME: (even more) hackish self.columnWidths= ("M"*15, "M"*4, "M"*15, "M"*3, "M"*20, "M"*3, "M"*25, "M"*5, "M"*200) logger.debug ("QPLM: ", self)
def __init__(self, strip, parent=None): super(LEDDialog,self).__init__(parent) self.strip = strip self.buttons = [] layout = QVBoxLayout() btnlayout = QGridLayout() self.btnmapper = QSignalMapper() for i in xrange(int(self.strip.config['nleds'])): p = QPushButton() p.setFixedWidth(40) p.setFlat(True) p.setAutoFillBackground(True) self.btnmapper.setMapping( p, i) p.clicked.connect( self.btnmapper.map) self.buttons += [[p,QColor()]] btnlayout.addWidget(p, i/self.rowwidth, i%self.rowwidth) self.btnmapper.mapped['int'].connect(self.chooseColor) layout.addLayout(btnlayout) ctrllayout = QHBoxLayout() p = QPushButton("Refresh") p.clicked.connect(self.refresh) ctrllayout.addWidget(p) p = QPushButton("Set") p.clicked.connect(self.set) ctrllayout.addWidget(p) p = QPushButton("Close") p.clicked.connect(self.close) ctrllayout.addWidget(p) layout.addLayout(ctrllayout) self.setLayout( layout) self.refresh()
def setup_file_locs(self): # Because the default margins are ugly as h*ck. self.ui.tabLocs.layout().setContentsMargins(0, 0, 0, 0) # Map our buttons to functions that retrieve the necessary data. cfg_mapper = QSignalMapper(self) for i, item in enumerate(FILE_LOCATIONS): self.connect(self.ui.__dict__[item[BTN]], QtCore.SIGNAL("clicked()"), cfg_mapper, QtCore.SLOT("map()")) cfg_mapper.setMapping(self.ui.__dict__[item[BTN]], i) self.connect(cfg_mapper, QtCore.SIGNAL("mapped(int)"), self.__get_cfg_item) # Load in all our info from the config file. for item in FILE_LOCATIONS: self.ui.__dict__[item[TEXT]].setText(common.editor_config.get_pref(item[CFG]))
def __init__(self, *args, **kwargs): QGraphicsScene.__init__(self, *args, **kwargs) self.scheme = None self.registry = None # All node items self.__node_items = [] # Mapping from SchemeNodes to canvas items self.__item_for_node = {} # All link items self.__link_items = [] # Mapping from SchemeLinks to canvas items. self.__item_for_link = {} # All annotation items self.__annotation_items = [] # Mapping from SchemeAnnotations to canvas items. self.__item_for_annotation = {} # Is the scene editable self.editable = True # Anchor Layout self.__anchor_layout = AnchorLayout() self.addItem(self.__anchor_layout) self.__channel_names_visible = True self.__node_animation_enabled = True self.user_interaction_handler = None self.activated_mapper = QSignalMapper(self) self.activated_mapper.mapped[QObject].connect( lambda node: self.node_item_activated.emit(node) ) self.hovered_mapper = QSignalMapper(self) self.hovered_mapper.mapped[QObject].connect( lambda node: self.node_item_hovered.emit(node) ) self.position_change_mapper = QSignalMapper(self) self.position_change_mapper.mapped[QObject].connect( self._on_position_change ) log.info("'%s' intitialized." % self)
def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) # Scroll area for the contents. self.__scrollArea = \ _ToolBoxScrollArea(self, objectName="toolbox-scroll-area") self.__scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.__scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.__scrollArea.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.__scrollArea.setFrameStyle(QScrollArea.NoFrame) self.__scrollArea.setWidgetResizable(True) # A widget with all of the contents. # The tabs/contents are placed in the layout inside this widget self.__contents = QWidget(self.__scrollArea, objectName="toolbox-contents") # The layout where all the tab/pages are placed self.__contentsLayout = QVBoxLayout() self.__contentsLayout.setContentsMargins(0, 0, 0, 0) self.__contentsLayout.setSizeConstraint(QVBoxLayout.SetMinAndMaxSize) self.__contentsLayout.setSpacing(0) self.__contents.setLayout(self.__contentsLayout) self.__scrollArea.setWidget(self.__contents) layout.addWidget(self.__scrollArea) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding) self.__tabActionGroup = \ QActionGroup(self, objectName="toolbox-tab-action-group") self.__tabActionGroup.setExclusive(self.__exclusive) self.__actionMapper = QSignalMapper(self) self.__actionMapper.mapped[QObject].connect(self.__onTabActionToogled)
def __init__(self): Observer.__init__(self) QMainWindow.__init__(self) super(TratadorInterface, self).__init__(self) self.setupUi(self) self.erro_vertice_existe.connect(self.verticeExiste) self.erro_vertice_nao_existe.connect(self.verticeNaoExiste) self.eh_funcao.setEnabled(False) self.funcao_edit.setEnabled(False) self.grafo = None self.signalMapper = QSignalMapper(self)
class SelectMapper: def setupSelectMapper(self, selectMapper, selectAllButton=None): """selectMapper should include keys 'button'(QPushButton) and 'widget'(QWidget) """ self._select = None self.selectMapper = selectMapper self.selectAllButton = selectAllButton self.signalMapper = QSignalMapper(self) for key, value in self.selectMapper.iteritems(): # config signal mapper value['button'].clicked.connect(self.signalMapper.map) self.signalMapper.setMapping(value['button'], key) # connect signal mapper to slot 'select' QObject.connect(self.signalMapper, SIGNAL("mapped(QString)"), self.select) if selectAllButton: selectAllButton.clicked.connect(self.selectAll) def select(self, select): select = unicode(select) self.selectMapper[select]['button'].setChecked(True) if self._select == select: return if self._select: self.selectMapper[self._select]['button'].setChecked(False) self.selectMapper[self._select]['widget'].hide() else: if self.selectAllButton: self.selectAllButton.setChecked(False) for key, value in self.selectMapper.iteritems(): value['widget'].hide() self.selectMapper[select]['widget'].show() self._select = select def selectAll(self): self.selectAllButton.setChecked(True) if self._select == None: return for key, value in self.selectMapper.iteritems(): value['button'].setChecked(False) value['widget'].show() self._select = None
def __init__(self, items, colCount, parent=None): """ Create Grid and setup QSignalMapper. Connect each item's 'clicked' signal and use the sequence index as map value which will be passed as argument when the Grid's clicked signal is emitted. items: sequence with widgets having a 'void clicked()' signal colCount: column count for each row parent: parent widget, default None """ super(Grid, self).__init__(parent) # Create a grid layout. layout = QGridLayout() self.setLayout(layout) # Create the signal mapper. signalMapper = QSignalMapper(self) for cnt, item in enumerate(items): # Setup mapping for the item. In this case, the # mapping is the sequence index of the item. signalMapper.setMapping(item, cnt) # Connect the item's 'clicked' signal to the signal # mapper's 'map' slot. # The 'map' slot will emit the 'mapped' signal # when invoked and the mapping set previously will be # passed as an argument to the slot/signal that is # connected to the signal mapper's 'mapped' signal. item.clicked.connect(signalMapper.map) # Add the widget to the grid layout layout.addWidget(item, cnt / colCount, cnt % colCount) # Forward the signal mapper's 'mapped' signal via the Grid's # 'clicked' signal. This will handle all widgets' 'clicked' # ssignals. signalMapper.mapped.connect(self.clicked)
def setup_file_locs(self): # Because the default margins are ugly as h*ck. self.ui.tabLocs.layout().setContentsMargins(0, 0, 0, 0) # Map our buttons to functions that retrieve the necessary data. cfg_mapper = QSignalMapper(self) for i, item in enumerate(FILE_LOCATIONS): self.connect(self.ui.__dict__[item[BTN]], QtCore.SIGNAL("clicked()"), cfg_mapper, QtCore.SLOT("map()")) cfg_mapper.setMapping(self.ui.__dict__[item[BTN]], i) self.connect(cfg_mapper, QtCore.SIGNAL("mapped(int)"), self.__get_cfg_item) # Load in all our info from the config file. for item in FILE_LOCATIONS: self.ui.__dict__[item[TEXT]].setText( common.editor_config.get_pref(item[CFG]))
def on_adicionar_vertice_button_clicked(self): if not self.grafo: nome = str(self.nome_edit.text()) if nome == '': QMessageBox(self).critical(self, 'ERRO', 'O Gravo deve ter um nome!', buttons=QMessageBox.Ok) return self.grafo = AlgoritmosGrafoNO(nome) self.observe(self.grafo) self.limparInferencias() vertices = str(self.vertices_edit.text()) vertices = vertices.split(',') if len(vertices) > 0: self.signalMapper = QSignalMapper(self) for vertice in vertices: vertice = vertice.strip() if vertice != '': cont = self.tabela_adjacencia.rowCount() item = QTableWidgetItem(vertice) self.tabela_adjacencia.insertColumn(cont) self.tabela_adjacencia.insertRow(cont) self.tabela_adjacencia.setHorizontalHeaderItem(cont,item) self.tabela_adjacencia.setVerticalHeaderItem(cont,item) self.grafo.adicionarVertice(vertice) for x in xrange(self.tabela_adjacencia.rowCount()): comboV = QComboBox(self) comboH = QComboBox(self) comboV.addItems(['0','1']) comboH.addItems(['0','1']) comboV.setSizePolicy(QSizePolicy().Minimum, QSizePolicy().Minimum) comboH.setSizePolicy(QSizePolicy().Minimum, QSizePolicy().Minimum) self.tabela_adjacencia.setCellWidget(cont,x,comboH) self.tabela_adjacencia.setCellWidget(x,cont,comboV) for x in xrange(self.tabela_adjacencia.rowCount()): for y in xrange(self.tabela_adjacencia.rowCount()): item = self.tabela_adjacencia.cellWidget(x, y) self.connect(item, SIGNAL('currentIndexChanged(int)'),self.signalMapper, SLOT('map()')) self.signalMapper.setMapping(item, '{0};{1}'.format(x,y)) self.connect(self.signalMapper, SIGNAL('mapped(QString)'), self.valorAlterado) self.tabela_adjacencia.resizeColumnsToContents() self.tabela_adjacencia.resizeRowsToContents() self.fecho_origem.addItems(vertices) self.informacoes_vertice.addItems(vertices) self.busca_destino.addItems(vertices) self.busca_origem.addItems(vertices) self.remover_vertice_combo.addItems(vertices) self.ordem_resultado.setText(str(self.grafo.obterOrdem())) self.gerar_arestas_button.setEnabled(True) self.vertices_edit.clear()
def loadPlugins(self): """Looks for all plugins and creates menu entries, signals and slots for them.""" self.pluginSignalMapper = QSignalMapper(self) for p in plugin_list: click_action = QAction(p.name, self) self.menuPlugins.addAction(click_action) self.connect(click_action, SIGNAL("triggered()"), self.pluginSignalMapper, SLOT("map()")) self.pluginSignalMapper.setMapping(click_action, QString(p.name)) self.connect(self.pluginSignalMapper, SIGNAL("mapped(const QString &)"), self.image_browser.handlePluginClicked)
def init ( self, parent ): """ Finishes initializing the editor by creating the underlying toolkit widget. """ super( RadioEditor, self ).init( parent ) # The control is a grid layout: self.control = layout = QGridLayout() layout.setSpacing( 0 ) layout.setMargin( 0 ) self._mapper = QSignalMapper() QObject.connect( self._mapper, SIGNAL( 'mapped(QWidget *)' ), self.update_object ) self.rebuild_editor()
def setupSelectMapper(self, selectMapper, selectAllButton=None): """selectMapper should include keys 'button'(QPushButton) and 'widget'(QWidget) """ self._select = None self.selectMapper = selectMapper self.selectAllButton = selectAllButton self.signalMapper = QSignalMapper(self) for key, value in self.selectMapper.iteritems(): # config signal mapper value['button'].clicked.connect(self.signalMapper.map) self.signalMapper.setMapping(value['button'], key) # connect signal mapper to slot 'select' QObject.connect(self.signalMapper, SIGNAL("mapped(QString)"), self.select) if selectAllButton: selectAllButton.clicked.connect(self.selectAll)
def _connectSignals(self): self._signalMapper = QSignalMapper() for widgetName, modelAttr in self.FIELDS: widget = getattr(self, widgetName) self._widget2ModelAttr[widget] = modelAttr self._signalMapper.setMapping(widget, widget) if isinstance(widget, QComboBox): widget.currentIndexChanged.connect(self._signalMapper.map) elif isinstance(widget, QSpinBox): widget.valueChanged.connect(self._signalMapper.map) elif isinstance(widget, QLineEdit): widget.editingFinished.connect(self._signalMapper.map) elif isinstance(widget, QPlainTextEdit): widget.textChanged.connect(self._signalMapper.map) elif isinstance(widget, QCheckBox): widget.stateChanged.connect(self._signalMapper.map) self._signalMapper.mapped[QWidget].connect(self.widgetChanged)
def __init__(self, parent = None): QMainWindow.__init__(self, parent) self.setWindowFlags(Qt.Window) self._mdi_area = QMdiArea() self.setCentralWidget(self._mdi_area) self._mdi_area.subWindowActivated.connect(self.update_actions) self._viewer_mapper = QSignalMapper(self) self._viewer_mapper.mapped[QWidget].connect(self.set_active_sub_window) win_title = QApplication.translate("DocumentViewManager","Document Viewer") self.setWindowTitle(win_title) self.setUnifiedTitleAndToolBarOnMac(True) self.statusBar().showMessage(QApplication.translate("DocumentViewManager","Ready")) self._doc_viewers = {} self._create_menu_actions() self.update_actions()
def gTable(self): self.gtable = QTableWidget() self.gtable.setColumnCount(1) self.gtable.setRowCount(len(self.tables.tablesIdWriteMap)) self.gtable.setHorizontalHeaderItem(0, QTableWidgetItem(QString("version"))) self.hlayout.addWidget(self.gtable) self.sigMapper = QSignalMapper(self) for id in self.tables.tablesIdWriteMap: wlist = self.tables.tablesIdWriteMap[id] cbox = QComboBox(self.gtable) self.connect(cbox, SIGNAL("activated(QString)"), self.sigMapper, SLOT("map()")) self.sigMapper.setMapping(cbox, id) l = [] for write in wlist: l.append(write) l.sort() l.reverse() for write in l: cbox.addItem(QString(hex(write))) self.gtable.setCellWidget(id, 0, cbox) self.gtable.setVerticalHeaderItem(id, QTableWidgetItem(QString(hex(id)))) self.connect(self.sigMapper, SIGNAL("mapped(int)"), self.viewTableUpdate) self.gtable.setMaximumWidth(self.gtable.columnWidth(0) + self.gtable.verticalHeader().sectionSize(0) + 30)
def __init__(self, parent, tester): """Construct a new dockwindow following the tester """ self.tester = tester QtGui.QDockWidget.__init__(self, tester.testname, parent) self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) if not self.widget(): self.setWidget(QtGui.QWidget(self)) vl = QtGui.QVBoxLayout(self.widget()) #self.widget().setLayout(vl) panel = QtGui.QFrame(self) vl.addWidget(panel) self.login = QtGui.QLineEdit(self) self.login.textEdited.connect(self.check_logpass) self.password = QtGui.QLineEdit(self) self.password.setEchoMode(QtGui.QLineEdit.Password) self.password.textEdited.connect(self.check_logpass) self.tests = [] fl = QtGui.QFormLayout(panel) fl.addRow('&Login:'******'&Password:', self.password) panel.setLayout(fl) panel = QtGui.QFrame(self) panel.setFrameShadow(QtGui.QFrame.Sunken) panel.setFrameShape(QtGui.QFrame.Panel) vl.addWidget(panel) vl2 = QtGui.QVBoxLayout(panel) signalmapper = QSignalMapper(self) signalmapper.mapped[int].connect(self.test) for i, test in enumerate(self.tester.tests): btn = QtGui.QPushButton("Test {}: {}".format(i + 1, test.name), panel) btn.setStyleSheet(self.btn_default_stylesheet) btn.setEnabled(False) vl2.addWidget(btn) self.tests.append(btn) signalmapper.setMapping(btn, i) btn.clicked.connect(signalmapper.map) panel.setLayout(vl2) self.text = QtGui.QLabel( "Enter your Coursera login and assignments password and push one of the test buttons above to run the test and submit the results to Coursera." ) self.text.setWordWrap(True) vl.addWidget(self.text) self.text.setFrameShadow(QtGui.QFrame.Sunken) self.text.setFrameShape(QtGui.QFrame.Panel) self.text.setMargin(5) #vl.setStretch(2,1) vl.addStretch(1)
class MainWindowStart(QMainWindow, MainWindow_Pro.Ui_MainWindow): def __init__(self, parent=None): super(MainWindowStart, self).__init__(parent) # Mappers for connecting buttons and labels self.myMapper = QSignalMapper(self) self.myMapper_StyleSheet = QSignalMapper(self) # Load UI self.setupUi(self) self.regex_edits = QRegExp(r"(^[0]+$|^$)") self._filter = Filter() self.filename = QString() self.edit1_delayh.installEventFilter(self._filter) self.sizeLabel = QLabel() self.sizeLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.statusBar1.addPermanentWidget(self.sizeLabel) self.statusBar1.setSizeGripEnabled(False) self.create_connections() self.assign_shortcuts() self.create_tool_bar() self.update_devices_list() # self.button_stop.clicked.connect(self.stop_all) # List of valve pushbuttons self.valve_list = [ self.valve1, self.valve2, self.valve3, self.valve4, self.valve5, self.valve6, self.valve7, self.valve8 ] # GroupBoxes for grouping labels and buttons on each row, used for applying StyleSheets self.group_boxes = [ self.groupbox1, self.groupbox2, self.groupbox3, self.groupbox4, self.groupbox5, self.groupbox6, self.groupbox7, self.groupbox8 ] # List of lineEdits self.lineEdits_list = [ (self.edit1_delayh, self.edit1_delaym, self.edit1_delays, self.edit1_onh, self.edit1_onm, self.edit1_ons, self.edit1_offh, self.edit1_offm, self.edit1_offs, self.edit1_totalh, self.edit1_totalm, self.edit1_totals), (self.edit2_delayh, self.edit2_delaym, self.edit2_delays, self.edit2_onh, self.edit2_onm, self.edit2_ons, self.edit2_offh, self.edit2_offm, self.edit2_offs, self.edit2_totalh, self.edit2_totalm, self.edit2_totals), (self.edit3_delayh, self.edit3_delaym, self.edit3_delays, self.edit3_onh, self.edit3_onm, self.edit3_ons, self.edit3_offh, self.edit3_offm, self.edit3_offs, self.edit3_totalh, self.edit3_totalm, self.edit3_totals), (self.edit4_delayh, self.edit4_delaym, self.edit4_delays, self.edit4_onh, self.edit4_onm, self.edit4_ons, self.edit4_offh, self.edit4_offm, self.edit4_offs, self.edit4_totalh, self.edit4_totalm, self.edit4_totals), (self.edit5_delayh, self.edit5_delaym, self.edit5_delays, self.edit5_onh, self.edit5_onm, self.edit5_ons, self.edit5_offh, self.edit5_offm, self.edit5_offs, self.edit5_totalh, self.edit5_totalm, self.edit5_totals), (self.edit6_delayh, self.edit6_delaym, self.edit6_delays, self.edit6_onh, self.edit6_onm, self.edit6_ons, self.edit6_offh, self.edit6_offm, self.edit6_offs, self.edit6_totalh, self.edit6_totalm, self.edit6_totals), (self.edit7_delayh, self.edit7_delaym, self.edit7_delays, self.edit7_onh, self.edit7_onm, self.edit7_ons, self.edit7_offh, self.edit7_offm, self.edit7_offs, self.edit7_totalh, self.edit7_totalm, self.edit7_totals), (self.edit8_delayh, self.edit8_delaym, self.edit8_delays, self.edit8_onh, self.edit8_onm, self.edit8_ons, self.edit8_offh, self.edit8_offm, self.edit8_offs, self.edit8_totalh, self.edit8_totalm, self.edit8_totals) ] for index, editLabels in enumerate(self.lineEdits_list, 1): for index2, lineedits in enumerate(editLabels, 0): # Apply mapper (GUIObject, objectIndex) self.myMapper_StyleSheet.setMapping( self.lineEdits_list[index - 1][index2], index - 1) # Connect mapper to signal (self.lineEdits_list[index - 1][index2]).textChanged.connect( self.myMapper_StyleSheet.map) # Set event Filter, for detecting when Focus changes self.lineEdits_list[index - 1][index2].installEventFilter( self._filter) # Set Mappers for buttons (1..8) self.myMapper.setMapping(self.valve_list[index - 1], index) # Connect mapper to signal for detecting clicks on buttons (self.valve_list[index - 1]).clicked.connect(self.myMapper.map) # Connect to signal for enabling labelEdits self.myMapper.mapped['int'].connect(self.enable_fields) # Connect to signal for changing color of groupbox used for visual indication self.myMapper_StyleSheet.mapped['int'].connect(self.valve_color_status) # Create Keyboard Shortcuts def assign_shortcuts(self): self.actionArchivo_Nuevo.setShortcut(QKeySequence.New) self.action_Abrir.setShortcut(QKeySequence.Open) self.action_Guardar.setShortcut(QKeySequence.Save) self.actionGuardar_Como.setShortcut(QKeySequence.SaveAs) self.action_Limpiar.setShortcut('Ctrl+L') self.actionVAL_508_Ayuda.setShortcut(QKeySequence.HelpContents) self.action_Salir.setShortcut(QKeySequence.Close) # self.actionPreferencias.setShortcut(QKeySequence.Preferences) self.action_Detener_USB.setShortcut('Ctrl+Shift+C') self.action_Ejecutar.setShortcut('Ctrl+Shift+X') self.action_Para_Valvulas.setShortcut('Ctrl+Shift+P') # Create connections to signals def create_connections(self): self.actionArchivo_Nuevo.triggered.connect(self.new_file) self.action_Abrir.triggered.connect(self.open_file) self.action_Guardar.triggered.connect(self.save_file) self.actionGuardar_Como.triggered.connect(self.save_file_as) self.action_Limpiar.triggered.connect(self.clean_fields) self.action_Salir.triggered.connect(self.close) self.actionVAL_508_Ayuda.triggered.connect(self.show_help) self.actionAcerca_de_VAL_508.triggered.connect(self.show_about) self.action_Detener_USB.triggered.connect(self.stop_usb) self.action_Ejecutar.triggered.connect(self.execute) self.action_Para_Valvulas.triggered.connect(self.stop_all) # Creation of About Dialog def show_about(self): about = aboutdialog.AboutDialog(self) about.show() # Creation of Help Form def show_help(self): form = helpform.HelpForm('Help.html', self) form.show() def new_file(self): self.filename = QString() self.clean_fields() # Close connection to arduino before closing Program def closeEvent(self, QCloseEvent): try: self.thread_connection.serial_connection.close() logging.debug("Thread running and killed at closing program") except AttributeError: logging.debug("Thread was not running when closing program OK") def clean_fields(self): for index, editLabels in enumerate(self.lineEdits_list, 1): for index2, lineedits in enumerate(editLabels, 0): self.lineEdits_list[index - 1][index2].setText('0') def save_file_as(self): filename_copy = self.filename logging.info("Current filename: %s" % self.filename) my_home = os.path.expanduser('~') self.filename = QFileDialog.getSaveFileName( self, self.tr('Guardar como'), os.path.join(my_home, "archivo.txt"), "", "", QFileDialog.DontUseNativeDialog) logging.info("Filename to save: %s" % self.filename) if not self.filename.isNull(): if self.filename.endsWith(QString('.txt')): self.write_data_to_file('w') else: self.filename.append(QString('.txt')) messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Advertencia')) messageBox.setText( self.tr(u"El archivo ya existe, ¿Reemplazar?")) messageBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) messageBox.setIconPixmap(QPixmap(':/broken_file.png')) if messageBox.exec_() == QMessageBox.Yes: self.write_data_to_file('w') else: try: while True: self.filename = QFileDialog.getSaveFileName( self, self.tr('Guardar como'), os.path.join(my_home, "archivo.txt"), "", "", QFileDialog.DontUseNativeDialog) if self.filename.isNull(): raise Saved_Canceled() else: messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}' ) messageBox.setWindowTitle( self.tr('Advertencia')) messageBox.setText( self.tr( u"El archivo ya existe, ¿Reemplazar?")) messageBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No) messageBox.setIconPixmap( QPixmap(':/broken_file.png')) if messageBox.exec_() == QMessageBox.Yes: self.write_data_to_file('w') raise Saved_Accepted() except Saved_Canceled: self.filename = filename_copy except Saved_Accepted: pass logging.info("Current filename after operation: %s" % self.filename) def save_file(self): if self.filename.isNull(): self.save_file_as() else: self.write_data_to_file('w') # Colect data for arduino def execute(self): string_data = '' list_strings = [] if str(self.arduino_combobox.currentText()): self.statusBar1.showMessage(self.tr('Conectando...')) # Gather all the contents of each row of valves and create a list of lists with them for elem_edit in self.lineEdits_list: # delay string_data = string_data + str( ((int(elem_edit[0].text()) * 3600) + (int(elem_edit[1].text()) * 60) + (int(elem_edit[2].text()))) * 1000) + ';' # ON string_data = string_data + str( ((int(elem_edit[3].text()) * 3600) + (int(elem_edit[4].text()) * 60) + (int(elem_edit[5].text()))) * 1000) + ';' # OFF string_data = string_data + str( ((int(elem_edit[6].text()) * 3600) + (int(elem_edit[7].text()) * 60) + (int(elem_edit[8].text()))) * 1000) + ';' # Total string_data = string_data + str( ((int(elem_edit[9].text()) * 3600) + (int(elem_edit[10].text()) * 60) + (int(elem_edit[11].text()))) * 1000) + ';' list_strings.append(string_data) string_data = '' # Start QThread for communicating with arduino self.thread_connection = Arduino_Communication( str(self.arduino_combobox.currentText()), list_strings) self.thread_connection.start() self.action_Ejecutar.setEnabled(False) self.action_Para_Valvulas.setEnabled(False) # Connect to current QThread instance in order to know the status of it's termination # This line used only when stopping current task self.thread_connection.finished.connect(self.finished_thread) self.thread_connection.connection_exit_status.connect( self.finished_thread) else: messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Advertencia')) messageBox.setText(self.tr("Arduino no seleccionado")) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/usb_error.png')) messageBox.exec_() # Inform QThread to stop sending data to arduino def stop_usb(self): if str(self.arduino_combobox.currentText()): try: self.statusBar1.showMessage(self.tr(u'Conexión detenida')) if self.thread_connection.isRunning(): mutex.lock() self.thread_connection.kill_serial = True mutex.unlock() except AttributeError: logging.debug("Thread not running \'disconnected! \'") else: messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Advertencia')) messageBox.setText(self.tr("Arduino no seleccionado")) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/usb_error.png')) messageBox.exec_() def enable_fields(self, index): hours_reg = QRegExp(r"0*[0-9]{1,3}") sec_reg = QRegExp(r"(0*[0-9])|(0*[0-5][0-9])") for counter, line_edit in enumerate(self.lineEdits_list[index - 1]): line_edit.setEnabled(self.valve_list[index - 1].isChecked()) if counter % 3 == 0: line_edit.setValidator(QRegExpValidator(hours_reg, self)) else: line_edit.setValidator(QRegExpValidator(sec_reg, self)) def valve_color_status(self, index): logging.info("Checking color from valve button") for edit in self.lineEdits_list[index]: if edit.text().contains(self.regex_edits): self.group_boxes[index].setStyleSheet('''QGroupBox { border: 2px solid; border-color: rgba(255, 255, 255, 0);}''' ) else: self.group_boxes[index].setStyleSheet( '''QGroupBox {background-color: rgba(103, 255, 126, 150); border: 2px solid; border-color: rgba(255, 255, 255, 255);}''' ) break def create_tool_bar(self): self.label_arduino = QLabel(self.tr('Dispositivos: ')) self.toolBar.addWidget(self.label_arduino) self.arduino_combobox = QComboBox() self.arduino_combobox.setToolTip(self.tr('Seleccionar Arduino')) self.arduino_combobox.setFocusPolicy(Qt.NoFocus) # Update List of Arduino devices self.reload = QAction(QIcon(":/reload.png"), self.tr("&Refrescar"), self) self.reload.setShortcut(QKeySequence.Refresh) self.reload.setToolTip(self.tr('Refrescar Dispositivos')) self.reload.triggered.connect(self.update_devices_list) self.toolBar.addWidget(self.arduino_combobox) self.toolBar.addAction(self.reload) # Update current usb devices connected to PC def update_devices_list(self): device_list = serial.tools.list_ports.comports() current_arduino = self.arduino_combobox.currentText() self.arduino_combobox.clear() for device_index, device in enumerate(sorted(device_list)): self.arduino_combobox.addItem(device.device) if device.device == current_arduino: self.arduino_combobox.setCurrentIndex(device_index) # Stop current arduino task def stop_all(self): if str(self.arduino_combobox.currentText()): self.thread_connection = Arduino_Communication( str(self.arduino_combobox.currentText())) self.thread_connection.start() self.action_Ejecutar.setEnabled(False) self.action_Para_Valvulas.setEnabled(False) self.action_Detener_USB.setEnabled(False) self.thread_connection.finished.connect(self.finished_thread) self.thread_connection.connection_exit_status.connect( self.finished_thread) else: messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Advertencia')) messageBox.setText(self.tr("Arduino no seleccionado")) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/usb_error.png')) messageBox.exec_() def open_file(self): try: my_home = os.path.expanduser('~') file_name = QFileDialog.getOpenFileName( self, self.tr('Abrir archivo'), my_home, '*.txt', '*.txt', QFileDialog.DontUseNativeDialog) logging.warning("file_name type: %s" % type(file_name)) list_values = [] if not file_name.isNull(): with open(file_name) as fp: for line in fp: list_values.extend([line.replace('\n', '')]) logging.info("List Content: %s" % list_values) count = 0 for elems in self.lineEdits_list: for inner_elem in elems: if not unicode(list_values[count]).isdigit(): raise Uncompatible_Data() inner_elem.setText(list_values[count]) count = count + 1 self.filename = file_name except (IOError, OSError): messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Error')) messageBox.setText(self.tr('No se pudo abrir el archivo')) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/broken_file.png')) messageBox.exec_() except (IndexError, Uncompatible_Data): messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Error')) messageBox.setText(self.tr('Formato Incompatible')) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/broken_file.png')) messageBox.exec_() # Inform the user if we were able to send data successfully to arduino def finished_thread(self, error=None, message=''): if error == 'error': messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Error')) messageBox.setText(message) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/usb_error.png')) messageBox.exec_() return elif error == 'success': messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr(u'Éxito')) messageBox.setText(message) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/usb_success.png')) messageBox.exec_() return elif error == 'stopped': messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr(u'Éxito')) messageBox.setText(message) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIconPixmap(QPixmap(':/success_general.png')) messageBox.exec_() return self.action_Ejecutar.setEnabled(True) self.action_Para_Valvulas.setEnabled(True) self.action_Detener_USB.setEnabled(True) self.statusBar1.showMessage(self.tr('Finalizado')) # Save data to disk def write_data_to_file(self, open_mode): progressDialog = QProgressDialog() progressDialog.setModal(True) progressDialog.setLabelText(self.tr('Guardando...')) progressDialog.setMaximum(8) progressDialog.setCancelButton(None) progressDialog.show() try: # File is closed automatically even on error with open(unicode(self.filename), open_mode) as file_obj: for count, elem_edit in enumerate(self.lineEdits_list, 1): file_obj.write(''.join([str(elem_edit[0].text()), '\n'])) file_obj.write(''.join([str(elem_edit[1].text()), '\n'])) file_obj.write(''.join([str(elem_edit[2].text()), '\n'])) file_obj.write(''.join([str(elem_edit[3].text()), '\n'])) file_obj.write(''.join([str(elem_edit[4].text()), '\n'])) file_obj.write(''.join([str(elem_edit[5].text()), '\n'])) file_obj.write(''.join([str(elem_edit[6].text()), '\n'])) file_obj.write(''.join([str(elem_edit[7].text()), '\n'])) file_obj.write(''.join([str(elem_edit[8].text()), '\n'])) file_obj.write(''.join([str(elem_edit[9].text()), '\n'])) file_obj.write(''.join([str(elem_edit[10].text()), '\n'])) file_obj.write(''.join([str(elem_edit[11].text()), '\n'])) progressDialog.setValue(count) except (IOError, OSError): progressDialog.close() messageBox = QMessageBox(self) messageBox.setStyleSheet( 'QMessageBox QLabel {font: bold 14pt "Cantarell";}') messageBox.setWindowTitle(self.tr('Error')) messageBox.setText(self.tr('Error al guardar')) messageBox.setStandardButtons(QMessageBox.Ok) messageBox.setIcon(QMessageBox.Critical) messageBox.exec_() else: self.statusBar1.showMessage(self.tr('Guardado'), 3000)
class DocumentViewManager(QMainWindow): """ MDI area for displaying supporting documents within a given context e.g. supporting documents for a specific household based on the lifetime of the 'SourceDocumentManager' instance. """ def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowFlags(Qt.Window) self._mdi_area = QMdiArea() self._mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self._mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setCentralWidget(self._mdi_area) # set the size of mid_area and DocumentViewManager based on the # screen size. screen = QDesktopWidget().availableGeometry() self._mdi_area.resize(screen.width() - 30, screen.height() - 80) self.resize(self._mdi_area.size()) self._mdi_area.subWindowActivated.connect(self.update_actions) self._viewer_mapper = QSignalMapper(self) self._viewer_mapper.mapped[QWidget].connect(self.set_active_sub_window) win_title = QApplication.translate( "DocumentViewManager", "Document Viewer" ) self.setWindowTitle(win_title) self.setUnifiedTitleAndToolBarOnMac(True) self.statusBar().showMessage( QApplication.translate( "DocumentViewManager", "Ready" ) ) self._doc_viewers = {} self._create_menu_actions() self.update_actions() def center(self): """ Move the Document viewer to the center of the screen. """ # Get the current screens' dimensions... screen = QDesktopWidget().availableGeometry() # ... and get this windows' dimensions mdi_area_size = self.frameGeometry() # The horizontal position hpos = (screen.width() - mdi_area_size.width()) / 2 # vertical position vpos = (screen.height() - mdi_area_size.height()) / 2 # repositions the window self.move(hpos, vpos) def _create_menu_actions(self): self._window_menu = self.menuBar().addMenu( QApplication.translate( "DocumentViewManager","&Windows")) self._close_act = QAction( QApplication.translate("DocumentViewManager", "Cl&ose"), self) self._close_act.setStatusTip( QApplication.translate("DocumentViewManager", "Close the active document viewer")) self._close_act.triggered.connect(self._mdi_area.closeActiveSubWindow) self._close_all_act = QAction(QApplication.translate( "DocumentViewManager", "Close &All"), self ) self._close_all_act.setStatusTip( QApplication.translate("DocumentViewManager", "Close all the document viewers") ) self._close_all_act.triggered.connect( self._mdi_area.closeAllSubWindows ) self._tile_act = QAction(QApplication.translate( "DocumentViewManager", "&Tile"), self ) self._tile_act.setStatusTip( QApplication.translate("DocumentViewManager", "Tile the document viewers")) self._tile_act.triggered.connect(self.tile_windows) self._cascade_act = QAction(QApplication.translate( "DocumentViewManager", "&Cascade"), self) self._cascade_act.setStatusTip(QApplication.translate( "DocumentViewManager", "Cascade the document viewers")) self._cascade_act.triggered.connect(self.cascade_windows) self._next_act = QAction(QApplication.translate( "DocumentViewManager", "Ne&xt"), self) self._next_act.setStatusTip( QApplication.translate( "DocumentViewManager", "Move the focus to the next document viewer" ) ) self._next_act.triggered.connect(self._mdi_area.activateNextSubWindow) self._previous_act = QAction(QApplication.translate( "DocumentViewManager", "Pre&vious"), self) self._previous_act.setStatusTip( QApplication.translate( "DocumentViewManager", "Move the focus to the previous document viewer" ) ) self._previous_act.triggered.connect( self._mdi_area.activatePreviousSubWindow ) self._separator_act = QAction(self) self._separator_act.setSeparator(True) self.update_window_menu() self._window_menu.aboutToShow.connect(self.update_window_menu) def cascade_windows(self): #Cascade document windows self._mdi_area.cascadeSubWindows() def tile_windows(self): #Arrange document windows to occupy the available space in mdi area self._mdi_area.tileSubWindows() def update_actions(self): if self._mdi_area.activeSubWindow(): has_mdi_child = True else: has_mdi_child = False self._close_act.setEnabled(has_mdi_child) self._close_all_act.setEnabled(has_mdi_child) self._tile_act.setEnabled(has_mdi_child) self._cascade_act.setEnabled(has_mdi_child) self._previous_act.setEnabled(has_mdi_child) self._next_act.setEnabled(has_mdi_child) self._separator_act.setVisible(has_mdi_child) def update_window_menu(self): self._window_menu.clear() self._window_menu.addAction(self._close_act) self._window_menu.addAction(self._close_all_act) self._window_menu.addSeparator() self._window_menu.addAction(self._tile_act) self._window_menu.addAction(self._cascade_act) self._window_menu.addSeparator() self._window_menu.addAction(self._next_act) self._window_menu.addAction(self._previous_act) self._window_menu.addAction(self._separator_act) windows = self._mdi_area.subWindowList() self._separator_act.setVisible(len(windows) != 0) for i, window in enumerate(windows): text = "%d. %s" % (i + 1, window.windowTitle()) win_action = self._window_menu.addAction(text) win_action.setCheckable(True) win_action.setChecked(window is self._mdi_area.activeSubWindow()) win_action.triggered.connect(self._viewer_mapper.map) self._viewer_mapper.setMapping(win_action, window) def load_viewer(self, document_widget, visible=True): """ Open a new instance of the viewer or activate an existing one if the document had been previously loaded. :param document_widget: Contains all the necessary information required to load the specific document. :type document_widget: DocumentWidget :param visible: True to show the view manager after the viewer has been loaded, otherwise it will be the responsibility of the caller to enable visibility. :type visible: bool :returns: True if the document was successfully loaded, else False. :rtype: bool """ doc_identifier = document_widget.file_identifier() if doc_identifier in self._doc_viewers: doc_sw = self._doc_viewers[doc_identifier] self._mdi_area.setActiveSubWindow(doc_sw) doc_sw.showNormal() else: doc_viewer = self._create_viewer(document_widget) abs_doc_path = self.absolute_document_path(document_widget) if not QFile.exists(abs_doc_path): msg = QApplication.translate( "DocumentViewManager", "The selected document does not exist." "\nPlease check the supporting documents' " "repository setting." ) QMessageBox.critical( self, QApplication.translate( "DocumentViewManager","Invalid Document" ), msg ) return False doc_viewer.load_document(abs_doc_path) self._doc_viewers[doc_identifier] = doc_viewer self._mdi_area.addSubWindow(doc_viewer) doc_viewer.show() if not self.isVisible() and visible: self.setVisible(True) if self.isMinimized(): self.showNormal() self.center() return True def set_active_sub_window(self, viewer): if viewer: self._mdi_area.setActiveSubWindow(viewer) def absolute_document_path(self, document_widget): """ Build the absolute document path using info from the document widget. :param document_widget: Instance of document widget. :return: Absolute path of the supporting document. :rtype: str """ abs_path = '' file_manager = document_widget.fileManager if not file_manager is None: network_repository = file_manager.networkPath file_id = document_widget.file_identifier() source_entity = document_widget.doc_source_entity() profile_name = current_profile().name doc_type = document_widget.doc_type_value().lower().replace( ' ', '_' ) file_name, file_extension = guess_extension( document_widget.displayName() ) abs_path = network_repository + "/" +profile_name + '/' +\ unicode(source_entity) + "/" + unicode(doc_type) + "/" +\ unicode(file_id) + unicode(file_extension) return abs_path def reset(self): """ Removes all document viewers in the view area. The QCloseEvent sent to each sub-window will decrement the register. """ self._mdi_area.closeAllSubWindows() def _create_viewer(self, document_widget): """ Creates a new instance of a document viewer. :param document_widget: Contains all the necessary information required to load the specific document. :return: Document viewer object :rtype: DocumentViewer """ doc_viewer = DocumentViewer( self._mdi_area, document_widget.file_identifier() ) doc_viewer.setAttribute(Qt.WA_DeleteOnClose) doc_viewer.setWindowTitle( document_widget.displayName() ) # TODO: Incorporate logic for determining # TODO: viewer based on document type ph_viewer = PhotoViewer() # v_layout = QVBoxLayout() # v_layout.addWidget(ph_viewer) # doc_viewer.setLayout(v_layout) doc_viewer.set_view_widget(ph_viewer) doc_viewer.closed.connect(self._on_viewer_closed) return doc_viewer def remove_viewer(self, viewer_id): """ Close and remove the viewer with the specified viewer ID. """ if viewer_id in self._doc_viewers: viewer = self._doc_viewers[viewer_id] self._mdi_area.setActiveSubWindow(viewer) self._mdi_area.closeActiveSubWindow() self._on_viewer_closed(viewer_id) def _on_viewer_closed(self,file_id): """ Slot raised when a document viewer is closed. """ if file_id in self._doc_viewers: del self._doc_viewers[file_id]
class CaseSelectionWidget(QWidget): caseSelectionChanged = pyqtSignal() def __init__(self, current_case): QWidget.__init__(self) self.__model = PlotCaseModel() self.__signal_mapper = QSignalMapper(self) self.__case_selectors = {} self.__case_selectors_order = [] layout = QVBoxLayout() add_button_layout = QHBoxLayout() button = QPushButton(util.resourceIcon("ide/small/add"), "Add case to plot") button.clicked.connect(self.addCaseSelector) add_button_layout.addStretch() add_button_layout.addWidget(button) add_button_layout.addStretch() layout.addLayout(add_button_layout) self.__case_layout = QVBoxLayout() self.__case_layout.setMargin(0) layout.addLayout(self.__case_layout) self.addCaseSelector(disabled=True, current_case=current_case) layout.addStretch() self.setLayout(layout) self.__signal_mapper.mapped[QWidget].connect(self.removeWidget) def __caseName(self, widget): """ @rtype: str """ return str(self.__case_selectors[widget].currentText()) def getPlotCaseNames(self): if self.__model.rowCount() == 0: return [] return [self.__caseName(widget) for widget in self.__case_selectors_order] def addCaseSelector(self, disabled=False, current_case=None): if len(self.__case_selectors_order) == 5: return widget = QWidget() layout = QHBoxLayout() layout.setMargin(0) widget.setLayout(layout) combo = QComboBox() combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon) combo.setMinimumContentsLength(20) combo.setModel(self.__model) if current_case is not None: index = 0 for item in self.__model: if item == current_case: combo.setCurrentIndex(index) break index += 1 combo.currentIndexChanged.connect(self.caseSelectionChanged.emit) layout.addWidget(combo, 1) button = QToolButton() button.setAutoRaise(True) button.setDisabled(disabled) button.setIcon(util.resourceIcon("ide/small/delete")) button.clicked.connect(self.__signal_mapper.map) layout.addWidget(button) self.__case_selectors[widget] = combo self.__case_selectors_order.append(widget) self.__signal_mapper.setMapping(button, widget) self.__case_layout.addWidget(widget) self.caseSelectionChanged.emit() def removeWidget(self, widget): self.__case_layout.removeWidget(widget) del self.__case_selectors[widget] self.__case_selectors_order.remove(widget) widget.setParent(None) self.caseSelectionChanged.emit()
def _create_connections(self): """ Creates connections in MainWindow """ # TODO rewrite the connection to a modern style # Menu: File self.connect(self.ui.actionQuit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()')) self.connect(self.ui.actionOpen, QtCore.SIGNAL('triggered()'), self._open_file) self.connect(self.ui.actionOpen_folder, QtCore.SIGNAL('triggered()'), self._open_folder_dialog) # Menu: TOOLS self.connect(self.ui.actionConvert_files, QtCore.SIGNAL('triggered()'), self._show_convert_files) self.connect(self.ui.actionDownload_CTU_UHB_data, QtCore.SIGNAL('triggered()'), self._show_download_db) self.connect(self.ui.actionAttribute_selection, QtCore.SIGNAL('triggered()'), self._show_attribute_selection) self.connect(self.ui.actionExport_to_PDF, QtCore.SIGNAL('triggered()'), self._export_to_pdf) # self.connect(self.ui.actionSet_Clear_Baseline, QtCore.SIGNAL('triggered()'), self._show_set_clear_bsln) self.connect(self.ui.actionSent_annotations, QtCore.SIGNAL('triggered()'), self._show_sent_annotations) group_paper = QtGui.QActionGroup(self) self.ui.actionEU.setActionGroup(group_paper) self.ui.actionUS.setActionGroup(group_paper) self.connect(self.ui.actionEU, QtCore.SIGNAL('triggered()'), self._set_paper) self.connect(self.ui.actionUS, QtCore.SIGNAL('triggered()'), self._set_paper) ''' create dictionary in the following format: action: name ''' e = EnumAnnType pui = self.ui dactions = { pui.actionCursor: e.select, pui.actionBasal: e.basal, pui.actionBaseline: e.baseline, pui.actionRecovery: e.recovery, pui.actionNo_recovery: e.no_recovery, pui.actionExcessive_UA: e.excessive_ua, pui.actionEllipse: e.ellipse, pui.actionEllipseNote: e.ellipsenote, pui.actionNote: e.note, pui.actionEvaluationNote: e.evaluation_note } if DEBUG_FIGO_ANN: dactions[pui.actionFloating_Baseline] = e.floating_baseline dactions[pui.actionAcceleration] = e.acceleration dactions[pui.actionDeceleration] = e.deceleration dactions[pui.actionUA] = e.uterine_contraction group_ann = QtGui.QActionGroup(self) for action in dactions.iterkeys(): if isinstance(action, QtGui.QAction): # just to check the type action.setActionGroup(group_ann) # self.ui.actionBasal.triggered.connect(self._debug_slot) # self.ui.actionBaseline.triggered.connect(self._set_annotation_action) signal_mapper = QSignalMapper(self) # signal_mapper.setMapping(self.ui.actionBaseline, 'baseline') # self.connect(self.ui.actionBaseline, QtCore.SIGNAL('triggered()'), signal_mapper.map) # self.connect(signal_mapper, QtCore.SIGNAL('mapped()'), self._set_annotation_action) # for d in dactions.iteritems(): for action, name in dactions.iteritems(): signal_mapper.setMapping(action, name) if isinstance(action, QtGui.QAction): # just to check the type action.triggered.connect(signal_mapper.map) # self.connect(action, QtCore.SIGNAL('triggered()'), signal_mapper.map) signal_mapper.mapped[QtCore.QString].connect(self._ann_set_action) # self.connect(self.ui.actionUS, QtCore.SIGNAL('triggered()'), self._set_paper) # self.connect(signal_mapper, QtCore.SIGNAL('mapped()'), self._set_annotation_action) # signal_mapper = QtCore.QSignalMapper(self) # # # for d in dactions.iteritems(): # for action, name in dactions.iteritems(): # signal_mapper.setMapping(action, name) # # if isinstance(action, QtGui.QAction): # just to check the type # # action.triggered.connect(signal_mapper.map) # self.connect(action, QtCore.SIGNAL('triggered()'), signal_mapper.map) # # # signal_mapper.mapped[QtCore.QString].connect(self._set_annotation_action) # # self.connect(self.ui.actionUS, QtCore.SIGNAL('triggered()'), self._set_paper) # self.connect(signal_mapper, QtCore.SIGNAL('mapped()'), self._set_annotation_action) # self.ui.actionAnnShowHide.triggered.connect(self._show_ann_show_hide) self.connect(self.ui.actionSave, QtCore.SIGNAL('triggered()'), self._toolbar_ann_save) self.connect(self.ui.actionDelete, QtCore.SIGNAL('triggered()'), self._toolbar_ann_delete) self.ui.actionCaliper.triggered.connect(self._caliper_set) self.ui.actionCaliperFHR.triggered.connect(self._caliper_set) self.ui.actionCaliperTOCO.triggered.connect(self._caliper_set) self.ui.actionFIGO_acc_dec.triggered.connect( self._caliper_set_figo_acc_dec) self.ui.actionFIGO_UA.triggered.connect(self._caliper_set_figo_ua) self.ui.actionCaliperReset.triggered.connect(self._caliper_reset) # Menu: View self.connect(self.ui.actionClinical_information, QtCore.SIGNAL('triggered()'), self._dock_clin_info_toggle) self.connect(self.ui.dockClinInfo, QtCore.SIGNAL("visibilityChanged(bool)"), self._dock_clin_info_visibility) self.connect(self.ui.actionData_browser, QtCore.SIGNAL('triggered()'), self._dock_databrowse_toggle) self.connect(self.ui.dockDataBrowser, QtCore.SIGNAL("visibilityChanged(bool)"), self._dock_databrowse_visibility) self.connect(self.ui.actionAnnToolbarVisible, QtCore.SIGNAL('triggered()'), self._toolbar_ann_toggle) self.connect(self.ui.toolBar, QtCore.SIGNAL('visibilityChanged(bool)'), self._toolbar_ann_visibility) self.connect(self.ui.actionAnnToolbarAlign_right, QtCore.SIGNAL('triggered()'), self._toolbar_align) # Menu: Help self.connect(self.ui.actionAbout, QtCore.SIGNAL('triggered()'), self._show_about) # SIGNALS self.ui.PlotWidget.fhrPlot.signal_ann_changed.connect( self._toolbar_ann_changed) self.ui.PlotWidget.tocoPlot.signal_ann_changed.connect( self._toolbar_ann_changed) self._attSelectForm.signal_sel_att_changed.connect( self._update_data_browser) if DEBUG_TOOLS is True: self.ui.actionDebug_CalibSignal.triggered.connect( self.plot_calibration_signal) if self._dataBrowserWidget.bDebugStageIICorrect: self._dataBrowserWidget.debug_stageI_signal.connect( self.debug_plot_stage1)
class ImportData(QWizard, Ui_frmImport): def __init__(self,parent=None): QWizard.__init__(self,parent) self.setupUi(self) self.curr_profile = current_profile() #Connect signals self.btnBrowseSource.clicked.connect(self.setSourceFile) self.lstDestTables.itemClicked.connect(self.destSelectChanged) self.btnSrcUp.clicked.connect(self.srcItemUp) self.btnSrcDown.clicked.connect(self.srcItemDown) self.btnSrcAll.clicked.connect(self.checkSrcItems) self.btnSrcNone.clicked.connect(self.uncheckSrcItems) self.btnDestUp.clicked.connect(self.targetItemUp) self.btnDestDown.clicked.connect(self.targetItemDown) self.lstSrcFields.currentRowChanged[int].connect(self.sourceRowChanged) self.lstTargetFields.currentRowChanged[int].connect(self.destRowChanged) self.lstTargetFields.currentRowChanged[int].connect(self._enable_disable_trans_tools) self.chk_virtual.toggled.connect(self._on_load_virtual_columns) #Data Reader self.dataReader = None #Init self.registerFields() #Geometry columns self.geomcols = [] #Initialize value translators from definitions self._init_translators() #self._set_target_fields_stylesheet() def _init_translators(self): translator_menu = QMenu(self) self._trans_widget_mgr = TranslatorWidgetManager(self) self._trans_signal_mapper = QSignalMapper(self) for trans_name, config in ValueTranslatorConfig.translators.iteritems(): trans_action = QAction( u'{}...'.format(trans_name), translator_menu ) self._trans_signal_mapper.setMapping(trans_action, trans_name) trans_action.triggered.connect(self._trans_signal_mapper.map) translator_menu.addAction(trans_action) if len(translator_menu.actions()) == 0: self.btn_add_translator.setEnabled(False) else: self.btn_add_translator.setMenu(translator_menu) self._trans_signal_mapper.mapped[str].connect(self._load_translator_dialog) self.btn_edit_translator.setEnabled(False) self.btn_delete_translator.setEnabled(False) self.btn_edit_translator.clicked.connect(self._on_edit_translator) self.btn_delete_translator.clicked.connect(self._on_delete_translator) def _load_translator_dialog(self, config_key): """ Load translator dialog. """ dest_column = self._selected_destination_column() src_column = self._selected_source_column() if dest_column: #Check if there is an existing dialog in the manager trans_dlg = self._trans_widget_mgr.translator_widget(dest_column) if trans_dlg is None: trans_config = ValueTranslatorConfig.translators.get(config_key, None) #Safety precaution if trans_config is None: return try: trans_dlg = trans_config.create( self, self._source_columns(), self.targetTab, dest_column, src_column ) except RuntimeError as re: QMessageBox.critical( self, QApplication.translate( 'ImportData', 'Value Translator' ), unicode(re) ) return self._handle_translator_dlg(dest_column, trans_dlg) def _handle_translator_dlg(self, key, dlg): if dlg.exec_() == QDialog.Accepted: self._trans_widget_mgr.add_widget(key, dlg) self._enable_disable_trans_tools() def _on_edit_translator(self): """ Slot to load the translator widget specific for the selected column for editing. """ dest_column = self._selected_destination_column() if dest_column: #Check if there is an existing dialog in the manager trans_dlg = self._trans_widget_mgr.translator_widget(dest_column) self._handle_translator_dlg(dest_column, trans_dlg) def _on_delete_translator(self): """ Slot for deleting the translator widget for the selected column. """ dest_column = self._selected_destination_column() self._delete_translator(dest_column) def _delete_translator(self, destination_column): if not destination_column: return res = self._trans_widget_mgr.remove_translator_widget(destination_column) self._enable_disable_trans_tools() def _enable_disable_trans_tools(self, index=-1): """ Enable/disable appropriate value translator tools based on the selected column. """ dest_column = self._selected_destination_column() if dest_column: #Check if there is an existing dialog in the manager trans_dlg = self._trans_widget_mgr.translator_widget(dest_column) if trans_dlg is None: self.btn_add_translator.setEnabled(True) self.btn_edit_translator.setEnabled(False) self.btn_delete_translator.setEnabled(False) else: self.btn_add_translator.setEnabled(False) self.btn_edit_translator.setEnabled(True) self.btn_delete_translator.setEnabled(True) else: self.btn_add_translator.setEnabled(False) self.btn_edit_translator.setEnabled(False) self.btn_delete_translator.setEnabled(False) def _selected_destination_column(self): dest_field_item = self.lstTargetFields.currentItem() if dest_field_item is None: return "" else: return dest_field_item.text() def _selected_source_column(self): src_field_item = self.lstSrcFields.currentItem() if src_field_item is None: return "" else: return src_field_item.text() def _set_target_fields_stylesheet(self): self.lstTargetFields.setStyleSheet("QListWidget#lstTargetFields::item:selected" " { selection-background-color: darkblue }") def registerFields(self): #Register wizard fields pgSource = self.page(0) pgSource.registerField("srcFile*",self.txtDataSource) pgSource.registerField("typeText",self.rbTextType) pgSource.registerField("typeSpatial",self.rbSpType) #Destination table configuration destConf = self.page(1) destConf.registerField("optAppend",self.rbAppend) destConf.registerField("optOverwrite",self.rbOverwrite) destConf.registerField("tabIndex*",self.lstDestTables) destConf.registerField("geomCol",self.geomClm,"currentText",SIGNAL("currentIndexChanged(int)")) def initializePage(self,pageid): #Re-implementation of wizard page initialization if pageid == 1: #Reference to checked listwidget item representing table name self.destCheckedItem=None self.geomClm.clear() if self.field("typeText"): self.loadTables("textual") self.geomClm.setEnabled(False) elif self.field("typeSpatial"): self.loadTables("spatial") self.geomClm.setEnabled(True) if pageid == 2: self.lstSrcFields.clear() self.lstTargetFields.clear() self.assignCols() self._enable_disable_trans_tools() def _source_columns(self): return self.dataReader.getFields() def assignCols(self): #Load source and target columns respectively srcCols = self._source_columns() for c in srcCols: srcItem = QListWidgetItem(c,self.lstSrcFields) srcItem.setCheckState(Qt.Unchecked) srcItem.setIcon(QIcon(":/plugins/stdm/images/icons/column.png")) self.lstSrcFields.addItem(srcItem) #Destination Columns tabIndex = int(self.field("tabIndex")) self.targetTab = self.destCheckedItem.text() targetCols = table_column_names(self.targetTab, False, True) #Remove geometry columns in the target columns list for gc in self.geomcols: colIndex = getIndex(targetCols,gc) if colIndex != -1: targetCols.remove(gc) #Remove 'id' column if there id_idx = getIndex(targetCols, 'id') if id_idx != -1: targetCols.remove('id') self._add_target_table_columns(targetCols) def _add_target_table_columns(self, items, style=False): for item in items: list_item = QListWidgetItem(item) if style: color = QColor(0, 128, 255) list_item.setTextColor(color) self.lstTargetFields.addItem(list_item) def _on_load_virtual_columns(self, state): """ Load/unload relationships in the list of destination table columns. """ virtual_columns = self.dataReader.entity_virtual_columns(self.targetTab) if state: if len(virtual_columns) == 0: msg = QApplication.translate("ImportData", "There are no virtual columns for the specified table.") QMessageBox.warning( self, QApplication.translate( 'ImportData', 'Import Data' ), msg ) self.chk_virtual.setChecked(False) return self._add_target_table_columns(virtual_columns, True) else: self._remove_destination_table_fields(virtual_columns) def _remove_destination_table_fields(self, fields): """Remove the specified columns from the destination view.""" for f in fields: list_items = self.lstTargetFields.findItems(f, Qt.MatchFixedString) if len(list_items) > 0: list_item = list_items[0] row = self.lstTargetFields.row(list_item) rem_item = self.lstTargetFields.takeItem(row) del rem_item #Delete translator if already defined for the given column self._delete_translator(f) def loadGeomCols(self, table): #Load geometry columns based on the selected table self.geomcols = table_column_names(table, True, True) self.geomClm.clear() self.geomClm.addItems(self.geomcols) def loadTables(self, type): #Load textual or spatial tables self.lstDestTables.clear() tables = None if type == "textual": tables = profile_user_tables(self.curr_profile, False, True) elif type == "spatial": tables = profile_spatial_tables(self.curr_profile) if tables is not None: for t in tables: tabItem = QListWidgetItem(t,self.lstDestTables) tabItem.setCheckState(Qt.Unchecked) tabItem.setIcon(QIcon(":/plugins/stdm/images/icons/table.png")) self.lstDestTables.addItem(tabItem) def validateCurrentPage(self): #Validate the current page before proceeding to the next one validPage=True if not QFile.exists(unicode(self.field("srcFile"))): self.ErrorInfoMessage("The specified source file does not exist.") validPage = False else: if self.dataReader: self.dataReader.reset() self.dataReader = OGRReader(unicode(self.field("srcFile"))) if not self.dataReader.isValid(): self.ErrorInfoMessage("The source file could not be opened." "\nPlease check is the given file type " "is supported") validPage = False if self.currentId()==1: if self.destCheckedItem == None: self.ErrorInfoMessage("Please select the destination table.") validPage = False if self.currentId()==2: validPage = self.execImport() return validPage def setSourceFile(self): #Set the file path to the source file imageFilters = "Comma Separated Value (*.csv);;ESRI Shapefile (*.shp);;AutoCAD DXF (*.dxf)" sourceFile = QFileDialog.getOpenFileName(self,"Select Source File",vectorFileDir(),imageFilters) if sourceFile != "": self.txtDataSource.setText(sourceFile) def getSrcDestPairs(self): #Return the matched source and destination columns srcDest = {} for l in range(self.lstTargetFields.count()): if l < self.lstSrcFields.count(): srcItem = self.lstSrcFields.item(l) if srcItem.checkState() == Qt.Checked: destItem = self.lstTargetFields.item(l) srcDest[srcItem.text()] = destItem.text() return srcDest def execImport(self): #Initiate the import process success = False matchCols = self.getSrcDestPairs() #Specify geometry column geom_column=None if self.field("typeSpatial"): geom_column = self.field("geomCol") # Ensure that user has selected at least one column if it is a # non-spatial table if len(matchCols) == 0: self.ErrorInfoMessage("Please select at least one source column.") return success value_translator_manager = self._trans_widget_mgr.translator_manager() # try: if self.field("optOverwrite"): entity = self.curr_profile.entity_by_name(self.targetTab) dependencies = entity.dependencies() view_dep = dependencies['views'] entity_dep = [e.name for e in entity.children()] entities_dep_str = ', '.join(entity_dep) views_dep_str = ', '.join(view_dep) if len(entity_dep) > 0 or len(view_dep) > 0: del_msg = QApplication.translate( 'ImportData', "Overwriting existing records will permanently \n" "remove records from other tables linked to the \n" "records. The following tables will be affected." "\n{}\n{}" "\nClick Yes to proceed importing or No to cancel.". format(entities_dep_str, views_dep_str) ) del_result = QMessageBox.critical( self, QApplication.translate( "ImportData", "Overwrite Import Data Warning" ), del_msg, QMessageBox.Yes | QMessageBox.No ) if del_result == QMessageBox.Yes: self.dataReader.featToDb( self.targetTab, matchCols, False, self, geom_column, translator_manager=value_translator_manager ) # Update directory info in the registry setVectorFileDir(self.field("srcFile")) self.InfoMessage( "All features have been imported successfully!") else: success = False else: self.dataReader.featToDb( self.targetTab, matchCols, True, self, geom_column, translator_manager=value_translator_manager ) self.InfoMessage( "All features have been imported successfully!" ) #Update directory info in the registry setVectorFileDir(self.field("srcFile")) success = True # except: # self.ErrorInfoMessage(unicode(sys.exc_info()[1])) return success def _clear_dest_table_selections(self, exclude=None): #Clears checked items in destination table list view if exclude is None: exclude = [] for i in range(self.lstDestTables.count()): item = self.lstDestTables.item(i) if item.checkState() == Qt.Checked and not item.text() in exclude: item.setCheckState(Qt.Unchecked) def destSelectChanged(self, item): """ Handler when a list widget item is clicked, clears previous selections """ if not self.destCheckedItem is None: if item.checkState() == Qt.Checked: self.destCheckedItem.setCheckState(Qt.Unchecked) else: self.destCheckedItem = None if item.checkState() == Qt.Checked: self.destCheckedItem = item #Ensure other selected items have been cleared self._clear_dest_table_selections(exclude=[item.text()]) #Load geometry columns if selection is a spatial table if self.field("typeSpatial"): self.loadGeomCols(item.text()) def syncRowSelection(self, srcList, destList): """ Sync the selection of an srcList item to the corresponding one in the destination column list. """ if (srcList.currentRow() + 1) <= destList.count(): destList.setCurrentRow(srcList.currentRow()) def sourceRowChanged(self): #Slot when the source list's current row changes self.syncRowSelection(self.lstSrcFields,self.lstTargetFields) def destRowChanged(self): #Slot when the destination list's current row changes self.syncRowSelection(self.lstTargetFields, self.lstSrcFields) def itemUp(self, listWidget): #Moves the selected item in the list widget one level up curIndex = listWidget.currentRow() curItem = listWidget.takeItem(curIndex) listWidget.insertItem(curIndex - 1, curItem) listWidget.setCurrentRow(curIndex - 1) def itemDown(self, listWidget): #Moves the selected item in the list widget one level down curIndex=listWidget.currentRow() curItem=listWidget.takeItem(curIndex) listWidget.insertItem(curIndex + 1,curItem) listWidget.setCurrentRow(curIndex + 1) def checkAllItems(self, listWidget, state): #Checks all items in the list widget for l in range(listWidget.count()): item=listWidget.item(l) if state: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) def checkSrcItems(self): #Slot for checking all source table columns self.checkAllItems(self.lstSrcFields, True) def uncheckSrcItems(self): #Slot for unchecking all source table columns self.checkAllItems(self.lstSrcFields, False) def srcItemUp(self): #Slot for moving source list item up self.itemUp(self.lstSrcFields) def srcItemDown(self): #Slot for moving source list item down self.itemDown(self.lstSrcFields) def targetItemUp(self): #Slot for moving target item up self.itemUp(self.lstTargetFields) def targetItemDown(self): #Slot for moving target item down self.itemDown(self.lstTargetFields) def keyPressEvent(self,e): """ Override method for preventing the dialog from closing itself when the escape key is hit """ if e.key() == Qt.Key_Escape: pass def InfoMessage(self, message): #Information message box msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText(message) msg.exec_() def ErrorInfoMessage(self, message): #Error Message Box msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText(message) msg.exec_() # # def drag_drop_handler(self, event): # if event.source() == self: # rows = set([mi.row() for mi in self.selectedIndexes()]) # targetRow = self.indexAt(event.pos()).row() # rows.discard(targetRow) # rows = sorted(rows) # if not rows: # return # if targetRow == -1: # targetRow = self.rowCount() # for _ in range(len(rows)): # self.insertRow(targetRow) # rowMapping = dict() # Src row to target row. # for idx, row in enumerate(rows): # if row < targetRow: # rowMapping[row] = targetRow + idx # else: # rowMapping[row + len(rows)] = targetRow + idx # colCount = self.columnCount() # for srcRow, tgtRow in sorted(rowMapping.iteritems()): # for col in range(0, colCount): # self.setItem(tgtRow, col, self.takeItem(srcRow, col)) # for row in reversed(sorted(rowMapping.iterkeys())): # self.removeRow(row) # event.accept() # return def drag_move(self, e): e.accept()
def __createToolbarsAndConnect(self): actionGroup = QActionGroup(self) actionGroup.addAction(self.actionImport) actionGroup.addAction(self.actionVyhledavani) actionGroup.addAction(self.actionZpracujZmeny) # QSignalMapper self.signalMapper = QSignalMapper(self) # connect to 'clicked' on all buttons self.connect(self.actionImport, SIGNAL( "triggered()"), self.signalMapper, SLOT("map()")) self.connect(self.actionVyhledavani, SIGNAL( "triggered()"), self.signalMapper, SLOT("map()")) self.connect(self.actionZpracujZmeny, SIGNAL( "triggered()"), self.signalMapper, SLOT("map()")) # setMapping on each button to the QStackedWidget index we'd like to # switch to self.signalMapper.setMapping(self.actionImport, 0) self.signalMapper.setMapping(self.actionVyhledavani, 2) self.signalMapper.setMapping(self.actionZpracujZmeny, 1) # connect mapper to stackedWidget self.connect(self.signalMapper, SIGNAL("mapped(int)"), self.stackedWidget, SLOT("setCurrentIndex(int)")) self.actionImport.trigger() self.connect(self.vfkBrowser, SIGNAL( "switchToPanelImport"), self.switchToImport) self.connect(self.vfkBrowser, SIGNAL( "switchToPanelSearch"), self.switchToSearch) self.connect(self.vfkBrowser, SIGNAL( "switchToPanelChanges"), self.switchToChanges) # Browser toolbar # --------------- self.__mBrowserToolbar = QToolBar(self) self.connect(self.actionBack, SIGNAL( "triggered()"), self.vfkBrowser.goBack) self.connect(self.actionForward, SIGNAL( "triggered()"), self.vfkBrowser.goForth) self.connect(self.actionSelectBudInMap, SIGNAL("triggered()"), self.selectBudInMap) self.connect(self.actionSelectParInMap, SIGNAL("triggered()"), self.selectParInMap) self.connect(self.actionCuzkPage, SIGNAL("triggered()"), self.showOnCuzk) self.connect(self.actionExportLatex, SIGNAL("triggered()"), self.latexExport) self.connect(self.actionExportHtml, SIGNAL("triggered()"), self.htmlExport) self.connect(self.actionShowInfoaboutSelection, SIGNAL( "toggled(bool)"), self.setSelectionChangedConnected) self.connect(self.actionShowHelpPage, SIGNAL( "triggered()"), self.vfkBrowser.showHelpPage) self.loadVfkButton.clicked.connect(self.loadVfkButton_clicked) self.__browseButtons['browseButton_1'] = self.browseButton self.__browseButtons['browseButton_1'].clicked.connect( lambda: self.browseButton_clicked(int('{}'.format(len(self.__vfkLineEdits))))) self.__vfkLineEdits['vfkLineEdit_1'] = self.vfkFileLineEdit bt = QToolButton(self.__mBrowserToolbar) bt.setPopupMode(QToolButton.InstantPopup) bt.setText("Export ") menu = QMenu(bt) menu.addAction(self.actionExportLatex) menu.addAction(self.actionExportHtml) bt.setMenu(menu) # add actions to toolbar icons self.__mBrowserToolbar.addAction(self.actionImport) self.__mBrowserToolbar.addAction(self.actionVyhledavani) self.__mBrowserToolbar.addAction(self.actionZpracujZmeny) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionBack) self.__mBrowserToolbar.addAction(self.actionForward) self.__mBrowserToolbar.addAction(self.actionSelectParInMap) self.__mBrowserToolbar.addAction(self.actionSelectBudInMap) self.__mBrowserToolbar.addAction(self.actionCuzkPage) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionShowInfoaboutSelection) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addWidget(bt) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionShowHelpPage) self.rightWidgetLayout.insertWidget(0, self.__mBrowserToolbar) # connect signals from vfkbrowser when changing history self.connect(self.vfkBrowser, SIGNAL( "currentParIdsChanged"), self.actionSelectParInMap.setEnabled) self.connect(self.vfkBrowser, SIGNAL("currentBudIdsChanged"), self.actionSelectBudInMap.setEnabled) self.connect(self.vfkBrowser, SIGNAL( "historyBefore"), self.actionBack.setEnabled) self.connect(self.vfkBrowser, SIGNAL( "historyAfter"), self.actionForward.setEnabled) self.connect(self.vfkBrowser, SIGNAL( "definitionPointAvailable"), self.actionCuzkPage.setEnabled) # add toolTips self.pb_nextFile.setToolTip(u'Přidej další soubor VFK') self.parCheckBox.setToolTip(u'Načti vrstvu parcel') self.budCheckBox.setToolTip(u'Načti vrstvu budov') # add new VFK file self.pb_nextFile.clicked.connect(self.__addRowToGridLayout) # widget apply changes self.pb_mainDb.clicked.connect( lambda: self.browseDb_clicked('mainDb')) self.pb_amendmentDb.clicked.connect( lambda: self.browseDb_clicked('amendmentDb')) self.pb_exportDb.clicked.connect( lambda: self.browseDb_clicked('exportDb')) self.pb_applyChanges.clicked.connect(self.applyChanges) self.pb_applyChanges.setEnabled(False) self.connect(self.changes_instance, SIGNAL("maxRangeProgressBar"), self.__setRangeProgressBarChanges) self.connect(self.changes_instance, SIGNAL("updateStatus"), self.__updateProgressBarChanges) self.connect(self.changes_instance, SIGNAL("finishedStatus"), self.__changesApplied) self.connect(self.changes_instance, SIGNAL("preprocessingDatabase"), self.__changesPreprocessingDatabase) # connect radio boxes self.rb_file.clicked.connect(self.radioButtonValue) self.rb_directory.clicked.connect(self.radioButtonValue)
def __init__(self, parent=None): super(MainWindow, self).__init__() self._csvFilePath = "" self.serialport = serial.Serial() self.receiver_thread = readerThread(self) self.receiver_thread.setPort(self.serialport) self._localEcho = None self.setupUi(self) self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) font = QtGui.QFont() font.setFamily(EDITOR_FONT) font.setPointSize(10) self.txtEdtOutput.setFont(font) self.txtEdtInput.setFont(font) self.quickSendTable.setFont(font) if UI_FONT is not None: font = QtGui.QFont() font.setFamily(UI_FONT) font.setPointSize(9) self.dockWidget_PortConfig.setFont(font) self.dockWidget_SendHex.setFont(font) self.dockWidget_QuickSend.setFont(font) self.setupFlatUi() self.onEnumPorts() icon = QtGui.QIcon(":/icon.ico") self.setWindowIcon(icon) self.actionAbout.setIcon(icon) icon = QtGui.QIcon(":/qt_logo_16.ico") self.actionAbout_Qt.setIcon(icon) self._viewGroup = QActionGroup(self) self._viewGroup.addAction(self.actionAscii) self._viewGroup.addAction(self.actionHex_lowercase) self._viewGroup.addAction(self.actionHEX_UPPERCASE) self._viewGroup.setExclusive(True) # bind events self.actionOpen_Cmd_File.triggered.connect(self.openCSV) self.actionSave_Log.triggered.connect(self.onSaveLog) self.actionExit.triggered.connect(self.onExit) self.actionOpen.triggered.connect(self.openPort) self.actionClose.triggered.connect(self.closePort) self.actionPort_Config_Panel.triggered.connect(self.onTogglePrtCfgPnl) self.actionQuick_Send_Panel.triggered.connect(self.onToggleQckSndPnl) self.actionSend_Hex_Panel.triggered.connect(self.onToggleHexPnl) self.dockWidget_PortConfig.visibilityChanged.connect( self.onVisiblePrtCfgPnl) self.dockWidget_QuickSend.visibilityChanged.connect( self.onVisibleQckSndPnl) self.dockWidget_SendHex.visibilityChanged.connect(self.onVisibleHexPnl) self.actionLocal_Echo.triggered.connect(self.onLocalEcho) self.actionAlways_On_Top.triggered.connect(self.onAlwaysOnTop) self.actionAscii.triggered.connect(self.onViewChanged) self.actionHex_lowercase.triggered.connect(self.onViewChanged) self.actionHEX_UPPERCASE.triggered.connect(self.onViewChanged) self.actionAbout.triggered.connect(self.onAbout) self.actionAbout_Qt.triggered.connect(self.onAboutQt) self.btnOpen.clicked.connect(self.onOpen) self.btnClear.clicked.connect(self.onClear) self.btnSaveLog.clicked.connect(self.onSaveLog) self.btnEnumPorts.clicked.connect(self.onEnumPorts) self.btnSendHex.clicked.connect(self.sendHex) self.receiver_thread.read.connect(self.receive) self.receiver_thread.exception.connect(self.readerExcept) self._signalMap = QSignalMapper(self) self._signalMap.mapped[int].connect(self.tableClick) # initial action self.actionHEX_UPPERCASE.setChecked(True) self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE) self.initQuickSend() self.restoreLayout() self.moveScreenCenter() self.syncMenu() if self.isMaximized(): self.setMaximizeButton("restore") else: self.setMaximizeButton("maximize") self.LoadSettings()
class MainWindow(QMainWindow, Ui_MainWindow): """docstring for MainWindow.""" def __init__(self, parent=None): super(MainWindow, self).__init__() self._csvFilePath = "" self.serialport = serial.Serial() self.receiver_thread = readerThread(self) self.receiver_thread.setPort(self.serialport) self._localEcho = None self.setupUi(self) self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) font = QtGui.QFont() font.setFamily(EDITOR_FONT) font.setPointSize(10) self.txtEdtOutput.setFont(font) self.txtEdtInput.setFont(font) self.quickSendTable.setFont(font) if UI_FONT is not None: font = QtGui.QFont() font.setFamily(UI_FONT) font.setPointSize(9) self.dockWidget_PortConfig.setFont(font) self.dockWidget_SendHex.setFont(font) self.dockWidget_QuickSend.setFont(font) self.setupFlatUi() self.onEnumPorts() icon = QtGui.QIcon(":/icon.ico") self.setWindowIcon(icon) self.actionAbout.setIcon(icon) icon = QtGui.QIcon(":/qt_logo_16.ico") self.actionAbout_Qt.setIcon(icon) self._viewGroup = QActionGroup(self) self._viewGroup.addAction(self.actionAscii) self._viewGroup.addAction(self.actionHex_lowercase) self._viewGroup.addAction(self.actionHEX_UPPERCASE) self._viewGroup.setExclusive(True) # bind events self.actionOpen_Cmd_File.triggered.connect(self.openCSV) self.actionSave_Log.triggered.connect(self.onSaveLog) self.actionExit.triggered.connect(self.onExit) self.actionOpen.triggered.connect(self.openPort) self.actionClose.triggered.connect(self.closePort) self.actionPort_Config_Panel.triggered.connect(self.onTogglePrtCfgPnl) self.actionQuick_Send_Panel.triggered.connect(self.onToggleQckSndPnl) self.actionSend_Hex_Panel.triggered.connect(self.onToggleHexPnl) self.dockWidget_PortConfig.visibilityChanged.connect( self.onVisiblePrtCfgPnl) self.dockWidget_QuickSend.visibilityChanged.connect( self.onVisibleQckSndPnl) self.dockWidget_SendHex.visibilityChanged.connect(self.onVisibleHexPnl) self.actionLocal_Echo.triggered.connect(self.onLocalEcho) self.actionAlways_On_Top.triggered.connect(self.onAlwaysOnTop) self.actionAscii.triggered.connect(self.onViewChanged) self.actionHex_lowercase.triggered.connect(self.onViewChanged) self.actionHEX_UPPERCASE.triggered.connect(self.onViewChanged) self.actionAbout.triggered.connect(self.onAbout) self.actionAbout_Qt.triggered.connect(self.onAboutQt) self.btnOpen.clicked.connect(self.onOpen) self.btnClear.clicked.connect(self.onClear) self.btnSaveLog.clicked.connect(self.onSaveLog) self.btnEnumPorts.clicked.connect(self.onEnumPorts) self.btnSendHex.clicked.connect(self.sendHex) self.receiver_thread.read.connect(self.receive) self.receiver_thread.exception.connect(self.readerExcept) self._signalMap = QSignalMapper(self) self._signalMap.mapped[int].connect(self.tableClick) # initial action self.actionHEX_UPPERCASE.setChecked(True) self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE) self.initQuickSend() self.restoreLayout() self.moveScreenCenter() self.syncMenu() if self.isMaximized(): self.setMaximizeButton("restore") else: self.setMaximizeButton("maximize") self.LoadSettings() def setupFlatUi(self): self._dragPos = self.pos() self._isDragging = False self.setMouseTracking(True) self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(""" QWidget { background-color:#99d9ea; /*background-image: url(:/background.png);*/ outline: 1px solid #0057ff; } QLabel { color:#202020; font-size:13px; font-family:Century; } QComboBox { color:#202020; font-size:13px; font-family:Century Schoolbook; } QComboBox { border: none; padding: 1px 18px 1px 3px; } QComboBox:editable { background: white; } QComboBox:!editable, QComboBox::drop-down:editable { background: #62c7e0; } QComboBox:!editable:hover, QComboBox::drop-down:editable:hover { background: #c7eaf3; } QComboBox:!editable:pressed, QComboBox::drop-down:editable:pressed { background: #35b6d7; } QComboBox:on { padding-top: 3px; padding-left: 4px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 16px; border: none; } QComboBox::down-arrow { image: url(:/downarrow.png); } QComboBox::down-arrow:on { image: url(:/uparrow.png); } QGroupBox { color:#202020; font-size:12px; font-family:Century Schoolbook; border: 1px solid gray; margin-top: 15px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; left:5px; top:3px; } QCheckBox { color:#202020; spacing: 5px; font-size:12px; font-family:Century Schoolbook; } QScrollBar:horizontal { background-color:#99d9ea; border: none; height: 15px; margin: 0px 20px 0 20px; } QScrollBar::handle:horizontal { background: #61b9e1; min-width: 20px; } QScrollBar::add-line:horizontal { image: url(:/rightarrow.png); border: none; background: #7ecfe4; width: 20px; subcontrol-position: right; subcontrol-origin: margin; } QScrollBar::sub-line:horizontal { image: url(:/leftarrow.png); border: none; background: #7ecfe4; width: 20px; subcontrol-position: left; subcontrol-origin: margin; } QScrollBar:vertical { background-color:#99d9ea; border: none; width: 15px; margin: 20px 0px 20px 0px; } QScrollBar::handle::vertical { background: #61b9e1; min-height: 20px; } QScrollBar::add-line::vertical { image: url(:/downarrow.png); border: none; background: #7ecfe4; height: 20px; subcontrol-position: bottom; subcontrol-origin: margin; } QScrollBar::sub-line::vertical { image: url(:/uparrow.png); border: none; background: #7ecfe4; height: 20px; subcontrol-position: top; subcontrol-origin: margin; } QTableView { background-color: white; /*selection-background-color: #FF92BB;*/ border: 1px solid #eeeeee; color: #2f2f2f; } QTableView::focus { /*border: 1px solid #2a7fff;*/ } QTableView QTableCornerButton::section { border: none; border-right: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; background-color: #8ae6d2; } QTableView QWidget { background-color: white; } QTableView::item:focus { border: 1px red; background-color: transparent; color: #2f2f2f; } QHeaderView::section { border: none; border-right: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; padding-left: 2px; padding-right: 2px; color: #444444; background-color: #8ae6d2; } QTextEdit { background-color:white; color:#2f2f2f; border: 1px solid white; } QTextEdit::focus { border: 1px solid #2a7fff; } QPushButton { background-color:#30a7b8; border:none; color:#ffffff; font-size:14px; font-family:Century Schoolbook; } QPushButton:hover { background-color:#51c0d1; } QPushButton:pressed { background-color:#3a9ecc; } QMenuBar { color: #2f2f2f; } QMenuBar::item { background-color: transparent; margin: 8px 0px 0px 0px; padding: 1px 8px 1px 8px; height: 15px; } QMenuBar::item:selected { background: #51c0d1; } QMenuBar::item:pressed { } QMenu { color: #2f2f2f; } QMenu { margin: 2px; } QMenu::item { padding: 2px 25px 2px 21px; border: 1px solid transparent; } QMenu::item:selected { background: #51c0d1; } QMenu::icon { background: transparent; border: 2px inset transparent; } QDockWidget { font-size:13px; font-family:Century; color: #202020; titlebar-close-icon: none; titlebar-normal-icon: none; } QDockWidget::title { margin: 0; padding: 2px; subcontrol-origin: content; subcontrol-position: right top; text-align: left; background: #67baed; } QDockWidget::float-button { max-width: 12px; max-height: 12px; background-color:transparent; border:none; image: url(:/restore_inactive.png); } QDockWidget::float-button:hover { background-color:#227582; image: url(:/restore_active.png); } QDockWidget::float-button:pressed { padding: 0; background-color:#14464e; image: url(:/restore_active.png); } QDockWidget::close-button { max-width: 12px; max-height: 12px; background-color:transparent; border:none; image: url(:/close_inactive.png); } QDockWidget::close-button:hover { background-color:#ea5e00; image: url(:/close_active.png); } QDockWidget::close-button:pressed { background-color:#994005; image: url(:/close_active.png); padding: 0; } """) self.dockWidgetContents.setStyleSheet(""" QPushButton { min-height:23px; } """) self.dockWidget_QuickSend.setStyleSheet(""" QPushButton { background-color:#27b798; font-family:Consolas; font-size:12px; min-width:46px; } QPushButton:hover { background-color:#3bd5b4; } QPushButton:pressed { background-color:#1d8770; } """) self.dockWidgetContents_2.setStyleSheet(""" QPushButton { min-height:23px; min-width:50px; } """) w = self.frameGeometry().width() self._minBtn = QPushButton(self) self._minBtn.setGeometry(w - 103, 0, 28, 24) self._minBtn.clicked.connect(self.onMinimize) self._minBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/minimize_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/minimize_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/minimize_active.png); } """) self._maxBtn = QPushButton(self) self._maxBtn.setGeometry(w - 74, 0, 28, 24) self._maxBtn.clicked.connect(self.onMaximize) self.setMaximizeButton("maximize") self._closeBtn = QPushButton(self) self._closeBtn.setGeometry(w - 45, 0, 36, 24) self._closeBtn.clicked.connect(self.onExit) self._closeBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/close_inactive.png); } QPushButton:hover { background-color:#ea5e00; image: url(:/close_active.png); } QPushButton:pressed { background-color:#994005; image: url(:/close_active.png); } """) def resizeEvent(self, event): w = event.size().width() self._minBtn.move(w - 103, 0) self._maxBtn.move(w - 74, 0) self._closeBtn.move(w - 45, 0) def onMinimize(self): self.showMinimized() def isMaximized(self): return ((self.windowState() == Qt.WindowMaximized)) def onMaximize(self): if self.isMaximized(): self.showNormal() self.setMaximizeButton("maximize") else: self.showMaximized() self.setMaximizeButton("restore") def setMaximizeButton(self, style): if "maximize" == style: self._maxBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/maximize_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/maximize_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/maximize_active.png); } """) elif "restore" == style: self._maxBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/restore_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/restore_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/restore_active.png); } """) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self._isDragging = True self._dragPos = event.globalPos() - self.pos() event.accept() def mouseMoveEvent(self, event): if event.buttons( ) and Qt.LeftButton and self._isDragging and not self.isMaximized(): self.move(event.globalPos() - self._dragPos) event.accept() def mouseReleaseEvent(self, event): self._isDragging = False event.accept() def SaveSettings(self): root = ET.Element("MyTerm") GUISettings = ET.SubElement(root, "GUISettings") PortCfg = ET.SubElement(GUISettings, "PortConfig") ET.SubElement(PortCfg, "port").text = self.cmbPort.currentText() ET.SubElement(PortCfg, "baudrate").text = self.cmbBaudRate.currentText() ET.SubElement(PortCfg, "databits").text = self.cmbDataBits.currentText() ET.SubElement(PortCfg, "parity").text = self.cmbParity.currentText() ET.SubElement(PortCfg, "stopbits").text = self.cmbStopBits.currentText() ET.SubElement( PortCfg, "rtscts").text = self.chkRTSCTS.isChecked() and "on" or "off" ET.SubElement( PortCfg, "xonxoff").text = self.chkXonXoff.isChecked() and "on" or "off" View = ET.SubElement(GUISettings, "View") ET.SubElement( View, "LocalEcho" ).text = self.actionLocal_Echo.isChecked() and "on" or "off" ET.SubElement( View, "ReceiveView").text = self._viewGroup.checkedAction().text() with open(get_config_path('settings.xml'), 'w') as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write( ET.tostring(root, encoding='utf-8', pretty_print=True).decode("utf-8")) def LoadSettings(self): if os.path.isfile(get_config_path("settings.xml")): with open(get_config_path("settings.xml"), 'r') as f: tree = safeET.parse(f) port = tree.findtext('GUISettings/PortConfig/port', default='') if port != '': self.cmbPort.setCurrentText(port) baudrate = tree.findtext('GUISettings/PortConfig/baudrate', default='38400') if baudrate != '': self.cmbBaudRate.setCurrentText(baudrate) databits = tree.findtext('GUISettings/PortConfig/databits', default='8') id = self.cmbDataBits.findText(databits) if id >= 0: self.cmbDataBits.setCurrentIndex(id) parity = tree.findtext('GUISettings/PortConfig/parity', default='None') id = self.cmbParity.findText(parity) if id >= 0: self.cmbParity.setCurrentIndex(id) stopbits = tree.findtext('GUISettings/PortConfig/stopbits', default='1') id = self.cmbStopBits.findText(stopbits) if id >= 0: self.cmbStopBits.setCurrentIndex(id) rtscts = tree.findtext('GUISettings/PortConfig/rtscts', default='off') if 'on' == rtscts: self.chkRTSCTS.setChecked(True) else: self.chkRTSCTS.setChecked(False) xonxoff = tree.findtext('GUISettings/PortConfig/xonxoff', default='off') if 'on' == xonxoff: self.chkXonXoff.setChecked(True) else: self.chkXonXoff.setChecked(False) LocalEcho = tree.findtext('GUISettings/View/LocalEcho', default='off') if 'on' == LocalEcho: self.actionLocal_Echo.setChecked(True) self._localEcho = True else: self.actionLocal_Echo.setChecked(False) self._localEcho = False ReceiveView = tree.findtext('GUISettings/View/ReceiveView', default='HEX(UPPERCASE)') if 'Ascii' in ReceiveView: self.actionAscii.setChecked(True) elif 'lowercase' in ReceiveView: self.actionHex_lowercase.setChecked(True) elif 'UPPERCASE' in ReceiveView: self.actionHEX_UPPERCASE.setChecked(True) def closeEvent(self, event): self.saveLayout() self.saveCSV() self.SaveSettings() event.accept() def tableClick(self, row): self.sendTableRow(row) def initQuickSend(self): #self.quickSendTable.horizontalHeader().setDefaultSectionSize(40) #self.quickSendTable.horizontalHeader().setMinimumSectionSize(25) self.quickSendTable.setRowCount(50) self.quickSendTable.setColumnCount(20) for row in range(50): item = QPushButton(str("Send")) item.clicked.connect(self._signalMap.map) self._signalMap.setMapping(item, row) self.quickSendTable.setCellWidget(row, 0, item) self.quickSendTable.setRowHeight(row, 20) if os.path.isfile(get_config_path('QckSndBckup.csv')): self.loadCSV(get_config_path('QckSndBckup.csv')) self.quickSendTable.resizeColumnsToContents() def openCSV(self): fileName = QFileDialog.getOpenFileName(self, "Select a file", os.getcwd(), "CSV Files (*.csv)") if fileName: self.loadCSV(fileName, notifyExcept=True) def saveCSV(self): # scan table rows = self.quickSendTable.rowCount() cols = self.quickSendTable.columnCount() tmp_data = [[ self.quickSendTable.item(row, col) is not None and self.quickSendTable.item(row, col).text() or '' for col in range(1, cols) ] for row in range(rows)] data = [] # delete trailing blanks for row in tmp_data: for idx, d in enumerate(row[::-1]): if '' != d: break new_row = row[:len(row) - idx] data.append(new_row) #import pprint #pprint.pprint(data, width=120, compact=True) # write to file with open(get_config_path('QckSndBckup.csv'), 'w') as csvfile: csvwriter = csv.writer(csvfile, delimiter=',', lineterminator='\n') csvwriter.writerows(data) def loadCSV(self, path, notifyExcept=False): data = [] set_rows = 0 set_cols = 0 try: with open(path) as csvfile: csvData = csv.reader(csvfile) for row in csvData: data.append(row) set_rows = set_rows + 1 if len(row) > set_cols: set_cols = len(row) except IOError as e: print("({})".format(e)) if notifyExcept: QMessageBox.critical(self, "Open failed", str(e), QMessageBox.Close) return rows = self.quickSendTable.rowCount() cols = self.quickSendTable.columnCount() # clear table for col in range(cols): for row in range(rows): self.quickSendTable.setItem(row, col, QTableWidgetItem("")) self._csvFilePath = path if (cols - 1) < set_cols: # first colume is used by the "send" buttons. cols = set_cols + 10 self.quickSendTable.setColumnCount(cols) if rows < set_rows: rows = set_rows + 20 self.quickSendTable.setRowCount(rows) for row, rowdat in enumerate(data): if len(rowdat) > 0: for col, cell in enumerate(rowdat, 1): self.quickSendTable.setItem(row, col, QTableWidgetItem(str(cell))) self.quickSendTable.resizeColumnsToContents() #self.quickSendTable.resizeRowsToContents() def sendTableRow(self, row): cols = self.quickSendTable.columnCount() try: data = [ '0' + self.quickSendTable.item(row, col).text() for col in range(1, cols) if self.quickSendTable.item(row, col) is not None and self.quickSendTable.item(row, col).text() is not '' ] except: print("Exception in get table data(row = %d)" % (row + 1)) else: tmp = [d[-2] + d[-1] for d in data if len(d) >= 2] for t in tmp: if not is_hex(t): QMessageBox.critical(self, "Error", "'%s' is not hexadecimal." % (t), QMessageBox.Close) return h = [int(t, 16) for t in tmp] self.transmitHex(h) def sendHex(self): hexStr = self.txtEdtInput.toPlainText() hexStr = ''.join(hexStr.split(" ")) hexarray = [] for i in range(0, len(hexStr), 2): hexarray.append(int(hexStr[i:i + 2], 16)) self.transmitHex(hexarray) def readerExcept(self, e): self.closePort() QMessageBox.critical(self, "Read failed", str(e), QMessageBox.Close) def timestamp(self): return datetime.datetime.now().time().isoformat()[:-3] def receive(self, data): self.appendOutputText("\n%s R<-:%s" % (self.timestamp(), data)) def appendOutputText(self, data, color=Qt.black): # the qEditText's "append" methon will add a unnecessary newline. # self.txtEdtOutput.append(data.decode('utf-8')) tc = self.txtEdtOutput.textColor() self.txtEdtOutput.moveCursor(QtGui.QTextCursor.End) self.txtEdtOutput.setTextColor(QtGui.QColor(color)) self.txtEdtOutput.insertPlainText(data) self.txtEdtOutput.moveCursor(QtGui.QTextCursor.End) self.txtEdtOutput.setTextColor(tc) def transmitHex(self, hexarray): if len(hexarray) > 0: byteArray = bytearray(hexarray) if self.serialport.isOpen(): try: self.serialport.write(byteArray) except serial.SerialException as e: print("Exception in transmitHex(%s)" % repr(hexarray)) QMessageBox.critical(self, "Exception in transmitHex", str(e), QMessageBox.Close) else: # self.txCount += len( b ) # self.frame.statusbar.SetStatusText('Tx:%d' % self.txCount, 2) text = ''.join(['%02X ' % i for i in hexarray]) self.appendOutputText( "\n%s T->:%s" % (self.timestamp(), text), Qt.blue) def GetPort(self): return self.cmbPort.currentText() def GetDataBits(self): s = self.cmbDataBits.currentText() if s == '5': return serial.FIVEBITS elif s == '6': return serial.SIXBITS elif s == '7': return serial.SEVENBITS elif s == '8': return serial.EIGHTBITS def GetParity(self): s = self.cmbParity.currentText() if s == 'None': return serial.PARITY_NONE elif s == 'Even': return serial.PARITY_EVEN elif s == 'Odd': return serial.PARITY_ODD elif s == 'Mark': return serial.PARITY_MARK elif s == 'Space': return serial.PARITY_SPACE def GetStopBits(self): s = self.cmbStopBits.currentText() if s == '1': return serial.STOPBITS_ONE elif s == '1.5': return serial.STOPBITS_ONE_POINT_FIVE elif s == '2': return serial.STOPBITS_TWO def openPort(self): if self.serialport.isOpen(): return _port = self.GetPort() if '' == _port: QMessageBox.information(self, "Invalid parameters", "Port is empty.") return _baudrate = self.cmbBaudRate.currentText() if '' == _baudrate: QMessageBox.information(self, "Invalid parameters", "Baudrate is empty.") return self.serialport.port = _port self.serialport.baudrate = _baudrate self.serialport.bytesize = self.GetDataBits() self.serialport.stopbits = self.GetStopBits() self.serialport.parity = self.GetParity() self.serialport.rtscts = self.chkRTSCTS.isChecked() self.serialport.xonxoff = self.chkXonXoff.isChecked() # self.serialport.timeout = THREAD_TIMEOUT # self.serialport.writeTimeout = SERIAL_WRITE_TIMEOUT try: self.serialport.open() except serial.SerialException as e: QMessageBox.critical(self, "Could not open serial port", str(e), QMessageBox.Close) else: self._start_reader() self.setWindowTitle("%s on %s [%s, %s%s%s%s%s]" % ( appInfo.title, self.serialport.portstr, self.serialport.baudrate, self.serialport.bytesize, self.serialport.parity, self.serialport.stopbits, self.serialport.rtscts and ' RTS/CTS' or '', self.serialport.xonxoff and ' Xon/Xoff' or '', )) pal = self.btnOpen.palette() pal.setColor(QtGui.QPalette.Button, QtGui.QColor(0, 0xff, 0x7f)) self.btnOpen.setAutoFillBackground(True) self.btnOpen.setPalette(pal) self.btnOpen.setText('Close') self.btnOpen.update() def closePort(self): if self.serialport.isOpen(): self._stop_reader() self.serialport.close() self.setWindowTitle(appInfo.title) pal = self.btnOpen.style().standardPalette() self.btnOpen.setAutoFillBackground(True) self.btnOpen.setPalette(pal) self.btnOpen.setText('Open') self.btnOpen.update() def _start_reader(self): """Start reader thread""" self.receiver_thread.start() def _stop_reader(self): """Stop reader thread only, wait for clean exit of thread""" self.receiver_thread.join() def onTogglePrtCfgPnl(self): if self.actionPort_Config_Panel.isChecked(): self.dockWidget_PortConfig.show() else: self.dockWidget_PortConfig.hide() def onToggleQckSndPnl(self): if self.actionQuick_Send_Panel.isChecked(): self.dockWidget_QuickSend.show() else: self.dockWidget_QuickSend.hide() def onToggleHexPnl(self): if self.actionSend_Hex_Panel.isChecked(): self.dockWidget_SendHex.show() else: self.dockWidget_SendHex.hide() def onVisiblePrtCfgPnl(self, visible): self.actionPort_Config_Panel.setChecked(visible) def onVisibleQckSndPnl(self, visible): self.actionQuick_Send_Panel.setChecked(visible) def onVisibleHexPnl(self, visible): self.actionSend_Hex_Panel.setChecked(visible) def onLocalEcho(self): self._localEcho = self.actionLocal_Echo.isChecked() def onAlwaysOnTop(self): if self.actionAlways_On_Top.isChecked(): style = self.windowFlags() self.setWindowFlags(style | Qt.WindowStaysOnTopHint) self.show() else: style = self.windowFlags() self.setWindowFlags(style & ~Qt.WindowStaysOnTopHint) self.show() def onOpen(self): if self.serialport.isOpen(): self.closePort() else: self.openPort() def onClear(self): self.txtEdtOutput.clear() def onSaveLog(self): fileName = QFileDialog.getSaveFileName( self, "Save as", os.getcwd(), "Log files (*.log);;Text files (*.txt);;All files (*.*)") if fileName: import codecs f = codecs.open(fileName, 'w', 'utf-8') f.write(self.txtEdtOutput.toPlainText()) f.close() def moveScreenCenter(self): w = self.frameGeometry().width() h = self.frameGeometry().height() desktop = QDesktopWidget() screenW = desktop.screen().width() screenH = desktop.screen().height() self.setGeometry((screenW - w) / 2, (screenH - h) / 2, w, h) def onEnumPorts(self): for p in enum_ports(): self.cmbPort.addItem(p) # self.cmbPort.update() def onAbout(self): q = QWidget() icon = QtGui.QIcon(":/icon.ico") q.setWindowIcon(icon) QMessageBox.about(q, "About MyTerm", appInfo.aboutme) def onAboutQt(self): QMessageBox.aboutQt(None) def onExit(self): if self.serialport.isOpen(): self.closePort() self.close() def restoreLayout(self): if os.path.isfile(get_config_path("layout.dat")): try: f = open(get_config_path("layout.dat"), 'rb') geometry, state = pickle.load(f) self.restoreGeometry(geometry) self.restoreState(state) except Exception as e: print("Exception on restoreLayout, {}".format(e)) else: try: f = QFile(':/default_layout.dat') f.open(QIODevice.ReadOnly) geometry, state = pickle.loads(f.readAll()) self.restoreGeometry(geometry) self.restoreState(state) except Exception as e: print("Exception on restoreLayout, {}".format(e)) def saveLayout(self): with open(get_config_path("layout.dat"), 'wb') as f: pickle.dump((self.saveGeometry(), self.saveState()), f) def syncMenu(self): self.actionPort_Config_Panel.setChecked( not self.dockWidget_PortConfig.isHidden()) self.actionQuick_Send_Panel.setChecked( not self.dockWidget_QuickSend.isHidden()) self.actionSend_Hex_Panel.setChecked( not self.dockWidget_SendHex.isHidden()) def onViewChanged(self): checked = self._viewGroup.checkedAction() if checked is None: self.actionHEX_UPPERCASE.setChecked(True) self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE) else: if 'Ascii' in checked.text(): self.receiver_thread.setViewMode(VIEWMODE_ASCII) elif 'lowercase' in checked.text(): self.receiver_thread.setViewMode(VIEWMODE_HEX_LOWERCASE) elif 'UPPERCASE' in checked.text(): self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE)
def main(icon_spec): app = QApplication(sys.argv) main_window = QMainWindow() def sigint_handler(*args): main_window.close() signal.signal(signal.SIGINT, sigint_handler) # the timer enables triggering the sigint_handler signal_timer = QTimer() signal_timer.start(100) signal_timer.timeout.connect(lambda: None) tool_bar = QToolBar() main_window.addToolBar(Qt.TopToolBarArea, tool_bar) table_view = QTableView() table_view.setSelectionBehavior(QAbstractItemView.SelectRows) table_view.setSelectionMode(QAbstractItemView.SingleSelection) table_view.setSortingEnabled(True) main_window.setCentralWidget(table_view) proxy_model = QSortFilterProxyModel() proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) proxy_model.setFilterKeyColumn(1) table_view.setModel(proxy_model) proxy_model.layoutChanged.connect(table_view.resizeRowsToContents) item_model = QStandardItemModel() proxy_model.setSourceModel(item_model) # get all icons and their available sizes QIcon.setThemeName("gnome") icons = [] all_sizes = set([]) for context, icon_names in icon_spec: for icon_name in icon_names: icon = QIcon.fromTheme(icon_name) sizes = [] for size in icon.availableSizes(): size = (size.width(), size.height()) sizes.append(size) all_sizes.add(size) sizes.sort() icons.append({ 'context': context, 'icon_name': icon_name, 'icon': icon, 'sizes': sizes, }) all_sizes = list(all_sizes) all_sizes.sort() # input field for filter def filter_changed(value): proxy_model.setFilterRegExp(value) table_view.resizeRowsToContents() filter_line_edit = QLineEdit() filter_line_edit.setMaximumWidth(200) filter_line_edit.setPlaceholderText('Filter name') filter_line_edit.setToolTip( 'Filter name optionally using regular expressions (' + QKeySequence(QKeySequence.Find).toString() + ')') filter_line_edit.textChanged.connect(filter_changed) tool_bar.addWidget(filter_line_edit) # actions to toggle visibility of available sizes/columns def action_toggled(index): column = 2 + index table_view.setColumnHidden(column, not table_view.isColumnHidden(column)) table_view.resizeColumnsToContents() table_view.resizeRowsToContents() signal_mapper = QSignalMapper() for i, size in enumerate(all_sizes): action = QAction('%dx%d' % size, tool_bar) action.setCheckable(True) action.setChecked(True) tool_bar.addAction(action) action.toggled.connect(signal_mapper.map) signal_mapper.setMapping(action, i) # set tool tip and handle key sequence tool_tip = 'Toggle visibility of column' if i < 10: digit = ('%d' % (i + 1))[-1] tool_tip += ' (%s)' % QKeySequence('Ctrl+%s' % digit).toString() action.setToolTip(tool_tip) signal_mapper.mapped.connect(action_toggled) # label columns header_labels = ['context', 'name'] for width, height in all_sizes: header_labels.append('%dx%d' % (width, height)) item_model.setColumnCount(len(header_labels)) item_model.setHorizontalHeaderLabels(header_labels) # fill rows item_model.setRowCount(len(icons)) for row, icon_data in enumerate(icons): # context item = QStandardItem(icon_data['context']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 0, item) # icon name item = QStandardItem(icon_data['icon_name']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 1, item) for index_in_all_sizes, size in enumerate(all_sizes): column = 2 + index_in_all_sizes if size in icon_data['sizes']: # icon as pixmap to keep specific size item = QStandardItem('') pixmap = icon_data['icon'].pixmap(size[0], size[1]) item.setData(pixmap, Qt.DecorationRole) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) else: # single space to be sortable against icons item = QStandardItem(' ') item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) table_view.resizeColumnsToContents() # manually set row heights because resizeRowsToContents is not working properly for row, icon_data in enumerate(icons): if len(icon_data['sizes']) > 0: max_size = icon_data['sizes'][-1] table_view.setRowHeight(row, max_size[1]) # enable focus find (ctrl+f) and toggle columns (ctrl+NUM) def main_window_keyPressEvent(self, event, old_keyPressEvent=QMainWindow.keyPressEvent): if event.matches(QKeySequence.Find): filter_line_edit.setFocus() return if event.modifiers() == Qt.ControlModifier and event.key( ) >= Qt.Key_0 and event.key() <= Qt.Key_9: index = event.key() - Qt.Key_1 if event.key() == Qt.Key_0: index += 10 action = signal_mapper.mapping(index) if action: action.toggle() return old_keyPressEvent(self, event) main_window.keyPressEvent = new.instancemethod(main_window_keyPressEvent, table_view, None) # enable copy (ctrl+c) name of icon to clipboard def table_view_keyPressEvent(self, event, old_keyPressEvent=QTableView.keyPressEvent): if event.matches(QKeySequence.Copy): selection_model = self.selectionModel() if selection_model.hasSelection(): index = selection_model.selectedRows()[0] source_index = self.model().mapToSource(index) item = self.model().sourceModel().item(source_index.row(), 1) icon_name = item.data(Qt.EditRole) app.clipboard().setText(icon_name.toString()) return old_keyPressEvent(self, event) table_view.keyPressEvent = new.instancemethod(table_view_keyPressEvent, table_view, None) print 'Icon Theme: ', QIcon.themeName() print 'Theme Search Paths:' for item in QIcon.themeSearchPaths(): print item main_window.showMaximized() return app.exec_()
class ToolBox(QFrame): """ A tool box widget. """ # Emitted when a tab is toggled. tabToogled = Signal(int, bool) def setExclusive(self, exclusive): """ Set exclusive tabs (only one tab can be open at a time). """ if self.__exclusive != exclusive: self.__exclusive = exclusive self.__tabActionGroup.setExclusive(exclusive) checked = self.__tabActionGroup.checkedAction() if checked is None: # The action group can be out of sync with the actions state # when switching between exclusive states. actions_checked = [ page.action for page in self.__pages if page.action.isChecked() ] if actions_checked: checked = actions_checked[0] # Trigger/toggle remaining open pages if exclusive and checked is not None: for page in self.__pages: if checked != page.action and page.action.isChecked(): page.action.trigger() def exclusive(self): """ Are the tabs in the toolbox exclusive. """ return self.__exclusive exclusive_ = Property(bool, fget=exclusive, fset=setExclusive, designable=True, doc="Exclusive tabs") def __init__(self, parent=None, **kwargs): QFrame.__init__(self, parent, **kwargs) self.__pages = [] self.__tabButtonHeight = -1 self.__tabIconSize = QSize() self.__exclusive = False self.__setupUi() def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) # Scroll area for the contents. self.__scrollArea = \ _ToolBoxScrollArea(self, objectName="toolbox-scroll-area") self.__scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.__scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.__scrollArea.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.__scrollArea.setFrameStyle(QScrollArea.NoFrame) self.__scrollArea.setWidgetResizable(True) # A widget with all of the contents. # The tabs/contents are placed in the layout inside this widget self.__contents = QWidget(self.__scrollArea, objectName="toolbox-contents") # The layout where all the tab/pages are placed self.__contentsLayout = QVBoxLayout() self.__contentsLayout.setContentsMargins(0, 0, 0, 0) self.__contentsLayout.setSizeConstraint(QVBoxLayout.SetMinAndMaxSize) self.__contentsLayout.setSpacing(0) self.__contents.setLayout(self.__contentsLayout) self.__scrollArea.setWidget(self.__contents) layout.addWidget(self.__scrollArea) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding) self.__tabActionGroup = \ QActionGroup(self, objectName="toolbox-tab-action-group") self.__tabActionGroup.setExclusive(self.__exclusive) self.__actionMapper = QSignalMapper(self) self.__actionMapper.mapped[QObject].connect(self.__onTabActionToogled) def setTabButtonHeight(self, height): """ Set the tab button height. """ if self.__tabButtonHeight != height: self.__tabButtonHeight = height for page in self.__pages: page.button.setFixedHeight(height) def tabButtonHeight(self): """ Return the tab button height. """ return self.__tabButtonHeight def setTabIconSize(self, size): """ Set the tab button icon size. """ if self.__tabIconSize != size: self.__tabIconSize = size for page in self.__pages: page.button.setIconSize(size) def tabIconSize(self): """ Return the tab icon size. """ return self.__tabIconSize def tabButton(self, index): """ Return the tab button at `index` """ return self.__pages[index].button def tabAction(self, index): """ Return open/close action for the tab at `index`. """ return self.__pages[index].action def addItem(self, widget, text, icon=None, toolTip=None): """ Append the `widget` in a new tab and return its index. Parameters ---------- widget : :class:`QWidget` A widget to be inserted. The toolbox takes ownership of the widget. text : str Name/title of the new tab. icon : :class:`QIcon`, optional An icon for the tab button. toolTip : str, optional Tool tip for the tab button. """ return self.insertItem(self.count(), widget, text, icon, toolTip) def insertItem(self, index, widget, text, icon=None, toolTip=None): """ Insert the `widget` in a new tab at position `index`. See also -------- ToolBox.addItem """ button = self.createTabButton(widget, text, icon, toolTip) self.__contentsLayout.insertWidget(index * 2, button) self.__contentsLayout.insertWidget(index * 2 + 1, widget) widget.hide() page = _ToolBoxPage(index, widget, button.defaultAction(), button) self.__pages.insert(index, page) for i in range(index + 1, self.count()): self.__pages[i] = self.__pages[i]._replace(index=i) self.__updatePositions() # Show (open) the first tab. if self.count() == 1 and index == 0: page.action.trigger() self.__updateSelected() self.updateGeometry() return index def removeItem(self, index): """ Remove the widget at `index`. .. note:: The widget hidden but is is not deleted. """ self.__contentsLayout.takeAt(2 * index + 1) self.__contentsLayout.takeAt(2 * index) page = self.__pages.pop(index) # Update the page indexes for i in range(index, self.count()): self.__pages[i] = self.__pages[i]._replace(index=i) page.button.deleteLater() # Hide the widget and reparent to self # This follows QToolBox.removeItem page.widget.hide() page.widget.setParent(self) self.__updatePositions() self.__updateSelected() self.updateGeometry() def count(self): """ Return the number of widgets inserted in the toolbox. """ return len(self.__pages) def widget(self, index): """ Return the widget at `index`. """ return self.__pages[index].widget def createTabButton(self, widget, text, icon=None, toolTip=None): """ Create the tab button for `widget`. """ action = QAction(text, self) action.setCheckable(True) if icon: action.setIcon(icon) if toolTip: action.setToolTip(toolTip) self.__tabActionGroup.addAction(action) self.__actionMapper.setMapping(action, action) action.toggled.connect(self.__actionMapper.map) button = ToolBoxTabButton(self, objectName="toolbox-tab-button") button.setDefaultAction(action) button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) if self.__tabIconSize.isValid(): button.setIconSize(self.__tabIconSize) if self.__tabButtonHeight > 0: button.setFixedHeight(self.__tabButtonHeight) return button def ensureWidgetVisible(self, child, xmargin=50, ymargin=50): """ Scroll the contents so child widget instance is visible inside the viewport. """ self.__scrollArea.ensureWidgetVisible(child, xmargin, ymargin) def sizeHint(self): hint = self.__contentsLayout.sizeHint() if self.count(): # Compute max width of hidden widgets also. scroll = self.__scrollArea scroll_w = scroll.verticalScrollBar().sizeHint().width() frame_w = self.frameWidth() * 2 + scroll.frameWidth() * 2 max_w = max([p.widget.sizeHint().width() for p in self.__pages]) hint = QSize( max(max_w, hint.width()) + scroll_w + frame_w, hint.height()) return QSize(200, 200).expandedTo(hint) def __onTabActionToogled(self, action): page = find(self.__pages, action, key=attrgetter("action")) on = action.isChecked() page.widget.setVisible(on) index = page.index if index > 0: # Update the `previous` tab buttons style hints previous = self.__pages[index - 1].button flag = QStyleOptionToolBoxV2.NextIsSelected if on: previous.selected |= flag else: previous.selected &= ~flag previous.update() if index < self.count() - 1: next = self.__pages[index + 1].button flag = QStyleOptionToolBoxV2.PreviousIsSelected if on: next.selected |= flag else: next.selected &= ~flag next.update() self.tabToogled.emit(index, on) self.__contentsLayout.invalidate() def __updateSelected(self): """Update the tab buttons selected style flags. """ if self.count() == 0: return opt = QStyleOptionToolBoxV2 def update(button, next_sel, prev_sel): if next_sel: button.selected |= opt.NextIsSelected else: button.selected &= ~opt.NextIsSelected if prev_sel: button.selected |= opt.PreviousIsSelected else: button.selected &= ~opt.PreviousIsSelected button.update() if self.count() == 1: update(self.__pages[0].button, False, False) elif self.count() >= 2: pages = self.__pages for i in range(1, self.count() - 1): update(pages[i].button, pages[i + 1].action.isChecked(), pages[i - 1].action.isChecked()) def __updatePositions(self): """Update the tab buttons position style flags. """ if self.count() == 0: return elif self.count() == 1: self.__pages[0].button.position = QStyleOptionToolBoxV2.OnlyOneTab else: self.__pages[0].button.position = QStyleOptionToolBoxV2.Beginning self.__pages[-1].button.position = QStyleOptionToolBoxV2.End for p in self.__pages[1:-1]: p.button.position = QStyleOptionToolBoxV2.Middle for p in self.__pages: p.button.update()
class ToolGrid(QFrame): """ A widget containing a grid of actions/buttons. Actions can be added using standard :func:`QWidget.addAction(QAction)` and :func:`QWidget.insertAction(int, QAction)` methods. Parameters ---------- parent : :class:`QWidget` Parent widget. columns : int Number of columns in the grid layout. buttonSize : :class:`QSize`, optional Size of tool buttons in the grid. iconSize : :class:`QSize`, optional Size of icons in the buttons. toolButtonStyle : :class:`Qt.ToolButtonStyle` Tool button style. """ actionTriggered = Signal(QAction) actionHovered = Signal(QAction) def __init__(self, parent=None, columns=4, buttonSize=None, iconSize=None, toolButtonStyle=Qt.ToolButtonTextUnderIcon): QFrame.__init__(self, parent) if buttonSize is not None: buttonSize = QSize(buttonSize) if iconSize is not None: iconSize = QSize(iconSize) self.__columns = columns self.__buttonSize = buttonSize or QSize(50, 50) self.__iconSize = iconSize or QSize(26, 26) self.__toolButtonStyle = toolButtonStyle self.__gridSlots = [] self.__buttonListener = ToolButtonEventListener(self) self.__buttonListener.buttonRightClicked.connect( self.__onButtonRightClick) self.__buttonListener.buttonEnter.connect(self.__onButtonEnter) self.__mapper = QSignalMapper() self.__mapper.mapped[QObject].connect(self.__onClicked) self.__setupUi() def __setupUi(self): layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.setSizeConstraint(QGridLayout.SetFixedSize) self.setLayout(layout) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding) def setButtonSize(self, size): """ Set the button size. """ if self.__buttonSize != size: self.__buttonSize = size for slot in self.__gridSlots: slot.button.setFixedSize(size) def buttonSize(self): """ Return the button size. """ return QSize(self.__buttonSize) def setIconSize(self, size): """ Set the button icon size. """ if self.__iconSize != size: self.__iconSize = size for slot in self.__gridSlots: slot.button.setIconSize(size) def iconSize(self): """ Return the icon size """ return QSize(self.__iconSize) def setToolButtonStyle(self, style): """ Set the tool button style. """ if self.__toolButtonStyle != style: self.__toolButtonStyle = style for slot in self.__gridSlots: slot.button.setToolButtonStyle(style) def toolButtonStyle(self): """ Return the tool button style. """ return self.__toolButtonStyle def setColumnCount(self, columns): """ Set the number of button/action columns. """ if self.__columns != columns: self.__columns = columns self.__relayout() def columns(self): """ Return the number of columns in the grid. """ return self.__columns def clear(self): """ Clear all actions/buttons. """ for slot in reversed(list(self.__gridSlots)): self.removeAction(slot.action) self.__gridSlots = [] def insertAction(self, before, action): """ Insert a new action at the position currently occupied by `before` (can also be an index). Parameters ---------- before : :class:`QAction` or int Position where the `action` should be inserted. action : :class:`QAction` Action to insert """ if isinstance(before, int): actions = list(self.actions()) if len(actions) == 0 or before >= len(actions): # Insert as the first action or the last action. return self.addAction(action) before = actions[before] return QFrame.insertAction(self, before, action) def setActions(self, actions): """ Clear the grid and add `actions`. """ self.clear() for action in actions: self.addAction(action) def buttonForAction(self, action): """ Return the :class:`QToolButton` instance button for `action`. """ actions = [slot.action for slot in self.__gridSlots] index = actions.index(action) return self.__gridSlots[index].button def createButtonForAction(self, action): """ Create and return a :class:`QToolButton` for action. """ button = _ToolGridButton(self) button.setDefaultAction(action) if self.__buttonSize.isValid(): button.setFixedSize(self.__buttonSize) if self.__iconSize.isValid(): button.setIconSize(self.__iconSize) button.setToolButtonStyle(self.__toolButtonStyle) button.setProperty("tool-grid-button", QVariant(True)) return button def count(self): """ Return the number of buttons/actions in the grid. """ return len(self.__gridSlots) def actionEvent(self, event): QFrame.actionEvent(self, event) if event.type() == QEvent.ActionAdded: # Note: the action is already in the self.actions() list. actions = list(self.actions()) index = actions.index(event.action()) self.__insertActionButton(index, event.action()) elif event.type() == QEvent.ActionRemoved: self.__removeActionButton(event.action()) def __insertActionButton(self, index, action): """Create a button for the action and add it to the layout at index. """ self.__shiftGrid(index, 1) button = self.createButtonForAction(action) row = index / self.__columns column = index % self.__columns self.layout().addWidget(button, row, column, Qt.AlignLeft | Qt.AlignTop) self.__gridSlots.insert(index, _ToolGridSlot(button, action, row, column)) self.__mapper.setMapping(button, action) button.clicked.connect(self.__mapper.map) button.installEventFilter(self.__buttonListener) button.installEventFilter(self) def __removeActionButton(self, action): """Remove the button for the action from the layout and delete it. """ actions = [slot.action for slot in self.__gridSlots] index = actions.index(action) slot = self.__gridSlots.pop(index) slot.button.removeEventFilter(self.__buttonListener) slot.button.removeEventFilter(self) self.__mapper.removeMappings(slot.button) self.layout().removeWidget(slot.button) self.__shiftGrid(index + 1, -1) slot.button.deleteLater() def __shiftGrid(self, start, count=1): """Shift all buttons starting at index `start` by `count` cells. """ button_count = self.layout().count() direction = 1 if count >= 0 else -1 if direction == 1: start, end = button_count - 1, start - 1 else: start, end = start, button_count for index in range(start, end, -direction): item = self.layout().itemAtPosition(index / self.__columns, index % self.__columns) if item: button = item.widget() new_index = index + count self.layout().addWidget(button, new_index / self.__columns, new_index % self.__columns, Qt.AlignLeft | Qt.AlignTop) def __relayout(self): """Relayout the buttons. """ for i in reversed(range(self.layout().count())): self.layout().takeAt(i) self.__gridSlots = [ _ToolGridSlot(slot.button, slot.action, i / self.__columns, i % self.__columns) for i, slot in enumerate(self.__gridSlots) ] for slot in self.__gridSlots: self.layout().addWidget(slot.button, slot.row, slot.column, Qt.AlignLeft | Qt.AlignTop) def __indexOf(self, button): """Return the index of button widget. """ buttons = [slot.button for slot in self.__gridSlots] return buttons.index(button) def __onButtonRightClick(self, button): pass def __onButtonEnter(self, button): action = button.defaultAction() self.actionHovered.emit(action) def __onClicked(self, action): self.actionTriggered.emit(action) def paintEvent(self, event): return utils.StyledWidget_paintEvent(self, event) def eventFilter(self, obj, event): etype = event.type() if etype == QEvent.KeyPress and obj.hasFocus(): key = event.key() if key in [Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right]: if self.__focusMove(obj, key): event.accept() return True return QFrame.eventFilter(self, obj, event) def __focusMove(self, focus, key): assert (focus is self.focusWidget()) try: index = self.__indexOf(focus) except IndexError: return False if key == Qt.Key_Down: index += self.__columns elif key == Qt.Key_Up: index -= self.__columns elif key == Qt.Key_Left: index -= 1 elif key == Qt.Key_Right: index += 1 if index >= 0 and index < self.count(): button = self.__gridSlots[index].button button.setFocus(Qt.TabFocusReason) return True else: return False
def __init__(self, parent=None): super(MainWindowStart, self).__init__(parent) # Mappers for connecting buttons and labels self.myMapper = QSignalMapper(self) self.myMapper_StyleSheet = QSignalMapper(self) # Load UI self.setupUi(self) self.regex_edits = QRegExp(r"(^[0]+$|^$)") self._filter = Filter() self.filename = QString() self.edit1_delayh.installEventFilter(self._filter) self.sizeLabel = QLabel() self.sizeLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.statusBar1.addPermanentWidget(self.sizeLabel) self.statusBar1.setSizeGripEnabled(False) self.create_connections() self.assign_shortcuts() self.create_tool_bar() self.update_devices_list() # self.button_stop.clicked.connect(self.stop_all) # List of valve pushbuttons self.valve_list = [ self.valve1, self.valve2, self.valve3, self.valve4, self.valve5, self.valve6, self.valve7, self.valve8 ] # GroupBoxes for grouping labels and buttons on each row, used for applying StyleSheets self.group_boxes = [ self.groupbox1, self.groupbox2, self.groupbox3, self.groupbox4, self.groupbox5, self.groupbox6, self.groupbox7, self.groupbox8 ] # List of lineEdits self.lineEdits_list = [ (self.edit1_delayh, self.edit1_delaym, self.edit1_delays, self.edit1_onh, self.edit1_onm, self.edit1_ons, self.edit1_offh, self.edit1_offm, self.edit1_offs, self.edit1_totalh, self.edit1_totalm, self.edit1_totals), (self.edit2_delayh, self.edit2_delaym, self.edit2_delays, self.edit2_onh, self.edit2_onm, self.edit2_ons, self.edit2_offh, self.edit2_offm, self.edit2_offs, self.edit2_totalh, self.edit2_totalm, self.edit2_totals), (self.edit3_delayh, self.edit3_delaym, self.edit3_delays, self.edit3_onh, self.edit3_onm, self.edit3_ons, self.edit3_offh, self.edit3_offm, self.edit3_offs, self.edit3_totalh, self.edit3_totalm, self.edit3_totals), (self.edit4_delayh, self.edit4_delaym, self.edit4_delays, self.edit4_onh, self.edit4_onm, self.edit4_ons, self.edit4_offh, self.edit4_offm, self.edit4_offs, self.edit4_totalh, self.edit4_totalm, self.edit4_totals), (self.edit5_delayh, self.edit5_delaym, self.edit5_delays, self.edit5_onh, self.edit5_onm, self.edit5_ons, self.edit5_offh, self.edit5_offm, self.edit5_offs, self.edit5_totalh, self.edit5_totalm, self.edit5_totals), (self.edit6_delayh, self.edit6_delaym, self.edit6_delays, self.edit6_onh, self.edit6_onm, self.edit6_ons, self.edit6_offh, self.edit6_offm, self.edit6_offs, self.edit6_totalh, self.edit6_totalm, self.edit6_totals), (self.edit7_delayh, self.edit7_delaym, self.edit7_delays, self.edit7_onh, self.edit7_onm, self.edit7_ons, self.edit7_offh, self.edit7_offm, self.edit7_offs, self.edit7_totalh, self.edit7_totalm, self.edit7_totals), (self.edit8_delayh, self.edit8_delaym, self.edit8_delays, self.edit8_onh, self.edit8_onm, self.edit8_ons, self.edit8_offh, self.edit8_offm, self.edit8_offs, self.edit8_totalh, self.edit8_totalm, self.edit8_totals) ] for index, editLabels in enumerate(self.lineEdits_list, 1): for index2, lineedits in enumerate(editLabels, 0): # Apply mapper (GUIObject, objectIndex) self.myMapper_StyleSheet.setMapping( self.lineEdits_list[index - 1][index2], index - 1) # Connect mapper to signal (self.lineEdits_list[index - 1][index2]).textChanged.connect( self.myMapper_StyleSheet.map) # Set event Filter, for detecting when Focus changes self.lineEdits_list[index - 1][index2].installEventFilter( self._filter) # Set Mappers for buttons (1..8) self.myMapper.setMapping(self.valve_list[index - 1], index) # Connect mapper to signal for detecting clicks on buttons (self.valve_list[index - 1]).clicked.connect(self.myMapper.map) # Connect to signal for enabling labelEdits self.myMapper.mapped['int'].connect(self.enable_fields) # Connect to signal for changing color of groupbox used for visual indication self.myMapper_StyleSheet.mapped['int'].connect(self.valve_color_status)
def contextMenuEvent(self, event): menu = QtGui.QMenu() last_pos = event.pos() cursor = self.cursorForPosition(last_pos) pos = cursor.positionInBlock() line = cursor.blockNumber() word = self.error_at_pos(line, pos) if not word == None: suggestions = self.highlighter.checker.suggest(word[0]) if len(suggestions) > 0: suggestion_mapper = QSignalMapper(self) actions = [] # Generate our suggestions, packing all the data we need to make the replacement. for i, suggestion in enumerate(suggestions): if i == MAX_SUGGESTIONS: break actions.append(QtGui.QAction(suggestion, None)) # We can only send strings with the signal mapper, so pickle our data. data = pickle.dumps((word[0], line, word[1], suggestion)) data = QtCore.QString.fromAscii(data) self.connect(actions[-1], QtCore.SIGNAL("triggered()"), suggestion_mapper, QtCore.SLOT("map()")) suggestion_mapper.setMapping(actions[-1], data) self.connect(suggestion_mapper, QtCore.SIGNAL("mapped(QString)"), self.__replace) menu.addActions(actions) else: action = QtGui.QAction("(No spelling suggestions)", None) action.setDisabled(True) menu.addAction(action) menu.addSeparator() add_mapper = QSignalMapper(self) ignore_mapper = QSignalMapper(self) add_action = QtGui.QAction("Add to Dictionary", None) ignore_action = QtGui.QAction("Ignore All", None) self.connect(add_action, QtCore.SIGNAL("triggered()"), add_mapper, QtCore.SLOT("map()")) add_mapper.setMapping(add_action, word[0]) self.connect(add_mapper, QtCore.SIGNAL("mapped(QString)"), self.__add) self.connect(ignore_action, QtCore.SIGNAL("triggered()"), ignore_mapper, QtCore.SLOT("map()")) ignore_mapper.setMapping(ignore_action, word[0]) self.connect(ignore_mapper, QtCore.SIGNAL("mapped(QString)"), self.__ignore) menu.addAction(add_action) menu.addAction(ignore_action) menu.addSeparator() default_menu = self.createStandardContextMenu() menu.addActions(default_menu.actions()) menu.exec_(event.globalPos())
class K800IRec(QWidget, mfso): def __init__(self): mfso.__init__(self, "K800i-Recover") self.name = "K800i-Recover" self.icon = None self.__disown__() def start(self, args): self.vfs = vfs.vfs() self.dumpnumber = 1 try : self.nor = args['nor'].value() self.nand = args['nand'].value() except IndexError: return try: self.spareSize = args["spare-size"].value() except IndexError: self.spareSize = 16 try: self.pageSize = args["page-size"].value() except IndexError: self.pageSize = 512 self.k800n = Node("k800-base") self.k800n.__disown__() self.boot = SEBootBlock(self.nor, self.pageSize) self.blockSize = self.boot.blockSize self.nandClean = SpareNode(self, self.nand, "nandfs", self.pageSize, self.spareSize, self.k800n) self.norFs = NorFs(self, self.k800n, self.nor, "norfs", self.boot) self.fullFs = FullFs(self, self.k800n, self.norFs, self.nandClean, "fullfs", self.boot) self.gdfs = GDFS(self, self.k800n, self.nor, "gdfs", self.boot) self.firmware = Firmware(self, self.k800n, self.nor, "firmware", self.boot.norfsoffset) self.tables = Tables(self.fullFs, self.blockSize) self.registerTree(self.nand, self.k800n) def createDump(self): text, ok = QInputDialog.getText(self, "Create dump", "dump name:", QLineEdit.Normal, "k800-restore-" + str(self.dumpnumber)) if ok and text != "": if (self.vfs.getnode(self.nand.absolute() + "/" + str(text)) == None): self.dumpnumber += 1 newroot = Node(str(text)) newroot.__disown__() for id in range(0, len(self.tables.tablesIdWriteMap) - 1): write = int(str(self.gtable.cellWidget(id, 0).currentText()), 16) self.tables.map[id] = self.tables.tablesIdWriteMap[id][write] virtual = VirtualMap(self, newroot, self.fullFs, self.tables, "virtual", self.blockSize) separt = SEPartitionBlock(virtual, self.boot.partitionblock, self.blockSize) self.createPart(separt, newroot, virtual) self.registerTree(self.nand, newroot) else : box = QMessageBox(QMessageBox.Warning, "Error", "Error node already exists", QMessageBox.NoButton, self) box.exec_() self.createDump() def createPart(self, separt, newroot, virtual): for part in separt.partTable: if part.start > 0: p = Partition(self, newroot, virtual, part, self.blockSize) def g_display(self): QWidget.__init__(self, None) self.layout = QVBoxLayout(self) self.hlayout = QSplitter(self) self.layout.insertWidget(0, self.hlayout) self.layout.setStretchFactor(self.hlayout, 1) self.gTable() self.viewTable() self.button = QPushButton("&Create dump") self.connect(self.button, SIGNAL("clicked()"), self.createDump) self.layout.addWidget(self.button) def viewTable(self): self.vtable = QTableWidget() self.vtable.setColumnCount(20) self.vtable.setRowCount(48) self.hlayout.addWidget(self.vtable) def viewTableUpdate(self, id): write = int(str(self.gtable.cellWidget(id, 0).currentText()), 16) t = self.tables.tablesIdWriteMap[id][write] l = t.blockList for x in xrange(0, len(t.blockList[0])): block = t.blockList[0][x] c = ((x) % 20) r = ((x) / 20) item = QTableWidgetItem(QString(hex(block))) tipBlock = (id * 960) + x item.setToolTip(QString(hex(tipBlock))) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.vtable.setItem(r ,c, item) def gTable(self): self.gtable = QTableWidget() self.gtable.setColumnCount(1) self.gtable.setRowCount(len(self.tables.tablesIdWriteMap)) self.gtable.setHorizontalHeaderItem(0, QTableWidgetItem(QString("version"))) self.hlayout.addWidget(self.gtable) self.sigMapper = QSignalMapper(self) for id in self.tables.tablesIdWriteMap: wlist = self.tables.tablesIdWriteMap[id] cbox = QComboBox(self.gtable) self.connect(cbox, SIGNAL("activated(QString)"), self.sigMapper, SLOT("map()")) self.sigMapper.setMapping(cbox, id) l = [] for write in wlist: l.append(write) l.sort() l.reverse() for write in l: cbox.addItem(QString(hex(write))) self.gtable.setCellWidget(id, 0, cbox) self.gtable.setVerticalHeaderItem(id, QTableWidgetItem(QString(hex(id)))) self.connect(self.sigMapper, SIGNAL("mapped(int)"), self.viewTableUpdate) self.gtable.setMaximumWidth(self.gtable.columnWidth(0) + self.gtable.verticalHeader().sectionSize(0) + 30) def updateWidget(self): pass
class CaseSelectionWidget(QWidget): caseSelectionChanged = pyqtSignal() def __init__(self, current_case): QWidget.__init__(self) self.__model = PlotCaseModel() self.__signal_mapper = QSignalMapper(self) self.__case_selectors = {} self.__case_selectors_order = [] layout = QVBoxLayout() add_button_layout = QHBoxLayout() self.__add_case_button = QToolButton() self.__add_case_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.__add_case_button.setText("Add case to plot") self.__add_case_button.setIcon(resourceIcon("ide/small/add")) self.__add_case_button.clicked.connect(self.addCaseSelector) add_button_layout.addStretch() add_button_layout.addWidget(self.__add_case_button) add_button_layout.addStretch() layout.addLayout(add_button_layout) self.__case_layout = QVBoxLayout() self.__case_layout.setMargin(0) layout.addLayout(self.__case_layout) self.addCaseSelector(disabled=True, current_case=current_case) layout.addStretch() self.setLayout(layout) self.__signal_mapper.mapped[QWidget].connect(self.removeWidget) def __caseName(self, widget): """ @rtype: str """ return str(self.__case_selectors[widget].currentText()) def getPlotCaseNames(self): if self.__model.rowCount() == 0: return [] return [ self.__caseName(widget) for widget in self.__case_selectors_order ] def checkCaseCount(self): state = True if len(self.__case_selectors_order) == 5: state = False self.__add_case_button.setEnabled(state) def addCaseSelector(self, disabled=False, current_case=None): widget = QWidget() layout = QHBoxLayout() layout.setMargin(0) widget.setLayout(layout) combo = QComboBox() combo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) combo.setMinimumContentsLength(20) combo.setModel(self.__model) if current_case is not None: index = 0 for item in self.__model: if item == current_case: combo.setCurrentIndex(index) break index += 1 combo.currentIndexChanged.connect(self.caseSelectionChanged.emit) layout.addWidget(combo, 1) button = QToolButton() button.setAutoRaise(True) button.setDisabled(disabled) button.setIcon(resourceIcon("ide/small/delete")) button.clicked.connect(self.__signal_mapper.map) layout.addWidget(button) self.__case_selectors[widget] = combo self.__case_selectors_order.append(widget) self.__signal_mapper.setMapping(button, widget) self.__case_layout.addWidget(widget) self.checkCaseCount() self.caseSelectionChanged.emit() def removeWidget(self, widget): self.__case_layout.removeWidget(widget) del self.__case_selectors[widget] self.__case_selectors_order.remove(widget) widget.setParent(None) self.caseSelectionChanged.emit() self.checkCaseCount()