Search code examples
pythonqtpyqt4qpainter

Python PyQt: TypeError while pressing the button to change the color of Circle


I am new in Python and using PyQt4 for developing the Gui. I want to change the color of circles while pressing the toggle button. But I am getting the error in slot.

My code is:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyFrame(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self)

        self.scene=QGraphicsScene(self)
        self.scene.setSceneRect(QRectF(0,0,245,245))
        self.bt=QPushButton("Press",self)
        self.bt.setGeometry(QRect(450, 150, 90, 30))
        self.bt.setCheckable(True)
        self.color = QColor(Qt.green)
        self.color1= QColor(Qt.magenta)
        self.show()
        self.connect(self.bt, SIGNAL("clicked()"), self.changecolor)

    def paintEvent(self, event=None):
        paint=QPainter(self)
        paint.setPen(QPen(QColor(Qt.magenta),1,Qt.SolidLine))
        paint.setBrush(self.color)
        paint.drawEllipse(190,190, 70, 70)
        paint.setPen(QPen(QColor(Qt.green),1,Qt.SolidLine))
        paint.setBrush(self.color1)
        paint.drawEllipse(300,300, 70, 70)

    def changecolor(self):
        if pressed:
         self.color = QColor(Qt.red)
         self.color1= QColor(Qt.blue)
        else:
         self.color=QColor(Qt.yellow)
         self.color1=QColor(Qt.gray)

        self.update()

app=QApplication(sys.argv)
f=MyFrame()
f.show()
app.exec_()

Solution

  • The way it stands, it tries to call changecolor with only one argument, self. I'm not entirely sure what you're trying to achieve. Your changecolor takes in a variable "paint", but tries to use self.paint, which doesn't exist. So maybe you could think, that you can just get a hold of the painter with a call to to QPainter and lose the parameter called "paint", like following:

    def changecolor(self):
      paint = QPainter(self)
      paint.setBrush(QColor(Qt.red))
      paint.drawEllipse(190,190,70,70)
      self.update()
    

    This runs into the following error:

    QPainter::begin: Widget painting can only begin as a result of a paintEvent
    QPainter::setBrush: Painter not active
    

    That tells you, that you can only have painting actions inside the paintEvent. One solution is to have an class member, e.g. self.color that holds the color you want for the circle. A fully working code is below:

    import sys
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *
    
    class MyFrame(QWidget):
      def __init__(self, parent=None):
        QWidget.__init__(self)
    
        self.scene=QGraphicsScene(self)
        self.scene.setSceneRect(QRectF(0,0,245,245))
        self.bt=QPushButton("Press",self)
        self.bt.setGeometry(QRect(450, 150, 90, 30))
        self.color = QColor(Qt.green)
        self.show()
        self.connect(self.bt, SIGNAL("clicked()"), self.changecolor)
    
      def paintEvent(self, event=None):
        paint=QPainter(self)
        paint.setPen(QPen(QColor(Qt.red),1,Qt.SolidLine))
        paint.setBrush(self.color)
        paint.drawEllipse(190,190, 70, 70)
    
      def changecolor(self):
        self.color = QColor(Qt.red)
        self.update()
    
    app=QApplication(sys.argv)
    f=MyFrame()
    f.show()
    app.exec_()