<legend id='aFTEX'><style id='aFTEX'><dir id='aFTEX'><q id='aFTEX'></q></dir></style></legend>

    <small id='aFTEX'></small><noframes id='aFTEX'>

        <bdo id='aFTEX'></bdo><ul id='aFTEX'></ul>
      1. <tfoot id='aFTEX'></tfoot>

      2. <i id='aFTEX'><tr id='aFTEX'><dt id='aFTEX'><q id='aFTEX'><span id='aFTEX'><b id='aFTEX'><form id='aFTEX'><ins id='aFTEX'></ins><ul id='aFTEX'></ul><sub id='aFTEX'></sub></form><legend id='aFTEX'></legend><bdo id='aFTEX'><pre id='aFTEX'><center id='aFTEX'></center></pre></bdo></b><th id='aFTEX'></th></span></q></dt></tr></i><div id='aFTEX'><tfoot id='aFTEX'></tfoot><dl id='aFTEX'><fieldset id='aFTEX'></fieldset></dl></div>

        将范围滑块小部件移植到 PyQt5

        Porting range-slider widget to PyQt5(将范围滑块小部件移植到 PyQt5)

        • <bdo id='Tchir'></bdo><ul id='Tchir'></ul>
          <tfoot id='Tchir'></tfoot>
            1. <small id='Tchir'></small><noframes id='Tchir'>

                <i id='Tchir'><tr id='Tchir'><dt id='Tchir'><q id='Tchir'><span id='Tchir'><b id='Tchir'><form id='Tchir'><ins id='Tchir'></ins><ul id='Tchir'></ul><sub id='Tchir'></sub></form><legend id='Tchir'></legend><bdo id='Tchir'><pre id='Tchir'><center id='Tchir'></center></pre></bdo></b><th id='Tchir'></th></span></q></dt></tr></i><div id='Tchir'><tfoot id='Tchir'></tfoot><dl id='Tchir'><fieldset id='Tchir'></fieldset></dl></div>

                    <tbody id='Tchir'></tbody>
                  <legend id='Tchir'><style id='Tchir'><dir id='Tchir'><q id='Tchir'></q></dir></style></legend>
                  本文介绍了将范围滑块小部件移植到 PyQt5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我目前需要一个范围滑块(一个可以设置最小值和最大值的滑块).我发现了两个相关的问题 Qt 中的范围滑块(两个句柄在一个QSlider) 和 为什么 RangeSlider 在 QtQuick 中可用而不是作为标准 Widget 但它们都不是用 python3 编写的,而且我对 C++ 不是很熟悉.

                  I am currently in need for a range slider (a slider where I can set up a min and a max value). I found two related questions Range slider in Qt (two handles in a QSlider) and Why RangeSlider is available in QtQuick and not as standard Widget but neither of them is written in python3 and I am not very familiar with C++.

                  我找到了这个完美的 github 工具 https://github.com/rsgalloway/qrangeslider 但它不幸的是,它是为 PyQt4 编写的,我正在使用 PyQt5.

                  I found this perfect github tool https://github.com/rsgalloway/qrangeslider but it is unfortunately written for PyQt4 and I am using PyQt5.

                  我打算用 PyQt5 绑定重新格式化这个 github 源,但在这样做之前我想知道是否有人以前做过这样我可以节省时间?或者,如果有人有不同的解决方案,我愿意接受建议.

                  I am planning to reformat this github source with PyQt5 bindings but before doing so I want to know if anyone has done it before so I could save time? Or if anyone has a different solution, I am open to suggestions.

                  推荐答案

                  下面是 QRangeSlider 小部件的 PyQt5 端口.为简洁起见,我删除了所有注释、文档字符串、断言语句等.它似乎在 Python 2 和 Python 3 上都可以正常工作,但我并没有真正对其进行过多测试.

                  Below is a PyQt5 port of the QRangeSlider widget. For the sake of brevity, I have removed all comments, doc-strings, assert statements, etc. It seems to work okay with both Python 2 and Python 3, but I haven't really tested it much.

                  qrangeslider.py:

                  import sys, os
                  from PyQt5 import QtCore, QtGui, QtWidgets
                  
                  __all__ = ['QRangeSlider']
                  
                  DEFAULT_CSS = """
                  QRangeSlider * {
                      border: 0px;
                      padding: 0px;
                  }
                  QRangeSlider #Head {
                      background: #222;
                  }
                  QRangeSlider #Span {
                      background: #393;
                  }
                  QRangeSlider #Span:active {
                      background: #282;
                  }
                  QRangeSlider #Tail {
                      background: #222;
                  }
                  QRangeSlider > QSplitter::handle {
                      background: #393;
                  }
                  QRangeSlider > QSplitter::handle:vertical {
                      height: 4px;
                  }
                  QRangeSlider > QSplitter::handle:pressed {
                      background: #ca5;
                  }
                  """
                  
                  def scale(val, src, dst):
                      return int(((val - src[0]) / float(src[1]-src[0])) * (dst[1]-dst[0]) + dst[0])
                  
                  
                  class Ui_Form(object):
                      def setupUi(self, Form):
                          Form.setObjectName("QRangeSlider")
                          Form.resize(300, 30)
                          Form.setStyleSheet(DEFAULT_CSS)
                          self.gridLayout = QtWidgets.QGridLayout(Form)
                          self.gridLayout.setContentsMargins(0, 0, 0, 0)
                          self.gridLayout.setSpacing(0)
                          self.gridLayout.setObjectName("gridLayout")
                          self._splitter = QtWidgets.QSplitter(Form)
                          self._splitter.setMinimumSize(QtCore.QSize(0, 0))
                          self._splitter.setMaximumSize(QtCore.QSize(16777215, 16777215))
                          self._splitter.setOrientation(QtCore.Qt.Horizontal)
                          self._splitter.setObjectName("splitter")
                          self._head = QtWidgets.QGroupBox(self._splitter)
                          self._head.setTitle("")
                          self._head.setObjectName("Head")
                          self._handle = QtWidgets.QGroupBox(self._splitter)
                          self._handle.setTitle("")
                          self._handle.setObjectName("Span")
                          self._tail = QtWidgets.QGroupBox(self._splitter)
                          self._tail.setTitle("")
                          self._tail.setObjectName("Tail")
                          self.gridLayout.addWidget(self._splitter, 0, 0, 1, 1)
                          self.retranslateUi(Form)
                          QtCore.QMetaObject.connectSlotsByName(Form)
                  
                      def retranslateUi(self, Form):
                          _translate = QtCore.QCoreApplication.translate
                          Form.setWindowTitle(_translate("QRangeSlider", "QRangeSlider"))
                  
                  
                  class Element(QtWidgets.QGroupBox):
                      def __init__(self, parent, main):
                          super(Element, self).__init__(parent)
                          self.main = main
                  
                      def setStyleSheet(self, style):
                          self.parent().setStyleSheet(style)
                  
                      def textColor(self):
                          return getattr(self, '__textColor', QtGui.QColor(125, 125, 125))
                  
                      def setTextColor(self, color):
                          if type(color) == tuple and len(color) == 3:
                              color = QtGui.QColor(color[0], color[1], color[2])
                          elif type(color) == int:
                              color = QtGui.QColor(color, color, color)
                          setattr(self, '__textColor', color)
                  
                      def paintEvent(self, event):
                          qp = QtGui.QPainter()
                          qp.begin(self)
                          if self.main.drawValues():
                              self.drawText(event, qp)
                          qp.end()
                  
                  
                  class Head(Element):
                      def __init__(self, parent, main):
                          super(Head, self).__init__(parent, main)
                  
                      def drawText(self, event, qp):
                          qp.setPen(self.textColor())
                          qp.setFont(QtGui.QFont('Arial', 10))
                          qp.drawText(event.rect(), QtCore.Qt.AlignLeft, str(self.main.min()))
                  
                  
                  class Tail(Element):
                      def __init__(self, parent, main):
                          super(Tail, self).__init__(parent, main)
                  
                      def drawText(self, event, qp):
                          qp.setPen(self.textColor())
                          qp.setFont(QtGui.QFont('Arial', 10))
                          qp.drawText(event.rect(), QtCore.Qt.AlignRight, str(self.main.max()))
                  
                  
                  class Handle(Element):
                      def __init__(self, parent, main):
                          super(Handle, self).__init__(parent, main)
                  
                      def drawText(self, event, qp):
                          qp.setPen(self.textColor())
                          qp.setFont(QtGui.QFont('Arial', 10))
                          qp.drawText(event.rect(), QtCore.Qt.AlignLeft, str(self.main.start()))
                          qp.drawText(event.rect(), QtCore.Qt.AlignRight, str(self.main.end()))
                  
                      def mouseMoveEvent(self, event):
                          event.accept()
                          mx = event.globalX()
                          _mx = getattr(self, '__mx', None)
                          if not _mx:
                              setattr(self, '__mx', mx)
                              dx = 0
                          else:
                              dx = mx - _mx
                          setattr(self, '__mx', mx)
                          if dx == 0:
                              event.ignore()
                              return
                          elif dx > 0:
                              dx = 1
                          elif dx < 0:
                              dx = -1
                          s = self.main.start() + dx
                          e = self.main.end() + dx
                          if s >= self.main.min() and e <= self.main.max():
                              self.main.setRange(s, e)
                  
                  
                  class QRangeSlider(QtWidgets.QWidget, Ui_Form):
                      endValueChanged = QtCore.pyqtSignal(int)
                      maxValueChanged = QtCore.pyqtSignal(int)
                      minValueChanged = QtCore.pyqtSignal(int)
                      startValueChanged = QtCore.pyqtSignal(int)
                      minValueChanged = QtCore.pyqtSignal(int)
                      maxValueChanged = QtCore.pyqtSignal(int)
                      startValueChanged = QtCore.pyqtSignal(int)
                      endValueChanged = QtCore.pyqtSignal(int)
                  
                      _SPLIT_START = 1
                      _SPLIT_END = 2
                  
                      def __init__(self, parent=None):
                          super(QRangeSlider, self).__init__(parent)
                          self.setupUi(self)
                          self.setMouseTracking(False)
                          self._splitter.splitterMoved.connect(self._handleMoveSplitter)
                          self._head_layout = QtWidgets.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)
                          self._handle_layout = QtWidgets.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)
                          self._tail_layout = QtWidgets.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)
                          self.setMin(0)
                          self.setMax(99)
                          self.setStart(0)
                          self.setEnd(99)
                          self.setDrawValues(True)
                  
                      def min(self):
                          return getattr(self, '__min', None)
                  
                      def max(self):
                          return getattr(self, '__max', None)
                  
                      def setMin(self, value):
                          setattr(self, '__min', value)
                          self.minValueChanged.emit(value)
                  
                      def setMax(self, value):
                          setattr(self, '__max', value)
                          self.maxValueChanged.emit(value)
                  
                      def start(self):
                          return getattr(self, '__start', None)
                  
                      def end(self):
                          return getattr(self, '__end', None)
                  
                      def _setStart(self, value):
                          setattr(self, '__start', value)
                          self.startValueChanged.emit(value)
                  
                      def setStart(self, value):
                          v = self._valueToPos(value)
                          self._splitter.splitterMoved.disconnect()
                          self._splitter.moveSplitter(v, self._SPLIT_START)
                          self._splitter.splitterMoved.connect(self._handleMoveSplitter)
                          self._setStart(value)
                  
                      def _setEnd(self, value):
                          setattr(self, '__end', value)
                          self.endValueChanged.emit(value)
                  
                      def setEnd(self, value):
                          v = self._valueToPos(value)
                          self._splitter.splitterMoved.disconnect()
                          self._splitter.moveSplitter(v, self._SPLIT_END)
                          self._splitter.splitterMoved.connect(self._handleMoveSplitter)
                          self._setEnd(value)
                  
                      def drawValues(self):
                          return getattr(self, '__drawValues', None)
                  
                      def setDrawValues(self, draw):
                          setattr(self, '__drawValues', draw)
                  
                      def getRange(self):
                          return (self.start(), self.end())
                  
                      def setRange(self, start, end):
                          self.setStart(start)
                          self.setEnd(end)
                  
                      def keyPressEvent(self, event):
                          key = event.key()
                          if key == QtCore.Qt.Key_Left:
                              s = self.start()-1
                              e = self.end()-1
                          elif key == QtCore.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):
                          self._tail.setStyleSheet(style)
                          self._head.setStyleSheet(style)
                  
                      def setSpanStyle(self, style):
                          self._handle.setStyleSheet(style)
                  
                      def _valueToPos(self, value):
                          return scale(value, (self.min(), self.max()), (0, self.width()))
                  
                      def _posToValue(self, xpos):
                          return scale(xpos, (0, self.width()), (self.min(), self.max()))
                  
                      def _handleMoveSplitter(self, xpos, index):
                          hw = self._splitter.handleWidth()
                          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)
                          if index == self._SPLIT_START:
                              _lockWidth(self._tail)
                              if v >= self.end():
                                  return
                              offset = -20
                              w = xpos + offset
                              self._setStart(v)
                          elif index == self._SPLIT_END:
                              _lockWidth(self._head)
                              if v <= self.start():
                                  return
                              offset = -40
                              w = self.width() - xpos + offset
                              self._setEnd(v)
                          _unlockWidth(self._tail)
                          _unlockWidth(self._head)
                          _unlockWidth(self._handle)
                  
                  if __name__ == '__main__':
                  
                      app = QtWidgets.QApplication(sys.argv)
                      rs = QRangeSlider()
                      rs.show()
                      rs.setRange(15, 35)
                      rs.setBackgroundStyle('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);')
                      rs.handle.setStyleSheet('background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);')
                      app.exec_()
                  

                  如果你想运行 examples,你只需要更改以下代码块(在文件顶部):

                  If you want to run the examples, you just need to change the following code block (at the top of the file):

                  examples.py:

                  import sys, os
                  from PyQt5 import QtCore
                  from PyQt5 import QtGui
                  from PyQt5 import QtWidgets
                  
                  from qrangeslider import QRangeSlider
                  
                  app = QtWidgets.QApplication(sys.argv)
                  
                  ...
                  

                  这篇关于将范围滑块小部件移植到 PyQt5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Running .jl file from R or Python(从 R 或 Python 运行 .jl 文件)
                  Running Julia .jl file in python(在 python 中运行 Julia .jl 文件)
                  Using PIP in a Azure WebApp(在 Azure WebApp 中使用 PIP)
                  How to run python3.7 based flask web api on azure(如何在 azure 上运行基于 python3.7 的烧瓶 web api)
                  Azure Python Web App Internal Server Error(Azure Python Web 应用程序内部服务器错误)
                  Run python dlib library on azure app service(在 azure app 服务上运行 python dlib 库)
                  <i id='Q6dGY'><tr id='Q6dGY'><dt id='Q6dGY'><q id='Q6dGY'><span id='Q6dGY'><b id='Q6dGY'><form id='Q6dGY'><ins id='Q6dGY'></ins><ul id='Q6dGY'></ul><sub id='Q6dGY'></sub></form><legend id='Q6dGY'></legend><bdo id='Q6dGY'><pre id='Q6dGY'><center id='Q6dGY'></center></pre></bdo></b><th id='Q6dGY'></th></span></q></dt></tr></i><div id='Q6dGY'><tfoot id='Q6dGY'></tfoot><dl id='Q6dGY'><fieldset id='Q6dGY'></fieldset></dl></div>

                1. <tfoot id='Q6dGY'></tfoot>
                      • <bdo id='Q6dGY'></bdo><ul id='Q6dGY'></ul>

                        <small id='Q6dGY'></small><noframes id='Q6dGY'>

                            <tbody id='Q6dGY'></tbody>

                            <legend id='Q6dGY'><style id='Q6dGY'><dir id='Q6dGY'><q id='Q6dGY'></q></dir></style></legend>