1
votes

I am using PyQt4 to create a form which displays a web based image in a separate window using a Qlabel. It should be that clicking a button on the form updates the Qlabel with a new image by reading the new image url from a table cell on the form.

The issue I think I am having is not understanding how to create the Qlabel as a class object which I can then update by setting its setPixmap() property. Here's what I've written so far:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest


CAT_PICS = ["http://static.tumblr.com/ce35b04e242c6b8073f3ff7801147e9f/sz5wgey/obSmpcvso/tumblr_static_o-cats-kill-billions-facebook.jpg",
        "http://jasonlefkowitz.net/wp-content/uploads/2013/07/cats-16140154-1920-1080.jpg",
        "http://4.bp.blogspot.com/-MzZCzWI_6Xc/UIUQp1qPfzI/AAAAAAAAHpA/OTwHCJSWFAY/s1600/cats_animals_kittens_cat_kitten_cute_desktop_1680x1050_hd-wallpaper-753974.jpeg"]


class ImageLabel(QLabel):
    def __init__(self, parent=None):
        QLabel.__init__(self, parent)

        url = self.text()
        nam = QNetworkAccessManager()
        def finishRequest(reply):
            img = QImage()
            img.loadFromData(reply.readAll())
            myImage = QPixmap(img)

            self.setFixedSize(myImage.size())
            self.setPixmap(QPixmap(myImage))
        nam.finished.connect(finishRequest)
        nam.get(QNetworkRequest(QUrl(url)))



class MainForm(QDialog):
    index = 0
    def __init__(self):
        super(MainForm, self).__init__()

        changePhotoButton = QPushButton("Next Photo")
        layout = QHBoxLayout()
        layout.addWidget(changePhotoButton)
        self.setLayout(layout)

        self.connect(changePhotoButton, SIGNAL("clicked()"),
                     self.updatePhoto)


    def updatePhoto(self):
        url = CAT_PICS[self.index]
        imageLabel = ImageLabel(url)
        imageLabel.show()
        self.index += 1

def main():
    app = QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()
main()

The code will run, however when the ImageLabel class is called the QLabel is created with the initial text from the url but the image is never fetched and the Qlabel is removed from view immediately.

I would appreciate any tips on how to get this working.

1
Why are you making a QLabel subclass for this operation?lpapp
Hi, I wanted to make it so that the initial form can update the Qlabel by clicking the button. So far I can get a Qlabel with image created by placing the code inside the ImageLabel class in main() I can't get it to work by placing it anywhere else. I don't know how to handle the nam.finished.connect(finishRequest) and def finishRequest(reply): parts.wanyo
You really do not need a subclass for this. You can connect the button click to a slot which sets the corresponding pixmap... Also, you use imageLabel = ImageLabel(url) whereas the ImageLabel class does not have such an "init" method parameter... OT: "main()" as a line looks strange in python.lpapp
"I don't know how to handle the nam.finished.connect(finishRequest) and def finishRequest(reply): parts." -> What exactly is your concern in there?lpapp
Could you write some example code as I am not familiar with slots? I'm not really familiar with the syntax for nam.finished.connect(finishRequest) or def finishRequest(reply) and couldn't see a clear explanation so far.wanyo

1 Answers

1
votes

In short, I would drop the custom QLabel subclass and would extend the updatePhoto method instead as demonstrated below. However, it seems that you did not handle the url correctly.

def __init__(self):
    self.myLabel = QLabel()
    self.nam = QNetworkAccessManager()
    self.nam.finished.connect(self.finishRequest)
    ...

def finishRequest(self, reply):
    myPixmap = QPixmap()
    if not myPixmap.loadFromData(reply.readAll()):
        print('Could not load')
    self.myLabel.setFixedSize(myImage.size())
    self.myLabel.setPixmap(myPixmap)
    self.myLabel.show()

def updatePhoto(self):
    url = CAT_PICS[self.index]
    self.nam.get(QNetworkRequest(QUrl(url)))
    self.index += 1

Note that I would use the nam and myLabel as class members of your correponding python class.