Positioning and Displaying a Custom Widget

I am attempting to use PyQT to position and display a custom widget. Thus far, I have a widget, and my window. I have been successful in displaying the widget through a layout, however, I am interested in using .move(x,y,) to position my widget before show()'ing it. Thus far my code is as follows:

import sys, random
from PyQt4 import QtGui, QtCore

# Robot Widget
class RobotLink(QtGui.QWidget):
    def __init__(self, parent, x, y, width, height, fill):
        super(RobotLink, self).__init__(parent)
        self._x        = x
        self._y        = y
        self._width    = width
        self._height   = height
        self._fill     = fill
        self._rotation = 0

    def paintEvent(self, e):
        painter = QtGui.QPainter()
        painter.begin(self)
        self.drawLink(painter)
        painter.end()

    def drawLink(self, painter):
        painter.setPen(QtGui.QColor(0, 0, 0))
        painter.setBrush(self._fill)
        painter.drawEllipse(self._x, self._y, self._width, self._height)

# Window
class Window(QtGui.QWidget):
    # Default Constructor, sets up the window GUI
    def __init__(self):
        super(Window, self).__init__()
        self.initUI()

    def initUI(self):
        self._link1 = RobotLink(self, 225, 400, 30, 150, QtCore.Qt.DiagCrossPattern)
        self._link2 = RobotLink(self, 0, 320, 30, 100, QtCore.Qt.Dense5Pattern)
        self._link3 = RobotLink(self, 225, 260, 30, 75, QtCore.Qt.Dense2Pattern)

        self._link1.move(0, 0)
        self._link1.show()

        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle("CSCE 452 - PaintBot")


    def paintEvent(self, e):
        super(Window, self).paintEvent(e)
        painter = QtGui.QPainter()
        painter.begin(self)
        self.drawBoundingBoxes(painter)
        painter.end()

    # Draws the boxes that define the robots workspace and
    # the control panel
    def drawBoundingBoxes(self, painter):
        color = QtGui.QColor(0, 0, 0)
        color.setNamedColor("#cccccc")
        painter.setPen(color)

        # Draw the robot workspace
        painter.setBrush(QtGui.QColor(255, 255, 255))
        painter.drawRect(10, 10, 500, 578)

        # Draw the control panel workspace
        painter.setBrush(QtGui.QColor(150, 150, 150))
        painter.drawRect(520, 10, 270, 578)

        # Draws the slider 'base'
        painter.setPen(QtGui.QColor(0, 0, 0))
        painter.drawLine(100, 570, 400, 570)

    def changeValue(self, value):
        self.wid.emit(QtCore.SIGNAL("updateRobot(int)"), value)
        self.wid.repaint()

# Setup the Window, and the Robot
app = QtGui.QApplication(sys.argv)
win = Window()
win.show()
app.exec_()

Any idea how to attach my widget, without a layout, position it and have it show inside of my window?


Couple of things I noticed in your code:

  • you don't really need to define store x, y, width and height for your custom widget. Just call setGeometry with coordinates passed into the constructor. Widget already providers getGeometry, getHeight, getWidth, etc. methods which you can use to manipulate and paint your component.

  • when you call drawEllipse in the child widget drawLink method, you're passing x and y coordinates into the function as rectangle beginning. From my understanding you should put there 0, 0 as those coordinates should be widget relative not the window relative.

  • I've made some changes to your code, see if it works for you

    import sys, random
    from PyQt4 import QtGui, QtCore
    
    # Robot Widget
    class RobotLink(QtGui.QWidget):
        def __init__(self, parent, x, y, width, height, fill):
            super(RobotLink, self).__init__(parent)
            self._fill     = fill
            self._rotation = 0
            self.setGeometry(x, y, width, height)
    
        def paintEvent(self, e):
            painter = QtGui.QPainter()
            painter.begin(self)
            self.drawLink(painter)
            painter.end()
    
        def drawLink(self, painter):
            painter.setPen(QtGui.QColor(0, 0, 0))
            painter.setBrush(self._fill)
            painter.drawEllipse(0, 0, self.width(), self.height())
    
    # Window
    class Window(QtGui.QWidget):
        # Default Constructor, sets up the window GUI
        def __init__(self):
            super(Window, self).__init__()
            self.initUI()
    
        def initUI(self):
            self._link1 = RobotLink(self, 10, 10, 100, 50, QtCore.Qt.DiagCrossPattern)
            self._link2 = RobotLink(self, 100, 100, 50, 100, QtCore.Qt.Dense5Pattern)
            self._link3 = RobotLink(self, 150, 150, 50, 50, QtCore.Qt.Dense2Pattern)
    
            self.setGeometry(300, 300, 800, 600)
            self.setWindowTitle("CSCE 452 - PaintBot")
    
        def paintEvent(self, e):
            super(Window, self).paintEvent(e)
            painter = QtGui.QPainter()
            painter.begin(self)
            self.drawBoundingBoxes(painter)
            painter.end()
    
        # Draws the boxes that define the robots workspace and
        # the control panel
        def drawBoundingBoxes(self, painter):
            color = QtGui.QColor(0, 0, 0)
            color.setNamedColor("#cccccc")
            painter.setPen(color)
    
            # Draw the robot workspace
            painter.setBrush(QtGui.QColor(255, 255, 255))
            painter.drawRect(10, 10, 500, 578)
    
            # Draw the control panel workspace
            painter.setBrush(QtGui.QColor(150, 150, 150))
            painter.drawRect(520, 10, 270, 578)
    
            # Draws the slider 'base'
            painter.setPen(QtGui.QColor(0, 0, 0))
            painter.drawLine(100, 570, 400, 570)
    
        def changeValue(self, value):
            self.wid.emit(QtCore.SIGNAL("updateRobot(int)"), value)
            self.wid.repaint()
    
    # Setup the Window, and the Robot
    app = QtGui.QApplication(sys.argv)
    win = Window()
    win.show()
    app.exec_()
    

    hope this helps, regards

    链接地址: http://www.djcxy.com/p/77402.html

    上一篇: pyqt:如何删除一个小部件?

    下一篇: 定位和显示自定义小部件