Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何为QTableWidget设置选择滑块?_Python_Pyqt_Qtablewidget - Fatal编程技术网

Python 如何为QTableWidget设置选择滑块?

Python 如何为QTableWidget设置选择滑块?,python,pyqt,qtablewidget,Python,Pyqt,Qtablewidget,我正在寻找合并离散滑块和QTableWidget的解决方案,请参阅附加的屏幕截图。滑块用作选择点,而不是默认选择荧光灯。如何使用Qt-PyQt实现它 小前提。从技术上讲,根据StackOverflow标准,你的问题不是很好。我会在回答的最后解释 要得到你想要的东西并不容易,最重要的是,滑块不是为这个目的而设计的,有很多原因你不应该这样做,去问问他们 诀窍是创建一个将表小部件作为父项的QSlider。创建具有父窗口的小部件可确保子窗口小部件始终包含在父边界内。这对于QMainWindow和QDia

我正在寻找合并离散滑块和QTableWidget的解决方案,请参阅附加的屏幕截图。滑块用作选择点,而不是默认选择荧光灯。如何使用Qt-PyQt实现它


小前提。从技术上讲,根据StackOverflow标准,你的问题不是很好。我会在回答的最后解释

要得到你想要的东西并不容易,最重要的是,滑块不是为这个目的而设计的,有很多原因你不应该这样做,去问问他们

诀窍是创建一个将表小部件作为父项的QSlider。创建具有父窗口的小部件可确保子窗口小部件始终包含在父边界内。这对于QMainWindow和QDialog子体是错误的,只要小部件未添加到父布局中。这允许您自由设置其几何体位置和大小

在下面的示例中,我添加了一个内部QSlider,但是这个小部件的主要问题是如何将其对齐,使其值位置与表内容对齐

class GhostHeader(QtWidgets.QHeaderView):
    '''
    A "fake" vertical header that does not paint its sections
    '''
    def __init__(self, parent):
        super().__init__(QtCore.Qt.Vertical, parent)
        self.setSectionResizeMode(self.Fixed)

    def paintEvent(self, event):
        pass


