def init_widget(self): self.setWindowTitle("Hello World") form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self) self.setLayout(form_lbx) pgsb = QProgressBar() vscrb = QScrollBar(orientation=Qt.Horizontal) vscrb.setRange(0, 100) vscrb.valueChanged.connect(pgsb.setValue) form_lbx.addWidget(pgsb) form_lbx.addWidget(vscrb)
class ScrollDemo(QWidget): """主窗口""" def __init__(self, parent=None): super().__init__(parent=parent) self.setWindowTitle("QScrollBar 使用") self.label = QLabel("拖动滑块改变颜色") self.scroll_red = QScrollBar() self.scroll_green = QScrollBar() self.scroll_blue = QScrollBar() self.scroll_red.setRange(0, 255) self.scroll_green.setRange(0, 255) self.scroll_blue.setRange(0, 255) self.scroll_red.sliderMoved.connect(self.slider_value) self.scroll_green.sliderMoved.connect(self.slider_value) self.scroll_blue.sliderMoved.connect(self.slider_value) h_layout = QHBoxLayout() h_layout.addWidget(self.label) h_layout.addWidget(self.scroll_red) h_layout.addWidget(self.scroll_green) h_layout.addWidget(self.scroll_blue) self.setLayout(h_layout) def slider_value(self): # print("rgb(%s, %s, %d)" % (self.scroll_red.value(), self.scroll_green.value(), self.scroll_blue.value())) palette = QPalette() color = QColor(self.scroll_red.value(), self.scroll_green.value(), self.scroll_blue.value()) palette.setColor(QPalette.Foreground, color) self.label.setPalette(palette)
class Slider(QWidget): def __init__(self, parent, name): super().__init__(parent) self.name = name self.layout = QHBoxLayout(self) self.setLayout(self.layout) self.slider = QScrollBar(self) self.spin_box = QDoubleSpinBox(self) self.spin_box.setMaximumWidth(70) self.layout.addWidget(self.slider) self.layout.addWidget(self.spin_box) self.slider.setOrientation(QtCore.Qt.Horizontal) self.slider.setPageStep(1) self._slider_mult = 1 self._spin_val = QtPropertyVar(self.spin_box, 'value') self._slider_val = QtPropertyVar(self.slider, 'value') self._var = None self.set_from_value = None self._step = None self._min = None self._max = None self.var = Var(name='var') def _uses_integer(self): return isinstance(self._slider_mult, int) @reactive def _set_all_to(self, value): #print("set all to ", value) if self._min is not None and self._max is not None and self._min > self._max: set_if_inequal(self._var, None) return if self._uses_integer() and value is not None: value = int(round(value)) set_if_inequal(self._slider_val, value * self._slider_mult) set_if_inequal(self._spin_val, value) set_if_inequal(self._var, value) @property def var(self): return self._var @var.setter def var(self, var): with ScopedName(name=self.name): self._var = var if var is not None else Var(name='var') self.set_from_value = volatile(self._set_all_to(self._var)) def set_params(self, min, max, step=1): self._step = step self._min = min self._max = max if isinstance(min, float) or isinstance(max, float) or isinstance( step, float): self._slider_mult = 1.0 / step self.spin_box.setDecimals(int(ceil(-log10(step)))) else: self._slider_mult = 1 self.spin_box.setDecimals(0) self.slider.setRange(int(min * self._slider_mult), int(max * self._slider_mult)) self.slider.setSingleStep(int(step * self._slider_mult)) self.spin_box.setRange(min, max) self.spin_box.setSingleStep(step) with ScopedName(name=self.name): self.refs = [ volatile(self._set_all_to(self._spin_val)), volatile(self._set_all_to(self._slider_val / self._slider_mult)) ] val = unwrap_def(self._var, None) self.fix_value(max, min, val) def fix_value(self, max, min, val): if min > max: new_val = None elif val is None: new_val = min elif val > max: new_val = max elif val < min: new_val = min else: return set_if_inequal(self._var, new_val) def dump_state(self): return dict( # min=self._min, # max=self._max, # step=self._step, value=unwrap(self._var)) def load_state(self, state: dict): # self.set_params(state['min'], state['max'], state['step']) value = state['value'] if self._uses_integer() and value is not None: value = int(round(value)) self._var.set(value)
def bind(source: QScrollBar, target: QScrollBar) -> None: # bind target scroll bar to `source` (range and value). target.setRange(source.minimum(), source.maximum()) target.setValue(source.value()) source.rangeChanged.connect(target.setRange) source.valueChanged.connect(target.setValue)
class PdfDrawWidget(QWidget): horizontalScrollbar = None verticalScrollbar = None pdfVis: Document = None pageNum: int = 0 zoom: float = 1 __controlIsPressed = False __pressStart: Tuple[float, float] = None def __init__(self, parent: QWidget = None, painter: QPainter = QPainter()): super().__init__(parent) self.painter = painter self.horizontalScrollbar = QScrollBar(Qt.Horizontal) self.verticalScrollbar = QScrollBar(Qt.Vertical) self.horizontalScrollbar.setVisible(False) self.verticalScrollbar.setVisible(False) self.horizontalScrollbar.valueChanged.connect(lambda: self.update()) self.verticalScrollbar.valueChanged.connect(lambda: self.update()) self.setMouseTracking(True) def paintEvent(self, event: QPaintEvent): """All Drawing Actions are activated here""" self.__drawPDF(event) __viewchanged = True __zoomed = True __pdfImages: List[Tuple[int, QImage]] = [ ] # List of Tuples where first index is the hightoffset __pageoffsets: List[int] = [] def __drawPDF(self, event: QPaintEvent): """Draws the Pdf centered onto the self Object as long as the self.pdfVis variable isn't None. self.verticalScrollbar & self.horizontalScrollbar will be manipulated in range and visibility""" if self.pdfVis is not None: if self.__viewchanged: if self.__zoomed: hightCount = 0 self.__pageoffsets = [0] for page in self.pdfVis.pages(): hightCount += page.rect.height * self.zoom self.__pageoffsets.append(hightCount) hightCount -= self.height() if self.height() < hightCount: self.verticalScrollbar.setRange(0, hightCount) self.verticalScrollbar.setVisible(True) else: self.verticalScrollbar.setVisible(False) self.verticalScrollbar.setRange(0, 0) mat = fitz.Matrix(self.zoom, self.zoom) self.__pdfImages = [] lowestVisablePage = next( i for i in range(len(self.__pageoffsets) - 1) if self.__pageoffsets[i + 1] >= self.verticalScrollbar.value()) try: highestVisablePage = next( i for i in range(len(self.__pageoffsets) - 1) if self.__pageoffsets[i + 1] >= self.verticalScrollbar.value() + self.height()) + 1 except StopIteration: highestVisablePage = self.pdfVis.pageCount for falseI, page in enumerate( self.pdfVis.pages(lowestVisablePage, highestVisablePage)): i = falseI + lowestVisablePage clipx0 = (page.rect.width * self.zoom / 2 - self.width() / 2 + self.horizontalScrollbar.value()) \ if ( page.rect.width * self.zoom / 2 - self.width() / 2 + self.horizontalScrollbar.value()) > 0 else 0 clipy0 = (self.verticalScrollbar.value() - self.__pageoffsets[i]) / self.zoom \ if self.verticalScrollbar.value() >= self.__pageoffsets[i] else 0 # clipx1 = # clipy1 = print(clipy0, clipx0) # print(self.verticalScrollbar.value()) pix: Pixmap = page.getPixmap(mat) # , clip=Rect(0,0,110,110)) fmt = QImage.Format_RGBA8888 if pix.alpha else QImage.Format_RGB888 self.__pdfImages.append((self.__pageoffsets[i], QImage(pix.samples, pix.width, pix.height, pix.stride, fmt))) if self.__pdfImages[0][1].width() > self.width(): self.horizontalScrollbar.setRange( self.width() - self.__pdfImages[0][1].width(), self.__pdfImages[0][1].width() - self.width()) self.horizontalScrollbar.setVisible(True) else: self.horizontalScrollbar.setVisible(False) self.horizontalScrollbar.setRange(0, 0) self.__viewchanged = False self.painter.begin(self) for i, (y, img) in enumerate(self.__pdfImages): self.painter.drawImage( self.painter.viewport().width() / 2 - img.width() / 2 - self.horizontalScrollbar.value(), y + 5 * i - self.verticalScrollbar.value(), img) self.painter.end() else: pass def resizeEvent(self, QResizeEvent): super().resizeEvent(QResizeEvent) def wheelEvent(self, event: QWheelEvent): if self.__controlIsPressed: if self.zoom + 0.005 * event.angleDelta().y() > 0: self.zoom += 0.005 * event.angleDelta().y() else: self.zoom = 0.1 self.__zoomed = True else: self.verticalScrollbar.setValue(self.verticalScrollbar.value() - event.angleDelta().y()) self.__viewchanged = True self.update() def keyPressEvent(self, event: QKeyEvent): if event.key() == Qt.Key_Control: self.__controlIsPressed = True def keyReleaseEvent(self, event: QKeyEvent): if event.key() == Qt.Key_Control: self.__controlIsPressed = False def mousePressEvent(self, event: QMouseEvent): self.__pressStart = (event.x(), event.y()) def mouseMoveEvent(self, event: QMouseEvent): if self.__pressStart is not None: pass # Todo Draw Rectangle around all Textboxes def loadDocument(self, path: str): self.pdfVis = fitz.Document(path) self.update()
class GraphViewer(QWidget): def __init__(self, parent): super().__init__(parent) self._y = 0 self._width = 1 self._height = 1 self.dot = Digraph(format='svg', strict=True) self._declared_count = 1 self._declared = dict() self._renderer = QSvgRenderer(self.dot.pipe(), self) self.scrollbar = QScrollBar(self.parent()) self.scrollbar.setRange(0, 0) self.parent().wheelEvent = self.wheelEvent def wheelEvent(self, event): if event.x() > self.getScrollWidth(): return if event.y() > self._height: return self.scrollbar.wheelEvent(event) def add(self, data): # is variable if data in self._declared.keys(): return self._declared[data] if data.is_variable: name = data.name self._declared[data] = name self.dot.node(name) if data.toward is not None: toward = self.add(data.toward) self.dot.edge(toward, name) return name # is constant if data.is_constant: name = data.symbol self._declared[data] = name self.dot.node(name) return name # is operator if data.is_operator: name = '[%d] %s' % (self._declared_count, data.name) self._declared_count += 1 self._declared[data] = name self.dot.node(name) args = [data.sub, data.obj, data.step] if data.args is not None: args += data.args args = [arg for arg in args if arg is not None] for arg in args: arg = self.add(arg) self.dot.edge(arg, name) return name def paintEvent(self, event): self._width = self.width() self._height = self.height() self.scrollbar.setGeometry(self.getScrollWidth(), 0, 20, self._height) self.resize(self._renderer.defaultSize()) painter = QPainter(self) painter.restore() drawRect = QRectF(self.rect()) if self.scrollbar.maximum() == 0: draw_y = 0 else: draw_y = drawRect.height() - self._height draw_y *= self.scrollbar.value() / self.scrollbar.maximum() drawRect.setY(-draw_y) drawRect.setHeight(drawRect.y() + drawRect.height()) self._renderer.render(painter, drawRect) def flush(self): self._renderer = QSvgRenderer(self.dot.pipe()) max_h = self._renderer.defaultSize().height() / self._height if max_h <= 1: max_h = 0 max_h = int(self.delta() * max_h) self.scrollbar.setMaximum(max_h) def clear(self): self._declared_count = 1 self._declared = dict() self.dot.clear() def getScrollWidth(self): return self._width - 20 def delta(self): return 3.14
class MyCodeEditor(QWidget): def __init__(self,parent=None): QWidget.__init__(self,parent) self.__editorSettings = EditorSettings() self.__textDocument = PythonTextDocument() self.__splitter = QSplitter(self) # 横纵滚动条 self.__verticalScrollBar = QScrollBar(self) self.__verticalScrollBar.adjustSize() self.__verticalScrollBar.setMinimumWidth(self.__verticalScrollBar.width()) self.__verticalScrollBar.setMaximumWidth(self.__verticalScrollBar.width()) self.__verticalScrollBar.valueChanged.connect(self.__onVScrollValueChanged) self.__editorSettings.startDisLineNumberChangedSignal.connect(self.__verticalScrollBar.setValue) self.__horizontalScrollBar = QScrollBar(QtCore.Qt.Horizontal,self) self.__horizontalScrollBar.adjustSize() self.__horizontalScrollBar.setMinimumHeight(self.__horizontalScrollBar.height()) self.__horizontalScrollBar.setMaximumHeight(self.__horizontalScrollBar.height()) self.__horizontalScrollBar.valueChanged.connect(self.__onHScrollValueChanged) self.__editorSettings.startDisLetterXOffChangedSignal.connect(self.__horizontalScrollBar.setValue) self.__lineNumberWidget = LineNumberWidget(self.__editorSettings,self.__splitter) setattr(self.__lineNumberWidget,'resizeEvent',self.__onLineNumberWidgetSizeChanged) self.__codeTextWidget = CodeTextWidget(self.__textDocument,self.__editorSettings,self.__splitter) self.__codeTextWidget.document().totalLevelTextChangedSignal.connect(self.__onCodeTextChanged) self.__codeTextWidget.settings().lineTextMaxPixelChangedSignal.connect(self.__onLineStrLengthChanged) self.__codeTextWidget.visibleLineYOffInfoChangedSignal.connect( self.__lineNumberWidget.setVisibleLineYOffInfoArray ) self.__splitter.addWidget( self.__lineNumberWidget ) self.__splitter.addWidget( self.__codeTextWidget ) self.__splitter.setCollapsible( 0,False ) self.__splitter.setCollapsible( 1,False ) self.setText = self.__codeTextWidget.setText self.getText = self.__codeTextWidget.getText def __onLineStrLengthChanged(self,newMaxLength): hMax = newMaxLength-1 self.__horizontalScrollBar.setRange(0,hMax) if self.__horizontalScrollBar.value() > hMax: self.__horizontalScrollBar.setValue(hMax) def __onCodeTextChanged(self,*arg1,**arg2): vMax = self.__codeTextWidget.document().getLineCount()-1 self.__verticalScrollBar.setRange(0,vMax) if self.__verticalScrollBar.value() > vMax: self.__verticalScrollBar.setValue(vMax) def __onVScrollValueChanged(self): self.__codeTextWidget.showLineNumberAsTop(self.__verticalScrollBar.value()) def __onHScrollValueChanged(self): self.__codeTextWidget.showLeftXOffAsLeft(self.__horizontalScrollBar.value()) def __onLineNumberWidgetSizeChanged(self,*arg1,**arg2): lineNumberWidgetWidth = self.__lineNumberWidget.width() vScrollBarWidth = self.__verticalScrollBar.width() hScrollBarHeight = self.__horizontalScrollBar.height() self.__horizontalScrollBar.setGeometry(lineNumberWidgetWidth,self.height()-hScrollBarHeight, \ self.width()-vScrollBarWidth-lineNumberWidgetWidth,hScrollBarHeight) def resizeEvent(self, event): vScrollBarWidth = self.__verticalScrollBar.width() hScrollBarHeight = self.__horizontalScrollBar.height() self.__splitter.setGeometry( 0,0,self.width()-vScrollBarWidth,self.height()-hScrollBarHeight ) self.__verticalScrollBar.setGeometry(self.width()-vScrollBarWidth,0,vScrollBarWidth,self.height()-hScrollBarHeight) self.__onLineNumberWidgetSizeChanged() def wheelEvent(self, event): changedV = 3 if event.angleDelta().y() < 0 else -3 self.__verticalScrollBar.setValue( self.__verticalScrollBar.value() + changedV )