user2686299
user2686299

Reputation: 427

How to change a QImage that is already set up and shown within QWidget?

I want to change an image with my mouse. So, everytime I click somewhere, the image should change. I can show an image only one time. So I need to separate the initialization of everything that is needed to show an image from the part of code that is responsable for building an image.

Here is what I have got by far

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

class Example(QWidget):



    def __init__(self):
        super(Example, self).__init__()
        self.gx=1
        self.gy=1
        self.tlb=QLabel()
        self.lbl=QLabel()
        self.image = QImage(512, 512, QImage.Format_RGB32)
        self.hbox = QHBoxLayout()
        self.pixmap = QPixmap()
        self.initUI()

    def mousePressEvent(self, QMouseEvent):
        px = QMouseEvent.pos().x()
        py = QMouseEvent.pos().y()

        size = self.frameSize()

        self.gx = px-size.width()/2
        self.gy = py-size.height()/2

        self.fillImage()


    def initUI(self):    
        self.hbox = QHBoxLayout(self)
        self.pixmap = QPixmap()

        size = self.frameSize()

        self.fillImage()

        self.lbl = QLabel(self)
        self.lbl.setPixmap(self.pixmap)

        self.hbox.addWidget(self.lbl)
        self.setLayout(self.hbox)

        self.move(300, 200)
        self.setWindowTitle('Red Rock')

        self.tlb = QLabel(str(self.gx)+" : "+str(self.gy), self)
        self.tlb.move(12,3)
        self.show()  

    def fillImage(self):
        for x in range(0, 512):
            t = -1+(x/512)*2
            color =  (1 - (3 - 2*abs(t))*t**2) 

            for y in range(0, 512):

                t1 = -1+(y/512)*2
                color1 = (1 - (3 - 2*abs(t1))*t1**2)
                result = (255/2)+(color * color1 * (t*self.gx+t1*self.gy) )*(255/2)

                self.image.setPixel(x, y, qRgb(result, result, result))

        self.pixmap = self.pixmap.fromImage(self.image)

        self.tlb = QLabel(str(self.gx)+" : "+str(self.gy), self)

        print(self.gx)

        self.update()


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()    

The print(self.gx) shows me that self.gx is changed, but the image isn't changed at all.

What do I do wrong?

Upvotes: 0

Views: 1163

Answers (2)

user2686299
user2686299

Reputation: 427

I've added self.lbl.setPixmap(self.pixmap) into fillImage before self.repaint() and self.update() and now it works, then i changed a little the code and now it looks like this

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

class Example(QWidget):

    def __init__(self):
        super(Example, self).__init__()
        self.gx=1
        self.gy=1
        self.lbl=QLabel()
        self.tlb = None
        self.image = QImage(512, 512, QImage.Format_RGB32)
        self.hbox = QHBoxLayout()
        self.pixmap = QPixmap()
        self.length = 1
        self.initUI()

    def mousePressEvent(self, QMouseEvent):
        px = QMouseEvent.pos().x()
        py = QMouseEvent.pos().y()

        size = self.frameSize()

        self.gx = px-size.width()/2
        self.gy = py-size.height()/2

        h = (self.gx**2+self.gy**2)**0.5

        self.gx/=h
        self.gy/=h

        self.gx*=self.length
        self.gy*=self.length

        self.fillImage()

    def wheelEvent(self,event):
        self.length+=(event.delta()*0.001)
        print(self.length)


    def initUI(self):    
        self.hbox = QHBoxLayout(self)
        self.pixmap = QPixmap()
        self.move(300, 200)
        self.setWindowTitle('Red Rock')

        self.addedWidget = None

        self.fillImage()

        self.setLayout(self.hbox)

        self.show()  

    def fillImage(self):
        for x in range(0, 512):
            t = -1+(x/512)*2
            color =  (1 - (3 - 2*abs(t))*t**2) 

            for y in range(0, 512):

                t1 = -1+(y/512)*2
                color1 = (1 - (3 - 2*abs(t1))*t1**2)
                result = (255/2)+(color * color1 * (t*self.gx+t1*self.gy) )*(255/2)

                self.image.setPixel(x, y, qRgb(result, result, result))


        self.pixmap = self.pixmap.fromImage(self.image)

        if self.lbl == None:
            self.lbl = QLabel(self)
        else:
            self.lbl.setPixmap(self.pixmap)

        if self.addedWidget == None:
            self.hbox.addWidget(self.lbl)
            self.addedWidget = True

        if self.tlb==None:
            self.tlb = QLabel(str(self.gx)+" : "+str(self.gy), self)
            self.tlb.move(12,3)
        else:
            self.tlb.setText(str(self.gx)+" : "+str(self.gy))

        self.repaint()
        self.update()


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()    

Upvotes: 1

Roland Smith
Roland Smith

Reputation: 43533

You will have to tell the GUI that it needs to refresh the image.

In QT it seems you will need to call the update() or repaint() methods of the widget.

Upvotes: 1

Related Questions