class SliderTable(QtWidgets.QTableWidget):
    def __init__(self, rows=0, columns=0, parent=None):
        super().__init__(rows, columns, parent)
        self.horizontalHeader().setStretchLastSection(True)
        self.setHorizontalHeaderLabels(['Item table'])
        self.setVerticalHeader(GhostHeader(self))

        # create a slider that is a child of the table; there is no layout, but
        # setting the table as its parent will cause it to be shown "within" it.
        self.slider = QtWidgets.QSlider(QtCore.Qt.Vertical, self)
        # by default, a slider has its maximum on the top, let's invert this
        self.slider.setInvertedAppearance(True)
        self.slider.setInvertedControls(True)
        # show tick marks at each slider value, on both sides
        self.slider.setTickInterval(1)
        self.slider.setTickPosition(self.slider.TicksBothSides)
        self.slider.setRange(0, max(0, self.rowCount() - 1))
        # not necessary, but useful for wheel and click interaction
        self.slider.setPageStep(1)
        # disable focus on the slider
        self.slider.setFocusPolicy(QtCore.Qt.NoFocus)

        self.slider.valueChanged.connect(self.selectRowFromSlider)
        self.slider.valueChanged.connect(self.updateSlider)
        self.verticalScrollBar().valueChanged.connect(self.updateSlider)

        self.model().rowsInserted.connect(self.modelChanged)
        self.model().rowsRemoved.connect(self.modelChanged)

    def selectRowFromSlider(self, row):
        if self.currentIndex().isValid():
            column = self.currentIndex().column()
        else:
            column = 0
        self.setCurrentIndex(self.model().index(row, column))

    def modelChanged(self):
        self.slider.setMaximum(max(0, self.rowCount() - 1))
        self.updateSlider()

    def updateSlider(self):
        slider = self.slider
        option = QtWidgets.QStyleOptionSlider()
        slider.initStyleOption(option)
        style = slider.style()

        # get the available extent of the slider
        available = style.pixelMetric(style.PM_SliderSpaceAvailable, option, slider)
        # compute the space between the top of the slider and the position of
        # the minimum value (0)
        deltaTop = (slider.height() - available) // 2
        # do the same for the maximum
        deltaBottom = slider.height() - available - deltaTop

        # the vertical center of the first item
        top = self.visualRect(self.model().index(0, 0)).center().y()
        # the vertical center of the last
        bottom = self.visualRect(self.model().index(self.model().rowCount() - 1, 0)).y()

        # get the slider width and adjust the size of the "ghost" vertical header
        width = self.slider.sizeHint().width()
        left = self.frameWidth() + 1
        self.verticalHeader().setFixedWidth(width // 2 + left)

        viewGeo = self.viewport().geometry()
        headerHeight = viewGeo.top()
        # create the rectangle for the slider geometry
        rect = QtCore.QRect(0, headerHeight + top, width, headerHeight + bottom - top // 2)
        # adjust to the values computed above
        rect.adjust(0, -deltaTop + 1, 0, -deltaBottom)
        # translate it so that its center will be between the vertical header and
        # the table contents
        rect.translate(left, 0)
        self.slider.setGeometry(rect)

        # set the mask, in case the item view is scrolled, so that the top of the
        # slider won't be shown in the horizontal header
        visible = self.rect().adjusted(0, viewGeo.top(), 0, 0)
        mask = QtGui.QPainterPath()
        topLeft = slider.mapFromParent(visible.topLeft())
        bottomRight = slider.mapFromParent(visible.bottomRight() + QtCore.QPoint(1, 1))
        mask.addRect(QtCore.QRectF(topLeft, bottomRight))
        self.slider.setMask(QtGui.QRegion(mask.toFillPolygon(QtGui.QTransform()).toPolygon()))

    def currentChanged(self, current, previous):
        super().currentChanged(current, previous)
        if current.isValid():
            self.slider.setValue(current.row())

    def resizeEvent(self, event):
        # whenever the table is resized (even when first shown) call the base
        # implementation (which is required for correct drawing of items and
        # selections), then update the slider
        super().resizeEvent(event)
        self.updateSlider()


class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QVBoxLayout(self)
        self.table = SliderTable()
        self.table.setRowCount(4)
        self.table.setColumnCount(1)
        self.table.setHorizontalHeaderLabels(['Item table'])
        layout.addWidget(self.table)
        for row in range(self.table.rowCount()):
            item = QtWidgets.QTableWidgetItem('item {}'.format(row + 1))
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.table.setItem(row, 0, item)
为什么这个问题不是那么好? 好吧,它很危险的接近我不知道怎么做,你能帮我做吗?限度你应该提供任何信息,不管它是否起作用,你应该做一些研究并展示你的努力,即使在评论部分做了一些澄清之后,问题还是有点模糊。
长话短说:如果这太难了,你不能让它工作,你可能还需要一些学习和锻炼才能实现它。耐心地研究文档:幸运的是,Qt文档通常写得很好,所以这只是时间问题。

不,应该只有4项。没有了。我只需要实现你们在图片上看到的。当我点击项目时,我需要离散地移动滑块。通常,当我们点击项目时,我们会看到它高亮显示,对吗?因此,在我的例子中,需要使用滑块上的位置,而不是高亮显示。我需要能够通过移动滑块也选择项目。对不起,开头的帖子模糊不清。对了,你完全正确。我只是不知道如何合并QSlider和QTable小部件以获得我所附图片的视图垂直标题应该隐藏,正如我们在图片上看到的那样有没有任何解决方案可以将滑块放在表格的右侧?这是可能的,但我强烈反对:如果出于任何原因出现滚动条,那么使用该界面会非常困难,非常混乱。老实说,我认为您正在尝试创建一个真正没有必要的界面组件,它的用户体验关注点远多于优势:我真的看不出有什么好的理由为此使用滑块,不管您将它放在哪一边。