def __init__(self, controller, parent=None, state=None): QWidget.__init__(self, parent) # update Request for parameter gets sent to controller self.controller = controller # contains widgets that are currently displayed self.widgets = [] self.state = state if state is not None else self.standard_value self.doubleclick = None # setting up layout: layout = QHBoxLayout() layout.setContentsMargins(0.1, 0.1, 0.1, 0.1) layout.setSpacing(1) self.setLayout(layout)
class BaseDev(QWidget): base_address = 0 has_target = False has_status = False offset = 1 def __init__(self, model, name, index, addr, has_status=False, target=None, value_offset=1): QWidget.__init__(self) self.index = index self.name = name self.model = model self.offset = value_offset self.has_status = has_status self.has_target = target is not None self.base_address = addr self._namelabel = QLabel(name) self._namelabel.setMinimumWidth(120) self._namelabel.setMaximumWidth(120) # self._groupbox = QGroupBox(name) self._groupbox = QFrame() # self._groupbox.setFlat(False) # self._groupbox.setCheckable(False) self._hlayout = QHBoxLayout() self._hlayout.addWidget(self._namelabel) self._hlayout.addWidget(self._groupbox) self._hlayout.setSpacing(0) # inside of the groupbox there is a vbox with 1 or 2 hboxes self._inner_vbox = QVBoxLayout() self._groupbox.setLayout(self._inner_vbox) # upper inner hbox self._inner_hbox1 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox1) # fill upper hbox self.valueWidget = QLineEdit('0b123456789abcdef0') self.valueWidget.setMaximumWidth(120) self._inner_hbox1.addWidget(self.valueWidget) if self.has_target: self.targetWidget = QLineEdit() self.targetWidget.setPlaceholderText(target) self.targetWidget.setMaximumWidth(120) self.targetWidget.returnPressed.connect(lambda *a: model.targeter( index, (self.targetWidget.text(), self.targetWidget.setText(''))[0])) self._inner_hbox1.addWidget(self.targetWidget) self.goButton = QPushButton('Go') self.goButton.clicked.connect(lambda *a: model.targeter( index, (self.targetWidget.text(), self.targetWidget.setText(''))[0])) self._inner_hbox1.addWidget(self.goButton) self.stopButton = QPushButton('Stop') self.stopButton.clicked.connect(lambda *a: model.stopper(index)) self._inner_hbox1.addWidget(self.stopButton) # now (conditionally) the second hbox if has_status: self._inner_hbox2 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox2) self.statvalueWidget = QLineEdit('statval') self.statvalueWidget.setMaximumWidth(120) self._inner_hbox2.addWidget(self.statvalueWidget) self.statusWidget = QLineEdit('Statusstring if available') self.statusWidget.setMaximumWidth(10000) self._inner_hbox2.addWidget(self.statusWidget) self.resetButton = QPushButton('Reset') self.resetButton.clicked.connect(lambda *a: model.resetter(index)) self._inner_hbox1.addWidget(self.resetButton) # self._inner_hbox2.addStretch(0.1) # allow space for resizing self._inner_hbox1.addStretch(1) self._inner_vbox.setSpacing(0) self._inner_vbox.setContentsMargins(0, 0, 0, 0) self._hlayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._hlayout) self.show()
class QRangeSlider(QWidget, Ui_Form): """ The QRangeSlider class implements a horizontal range slider widget. Inherits QWidget. Methods * __init__ (self, QWidget parent = None) * bool drawValues (self) * int end (self) * (int, int) getRange (self) * int max (self) * int min (self) * int start (self) * setBackgroundStyle (self, QString styleSheet) * setDrawValues (self, bool draw) * setEnd (self, int end) * setStart (self, int start) * setRange (self, int start, int end) * setSpanStyle (self, QString styleSheet) Signals * endValueChanged (int) * maxValueChanged (int) * minValueChanged (int) * startValueChanged (int) Customizing QRangeSlider You can style the range slider as below: :: QRangeSlider * { border: 0px; padding: 0px; } QRangeSlider #Head { background: #222; } QRangeSlider #Span { background: #393; } QRangeSlider #Span:active { background: #282; } QRangeSlider #Tail { background: #222; } Styling the range slider handles follows QSplitter options: :: QRangeSlider > QSplitter::handle { background: #393; } QRangeSlider > QSplitter::handle:vertical { height: 4px; } QRangeSlider > QSplitter::handle:pressed { background: #ca5; } """ endValueChanged = pyqtSignal(int) maxValueChanged = pyqtSignal(int) minValueChanged = pyqtSignal(int) startValueChanged = pyqtSignal(int) # define splitter indices _SPLIT_START = 1 _SPLIT_END = 2 # signals minValueChanged = pyqtSignal(int) maxValueChanged = pyqtSignal(int) startValueChanged = pyqtSignal(int) endValueChanged = pyqtSignal(int) def __init__(self, parent=None): """Create a new QRangeSlider instance. :param parent: QWidget parent :return: New QRangeSlider instance. """ super(QRangeSlider, self).__init__(parent) self.setupUi(self) self.setMouseTracking(False) #self._splitter.setChildrenCollapsible(False) self._splitter.splitterMoved.connect(self._handleMoveSplitter) # head layout self._head_layout = QHBoxLayout() self._head_layout.setSpacing(0) self._head_layout.setContentsMargins(0, 0, 0, 0) self._head.setLayout(self._head_layout) self.head = Head(self._head, main=self) self._head_layout.addWidget(self.head) # handle layout self._handle_layout = QHBoxLayout() self._handle_layout.setSpacing(0) self._handle_layout.setContentsMargins(0, 0, 0, 0) self._handle.setLayout(self._handle_layout) self.handle = Handle(self._handle, main=self) self.handle.setTextColor((150, 255, 150)) self._handle_layout.addWidget(self.handle) # tail layout self._tail_layout = QHBoxLayout() self._tail_layout.setSpacing(0) self._tail_layout.setContentsMargins(0, 0, 0, 0) self._tail.setLayout(self._tail_layout) self.tail = Tail(self._tail, main=self) self._tail_layout.addWidget(self.tail) # defaults self.setMin(0) self.setMax(99) self.setStart(0) self.setEnd(99) self.setDrawValues(True) def min(self): """:return: minimum value""" return getattr(self, '__min', None) def max(self): """:return: maximum value""" return getattr(self, '__max', None) def setMin(self, value): """sets minimum value""" assert isinstance(value, int) setattr(self, '__min', value) self.minValueChanged.emit(value) def setMax(self, value): """sets maximum value""" assert isinstance(value, int) setattr(self, '__max', value) self.maxValueChanged.emit(value) def start(self): """:return: range slider start value""" return getattr(self, '__start', None) def end(self): """:return: range slider end value""" return getattr(self, '__end', None) def _setStart(self, value): """stores the start value only""" setattr(self, '__start', value) self.startValueChanged.emit(value) def setStart(self, value): """sets the range slider start value""" assert isinstance(value, int) v = self._valueToPos(value, self._SPLIT_START) self._splitter.splitterMoved.disconnect() self._splitter.moveSplitter(v, self._SPLIT_START) self._splitter.splitterMoved.connect(self._handleMoveSplitter) self._setStart(value) def _setEnd(self, value): """stores the end value only""" setattr(self, '__end', value) self.endValueChanged.emit(value) def setEnd(self, value): """set the range slider end value""" assert isinstance(value, int) v = self._valueToPos(value, self._SPLIT_END) self._splitter.splitterMoved.disconnect() self._splitter.moveSplitter(v, self._SPLIT_END) self._splitter.splitterMoved.connect(self._handleMoveSplitter) self._setEnd(value) def drawValues(self): """:return: True if slider values will be drawn""" return getattr(self, '__drawValues', None) def setDrawValues(self, draw): """sets draw values boolean to draw slider values""" assert isinstance(draw, bool) setattr(self, '__drawValues', draw) def getRange(self): """:return: the start and end values as a tuple""" return (self.start(), self.end()) def setRange(self, start, end): """set the start and end values""" self.setStart(start) self.setEnd(end) def keyPressEvent(self, event): """overrides key press event to move range left and right""" key = event.key() if key == Qt.Key_Left: s = self.start() - 1 e = self.end() - 1 elif key == Qt.Key_Right: s = self.start() + 1 e = self.end() + 1 else: event.ignore() return event.accept() if s >= self.min() and e <= self.max(): self.setRange(s, e) def setBackgroundStyle(self, style): """sets background style""" self._tail.setStyleSheet(style) self._head.setStyleSheet(style) def setSpanStyle(self, style): """sets range span handle style""" self._handle.setStyleSheet(style) def _valueToPos(self, value, index): """converts slider value to local pixel x coord""" left, right = self._splitter.getRange(index) return scale(value, (self.min(), self.max()), (left, right)) def _posToValue(self, xpos, index): """converts local pixel x coord to slider value""" left, right = self._splitter.getRange(index) return scale(xpos, (left, right), (self.min(), self.max())) def _handleMoveSplitter(self, xpos, index): """private method for handling moving splitter handles""" def _lockWidth(widget): width = widget.size().width() widget.setMinimumWidth(width) widget.setMaximumWidth(width) def _unlockWidth(widget): widget.setMinimumWidth(0) widget.setMaximumWidth(16777215) v = self._posToValue(xpos, index) if index == self._SPLIT_START: _lockWidth(self._tail) if v >= self.end(): return self._setStart(v) elif index == self._SPLIT_END: _lockWidth(self._head) if v <= self.start(): return self._setEnd(v) _unlockWidth(self._tail) _unlockWidth(self._head) _unlockWidth(self._handle)
class BaseDev(QWidget): has_target = False has_status = False def __init__(self, model, name, addr): super(BaseDev, self).__init__() self.name = name self.model = model self.addr = addr self._namelabel = QLabel(name) self._namelabel.setMinimumWidth(120) self._namelabel.setMaximumWidth(120) # self._groupbox = QGroupBox(name) self._groupbox = QFrame() # self._groupbox.setFlat(False) # self._groupbox.setCheckable(False) self._hlayout = QHBoxLayout() self._hlayout.addWidget(self._namelabel) self._hlayout.addWidget(self._groupbox) self._hlayout.setSpacing(0) # inside of the groupbox there is a vbox with 1 or 2 hboxes self._inner_vbox = QVBoxLayout() self._groupbox.setLayout(self._inner_vbox) # upper inner hbox self._inner_hbox1 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox1) # fill upper hbox self.valueWidget = QLineEdit('0b123456789abcdef0') self.valueWidget.setMaximumWidth(120) self._inner_hbox1.addWidget(self.valueWidget) if self.has_target: self.targetWidget = QLineEdit() self.targetWidget.setPlaceholderText('') self.targetWidget.setMaximumWidth(120) self.targetWidget.returnPressed.connect(self._go_clicked) self._inner_hbox1.addWidget(self.targetWidget) self.goButton = QPushButton('Go') self.goButton.clicked.connect(self._go_clicked) self._inner_hbox1.addWidget(self.goButton) self.stopButton = QPushButton('Stop') self.stopButton.clicked.connect(self._stop_clicked) self._inner_hbox1.addWidget(self.stopButton) # now (conditionally) the second hbox if self.has_status: self._inner_hbox2 = QHBoxLayout() self._inner_vbox.addLayout(self._inner_hbox2) self.statvalueWidget = QLineEdit('statval') self.statvalueWidget.setMaximumWidth(120) self._inner_hbox2.addWidget(self.statvalueWidget) self.statusWidget = QLineEdit('Statusstring if available') self.statusWidget.setMaximumWidth(10000) self._inner_hbox2.addWidget(self.statusWidget) self.resetButton = QPushButton('Reset') self.resetButton.clicked.connect(self._reset_clicked) self._inner_hbox1.addWidget(self.resetButton) # self._inner_hbox2.addStretch(0.1) # allow space for resizing self._inner_hbox1.addStretch(1) self._inner_vbox.setSpacing(0) self._inner_vbox.setContentsMargins(0, 0, 0, 0) self._hlayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._hlayout) self.show() def _go_clicked(self): self.model.targeter(self.index, self.targetWidget.text()) self.targetWidget.setText('') def _stop_clicked(self): self.model.stopper(self.index) def _reset_clicked(self): self.resetter(self.index) def _update(self): pass def _str2bin(self, value): return int(value) def _bin2str(self, value): return str(value) def _status(self, value): return "no status decoder implemented"