Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Dynamically paint or draw filled and coloured rectangle using pyqt



  • I've created a simple gui using qt-designer and python. I would like to dynamically create a rectangle (with fill and colour) by adjusting a slider in the gui. I have managed to do this with a dashed line rectangle but I think that is the limit of drawRecangle. This is what I have:

    from PyQt5 import QtWidgets, uic, QtGui, QtCore
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import*  
    from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)
    from matplotlib.patches import Rectangle
    import sys
    
    class MainWindow(QtWidgets.QMainWindow):
        
        def __init__(self, *args, **kwargs):
            super(MainWindow, self).__init__(*args, **kwargs)
        
            #Load the UI Page
            uic.loadUi('mainwindow.ui', self)
    
            global slider_widget
            slider_widget = self.findChild(QtWidgets.QSlider, "verticalSlider")
            slider_widget.valueChanged.connect(self.valueChanged)
        
            self.update_paintwidget()
            self.update_graph()
        
        def update_paintwidget(self):
            self.PaintWidget.paintEvent
        
        def update_graph(self):
            self.MplWidget.canvas.drawRectangle((10,200,100,0))
        
        def valueChanged(self):
            global val 
            val = slider_widget.value()
            self.MplWidget.canvas.drawRectangle((10,100-((val*2)-100),100,100+((val*2)-100)))
    
    def main():
        app = QtWidgets.QApplication(sys.argv)
        main = MainWindow()
        main.show()
        sys.exit(app.exec_())
    
    if __name__ == '__main__':      
        main()
    

    I have a separate widget (promoted in qt designer) to dynamically draw the rectangle. I cannot however colour the lines of the rectangle or fill in with a colour. It is just dashed black lines.

    mplwidget.py
    
    from PyQt5.QtWidgets import*
    
    from matplotlib.backends.backend_qt5agg import FigureCanvas
    
    from matplotlib.figure import Figure
    
    class MplWidget(QWidget):
    
        def __init__(self,parent = None):
    
            QWidget.__init__(self, parent)
            self.canvas = FigureCanvas(Figure())
            vertical_layout = QVBoxLayout()
            vertical_layout.addWidget(self.canvas)
            self.setLayout(vertical_layout)
    

    I've tried using paintevent and can create a rectange but I can't figure out how to dynamically pass the co-ordinate values to it.

    paintwidget.py
    
    from PyQt5 import QtCore, QtGui, Qt
    from PyQt5.QtWidgets import*
    
    class PaintWidget(QWidget):
    
        def __init__(self,parent = None):
            QWidget.__init__(self, parent)
    
        def paintEvent(self,event): #,event
            qp = QtGui.QPainter(self)
            qp.setPen(QtGui.QPen(QtCore.Qt.red))
            qp.drawRect(10, 15, 20, 20)
    

    Is this possible?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You should add a setter to your widget to pass it the coordinates you want.

    On a side note, you should call update and not try to call the paintEvent method directly.

    Depending on your end goal, you might want to consider the Graphics View framework.


Log in to reply