【问题标题】:Painting on a widget that contains a QGridLayout in PySide/PyQt在 PySide/PyQt 中包含 QGridLayout 的小部件上绘画
【发布时间】:2014-09-16 04:42:38
【问题描述】:

我正在制作一个自定义 QWidget,其中我有一个 QGridLayout,并在网格中的特定元素上绘制一个矩形。我还手动绘制线条来描绘网格元素的位置(使用 QPainter.DrawLines)。

绘制线条后,我在其中一个网格元素内绘制矩形,其位置使用 QGridLayout 坐标系指定。

问题是,矩形并不局限于它的网格元素。例如,在下面的示例中,蓝色矩形和黑色网格线没有对齐,所以我最终得到了一个漂浮在空间中的蓝色框。

我没有通过 Google 或 SO 找到对此问题的明确讨论。

编辑:

注意正如接受的答案中指出的那样,错误是使用 grid 坐标在网格上绘制,而我应该使用 point 坐标(即列, 排)。也就是说,下面代码中的错误是网格中的元素的x坐标和y坐标颠倒了。


from PySide import QtGui, QtCore

class HighlightSquare(QtGui.QWidget):
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent=None)
        self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                                       QtGui.QSizePolicy.Expanding))                  
        self.setMinimumSize(self.minimumSizeHint()) 
        layout = QtGui.QGridLayout()
        layout.addItem(QtGui.QSpacerItem(10,10), 0, 0)
        layout.addItem(QtGui.QSpacerItem(10,10), 0, 1)
        layout.addItem(QtGui.QSpacerItem(10,10), 1, 0)
        layout.addItem(QtGui.QSpacerItem(10,10), 1, 1)       
        self.setLayout(layout)
        self.resize(150, 150)
        self.update()

    def paintEvent(self, event = None):
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        winHeight=self.size().height(); heightStep=winHeight/2
        winWidth=self.size().width(); widthStep=winWidth/2

        #Draw lines
        painter.setPen(QtCore.Qt.black)
        for i in range(4):
            #vertical lines
            painter.drawLine(QtCore.QPoint(i*widthStep,0), QtCore.QPoint(i*widthStep, winHeight))
            #horizontal lines
            painter.drawLine(QtCore.QPoint(0,heightStep*i), QtCore.QPoint(winWidth, heightStep*i))

        #Draw blue outline around box 1,1
        highlightCoordinate=(1,1)
        pen=QtGui.QPen(QtCore.Qt.blue, 3)        
        painter.setPen(pen)
        coordHighlight=[QtCore.QPoint(highlightCoordinate[1]*heightStep, highlightCoordinate[0]*widthStep),\
                        QtCore.QPoint(highlightCoordinate[1]*heightStep, (highlightCoordinate[0]+1)*widthStep),\
                        QtCore.QPoint((highlightCoordinate[1]+1)*heightStep, (highlightCoordinate[0]+1)*widthStep),\
                        QtCore.QPoint((highlightCoordinate[1]+1)*heightStep, highlightCoordinate[0]*widthStep),\
                        QtCore.QPoint(highlightCoordinate[1]*heightStep, highlightCoordinate[0]*widthStep)]
        #print coordHighlight
        painter.drawPolyline(coordHighlight)

    def minimumSizeHint(self):
        return QtCore.QSize(120,120)


if __name__=="__main__":
    import sys
    app=QtGui.QApplication(sys.argv)
    myLight = HighlightSquare()
    myLight.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python qt pyqt pyside


    【解决方案1】:

    你读过QtCore.QPoint类的构造函数的定义吗?在方法QPoint.__init__ (self, int xpos, int ypos) 处,您的代码被反转(ypos, xpos)。我修好了。

    import sys
    from PyQt4 import QtGui, QtCore
    
    class QHighlightSquareWidget (QtGui.QWidget):
        def __init__ (self, parent = None):
            QtGui.QWidget.__init__(self, parent = None)
            self.setSizePolicy (
                QtGui.QSizePolicy (
                    QtGui.QSizePolicy.Expanding,
                    QtGui.QSizePolicy.Expanding))
            self.setMinimumSize(self.minimumSizeHint())
            allQGridLayout = QtGui.QGridLayout()
            allQGridLayout.addItem(QtGui.QSpacerItem(10,10), 0, 0)
            allQGridLayout.addItem(QtGui.QSpacerItem(10,10), 0, 1)
            allQGridLayout.addItem(QtGui.QSpacerItem(10,10), 1, 0)
            allQGridLayout.addItem(QtGui.QSpacerItem(10,10), 1, 1)       
            self.setLayout(allQGridLayout)
            self.resize(150, 150)
            self.update()
    
        def paintEvent (self, eventQPaintEvent):
            myQPainter = QtGui.QPainter(self)
            myQPainter.setRenderHint(QtGui.QPainter.Antialiasing)
            winHeight = self.size().height()
            heightStep = winHeight / 2
            winWidth  = self.size().width()
            widthStep = winWidth / 2
    
            myQPainter.setPen(QtCore.Qt.black)
            for i in range(4):
                myQPainter.drawLine(QtCore.QPoint(i * widthStep, 0             ), QtCore.QPoint(i * widthStep, winHeight     ))
                myQPainter.drawLine(QtCore.QPoint(0,             heightStep * i), QtCore.QPoint(winWidth,      heightStep * i))
    
            highlightCoordinate = (1, 1)
            myQPen = QtGui.QPen(QtCore.Qt.blue, 3)        
            myQPainter.setPen(myQPen)
            coordHighlight = [
                QtCore.QPoint( highlightCoordinate[0]      * widthStep,  highlightCoordinate[1]      * heightStep),
                QtCore.QPoint((highlightCoordinate[0] + 1) * widthStep,  highlightCoordinate[1]      * heightStep),
                QtCore.QPoint((highlightCoordinate[0] + 1) * widthStep, (highlightCoordinate[1] + 1) * heightStep),
                QtCore.QPoint( highlightCoordinate[0]      * widthStep, (highlightCoordinate[1] + 1) * heightStep),
                QtCore.QPoint( highlightCoordinate[0]      * widthStep,  highlightCoordinate[1]      * heightStep)]
            myQPainter.drawPolyline(*coordHighlight)
    
        def minimumSizeHint (self):
            return QtCore.QSize(120, 120)
    
    if __name__=="__main__":
        myQApplication = QtGui.QApplication(sys.argv)
        myQHighlightSquareWidget = QHighlightSquareWidget()
        myQHighlightSquareWidget.show()
        sys.exit(myQApplication.exec_())
    

    【讨论】:

      猜你喜欢
      • 2017-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多