How to display a url image in QNetwork Access Manager in PyQt6?
-
I understand that displaying an image via requests:
import requests from PyQt6.QtWidgets import QApplication, QWidget, QLabel from PyQt6.QtGui import QImage, QPixmap app = QApplication([]) url_image = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png" image = QImage() image.loadFromData(requests.get(url_image).content) image_label = QLabel() image_label.setPixmap(QPixmap(image)) image_label.show() app.exec()But I'm curious how this transfers to QNetwork Access Manager, especially since it seems to operate different from requests.
-
Hi,
QNetworkAccessManager is asynchronous therefore, you need to use a slot to retrieve the data once the request is finished and then set it on the image.
-
Hi,
QNetworkAccessManager is asynchronous therefore, you need to use a slot to retrieve the data once the request is finished and then set it on the image.
@SGaist I apologize that the code below is crap but it's difficult to find any information on how to code a url image display from QNAM.
I've coded the below:
import sys from PyQt6 import QtNetwork from PyQt6.QtGui import* from PyQt6.QtWidgets import* from PyQt6 import QtCore from PyQt6.QtCore import pyqtSignal, QUrl class MainWindow(QWidget): image_get = pyqtSignal(name= 'imageGet') def __init__ (self): super().__init__() self.setWindowTitle("Show Image") self.start_button() self.setGeometry(200,300,400,500) self.image_screen = QLabel(self) self.image_screen.setPixmap(QPixmap()) self.image_screen.setGeometry(180, -25, 200, 300) self.imageGet.connect(self.show_image) self.manager = QtNetwork.QNetworkAccessManager() self.show() def start_button(self): self.button_s = QPushButton(self) self.button_s.clicked.connect(self.start_button_click) self.button_s.setText("Start") self.button_s.setStyleSheet("QPushButton" "{" "background:red;}" "QPushButton:pressed" "{" "background:green;}" ) self.button_s.resize (48,48) self.button_s.move(170,412) def start_button_click(self): url = "https://pokeapi.co/api/v2/pokemon/25" self.site_request(url) def site_request(self, url): req = QtNetwork.QNetworkRequest(QUrl(url)) self.nam = QtNetwork.QNetworkAccessManager() self.nam.finished.connect(self.handle_request) self.nam.get(req) def handle_request(self, reply): json2qt = QtCore.QJsonDocument.fromJson er = reply.error() if er == QtNetwork.QNetworkReply.NetworkError.NoError: qbyte = reply.readAll() self.json = json2qt(qbyte) self.image_get.emit() else: print ("Error") print(reply.errorString()) def sprite_find_official(dict): return dict["sprites"]["other"]["official-artwork"]["front_default"].toString() def show_image(self): json_dict = self.json url_image = MainWindow.sprite_find_official(json_dict) image = QImage() image.loadFromData(url_image) QPixmap.loadFromData(image) image_label = QLabel() image_label.setPixmap(QPixmap(image)) if __name__ == '__main__': app = QApplication(sys.argv) ex = MainWindow() code = app.exec() sys.exit(code)After hitting the "start button" the program automatically exits out (crashes) and I receive this Traceback:
Traceback (most recent call last):File "c:\Users\Nader\OneDrive\Desktop\Coding\testing.py", line 68, in show_image image.loadFromData(url_image) TypeError: arguments did not match any overloaded call: loadFromData(self, PyQt6.sip.array[bytes], format: str = None): argument 1 has unexpected type 'str' loadFromData(self, QByteArray, format: str = None): argument 1 has unexpected type 'str'Taking the
toString()off of:def sprite_find_official(dict): return dict["sprites"]["other"]["official-artwork"]["front_default"]Results in a similar Traceback:
File "c:\Users\Nader\OneDrive\Desktop\Coding\testing.py", line 67, in show_image image.loadFromData(url_image) TypeError: arguments did not match any overloaded call: loadFromData(self, PyQt6.sip.array[bytes], format: str = None): argument 1 has unexpected type 'QJsonValue' loadFromData(self, QByteArray, format: str = None): argument 1 has unexpected type 'QJsonValue' -
@SGaist I apologize that the code below is crap but it's difficult to find any information on how to code a url image display from QNAM.
I've coded the below:
import sys from PyQt6 import QtNetwork from PyQt6.QtGui import* from PyQt6.QtWidgets import* from PyQt6 import QtCore from PyQt6.QtCore import pyqtSignal, QUrl class MainWindow(QWidget): image_get = pyqtSignal(name= 'imageGet') def __init__ (self): super().__init__() self.setWindowTitle("Show Image") self.start_button() self.setGeometry(200,300,400,500) self.image_screen = QLabel(self) self.image_screen.setPixmap(QPixmap()) self.image_screen.setGeometry(180, -25, 200, 300) self.imageGet.connect(self.show_image) self.manager = QtNetwork.QNetworkAccessManager() self.show() def start_button(self): self.button_s = QPushButton(self) self.button_s.clicked.connect(self.start_button_click) self.button_s.setText("Start") self.button_s.setStyleSheet("QPushButton" "{" "background:red;}" "QPushButton:pressed" "{" "background:green;}" ) self.button_s.resize (48,48) self.button_s.move(170,412) def start_button_click(self): url = "https://pokeapi.co/api/v2/pokemon/25" self.site_request(url) def site_request(self, url): req = QtNetwork.QNetworkRequest(QUrl(url)) self.nam = QtNetwork.QNetworkAccessManager() self.nam.finished.connect(self.handle_request) self.nam.get(req) def handle_request(self, reply): json2qt = QtCore.QJsonDocument.fromJson er = reply.error() if er == QtNetwork.QNetworkReply.NetworkError.NoError: qbyte = reply.readAll() self.json = json2qt(qbyte) self.image_get.emit() else: print ("Error") print(reply.errorString()) def sprite_find_official(dict): return dict["sprites"]["other"]["official-artwork"]["front_default"].toString() def show_image(self): json_dict = self.json url_image = MainWindow.sprite_find_official(json_dict) image = QImage() image.loadFromData(url_image) QPixmap.loadFromData(image) image_label = QLabel() image_label.setPixmap(QPixmap(image)) if __name__ == '__main__': app = QApplication(sys.argv) ex = MainWindow() code = app.exec() sys.exit(code)After hitting the "start button" the program automatically exits out (crashes) and I receive this Traceback:
Traceback (most recent call last):File "c:\Users\Nader\OneDrive\Desktop\Coding\testing.py", line 68, in show_image image.loadFromData(url_image) TypeError: arguments did not match any overloaded call: loadFromData(self, PyQt6.sip.array[bytes], format: str = None): argument 1 has unexpected type 'str' loadFromData(self, QByteArray, format: str = None): argument 1 has unexpected type 'str'Taking the
toString()off of:def sprite_find_official(dict): return dict["sprites"]["other"]["official-artwork"]["front_default"]Results in a similar Traceback:
File "c:\Users\Nader\OneDrive\Desktop\Coding\testing.py", line 67, in show_image image.loadFromData(url_image) TypeError: arguments did not match any overloaded call: loadFromData(self, PyQt6.sip.array[bytes], format: str = None): argument 1 has unexpected type 'QJsonValue' loadFromData(self, QByteArray, format: str = None): argument 1 has unexpected type 'QJsonValue'@gunraidan
image.loadFromData(url_image)apparently expectsurl_imageto be aQByteArrayor in Python somehting like abytesarray. Your value atdict["sprites"]["other"]["official-artwork"]["front_default"]is apparently aQJsonValuewith aQJsonValue::String/strvalue instead. You need to address that. JSON does not even have a "bytes" value type. In your original code it looks likeurl_imagewas a URL string on which you did a GET request to get its content. -
@gunraidan
image.loadFromData(url_image)apparently expectsurl_imageto be aQByteArrayor in Python somehting like abytesarray. Your value atdict["sprites"]["other"]["official-artwork"]["front_default"]is apparently aQJsonValuewith aQJsonValue::String/strvalue instead. You need to address that. JSON does not even have a "bytes" value type. In your original code it looks likeurl_imagewas a URL string on which you did a GET request to get its content.@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
image.loadFromData(url_image)apparently expectsurl_imageto be aQByteArrayor in Python somehting like abytesarray. Your value atdict["sprites"]["other"]["official-artwork"]["front_default"]is apparently aQJsonValuewith aQJsonValue::String/strvalue instead. You need to address that. JSON does not even have a "bytes" value type. In your original code it looks likeurl_imagewas a URL string on which you did a GET request to get its content.I followed your advice in changing
url_image1 to being abytestype and added the line:url_image = QtCore.QByteArray(url_image)` to:def show_image(self): json_dict = self.json url_image = MainWindow.sprite_find_official(json_dict) image = QImage() url_image = QtCore.QByteArray(url_image) image.loadFromData(url_image) QPixmap.loadFromData(image) image_label = QLabel() image_label.setPixmap(QPixmap(image))Traceback:
Traceback (most recent call last): File "c:\Users\Nader\OneDrive\Desktop\Coding\testing.py", line 68, in show_image image.loadFromData(url_image) TypeError: arguments did not match any overloaded call: loadFromData(self, PyQt6.sip.array[bytes], format: str = None): argument 1 has unexpected type 'QJsonValue' loadFromData(self, QByteArray, format: str = None): argument 1 has unexpected type 'QJsonValue'@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
Your value at dict["sprites"]["other"]["official-artwork"]["front_default"] is apparently a QJsonValue with a QJsonValue::String/str value instead.So I should do something like this for that function?
def sprite_find_official(dict): return QtCore.QJsonValue(dict["sprites"]["other"]["official-artwork"]["front_default"])This returns this Traceback:
TypeError: arguments did not match any overloaded call: QByteArray(): too many arguments QByteArray(int, bytes): argument 1 has unexpected type 'QJsonValue' QByteArray(QByteArray): argument 1 has unexpected type 'QJsonValue'So I doubt that is what you wanted.
-
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
image.loadFromData(url_image)apparently expectsurl_imageto be aQByteArrayor in Python somehting like abytesarray. Your value atdict["sprites"]["other"]["official-artwork"]["front_default"]is apparently aQJsonValuewith aQJsonValue::String/strvalue instead. You need to address that. JSON does not even have a "bytes" value type. In your original code it looks likeurl_imagewas a URL string on which you did a GET request to get its content.I followed your advice in changing
url_image1 to being abytestype and added the line:url_image = QtCore.QByteArray(url_image)` to:def show_image(self): json_dict = self.json url_image = MainWindow.sprite_find_official(json_dict) image = QImage() url_image = QtCore.QByteArray(url_image) image.loadFromData(url_image) QPixmap.loadFromData(image) image_label = QLabel() image_label.setPixmap(QPixmap(image))Traceback:
Traceback (most recent call last): File "c:\Users\Nader\OneDrive\Desktop\Coding\testing.py", line 68, in show_image image.loadFromData(url_image) TypeError: arguments did not match any overloaded call: loadFromData(self, PyQt6.sip.array[bytes], format: str = None): argument 1 has unexpected type 'QJsonValue' loadFromData(self, QByteArray, format: str = None): argument 1 has unexpected type 'QJsonValue'@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
Your value at dict["sprites"]["other"]["official-artwork"]["front_default"] is apparently a QJsonValue with a QJsonValue::String/str value instead.So I should do something like this for that function?
def sprite_find_official(dict): return QtCore.QJsonValue(dict["sprites"]["other"]["official-artwork"]["front_default"])This returns this Traceback:
TypeError: arguments did not match any overloaded call: QByteArray(): too many arguments QByteArray(int, bytes): argument 1 has unexpected type 'QJsonValue' QByteArray(QByteArray): argument 1 has unexpected type 'QJsonValue'So I doubt that is what you wanted.
@gunraidan
Insprite_find_official(dict)what exactly doesprint dict["sprites"]["other"]["official-artwork"]["front_default"]show? -
@gunraidan
Insprite_find_official(dict)what exactly doesprint dict["sprites"]["other"]["official-artwork"]["front_default"]show?@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
Insprite_find_official(dict)what exactly doesprint dict["sprites"]["other"]["official-artwork"]["front_default"]show?When printed it shows:
<PyQt6.QtCore.QJsonValue object at 0x0000027D7D106730> -
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
Insprite_find_official(dict)what exactly doesprint dict["sprites"]["other"]["official-artwork"]["front_default"]show?When printed it shows:
<PyQt6.QtCore.QJsonValue object at 0x0000027D7D106730>@gunraidan
So it is indeed not a byte array, hence the error message. You need to find out what it is. I think:print dict["sprites"]["other"]["official-artwork"]["front_default"].type()and see https://doc.qt.io/qt-5/qjsonvalue.html#Type-enum. You are supposed to know what is there, I do not. If you got this code from somewhere you ought look at that. I previously said I don't see how JSON can have a value which is a byte array, so I do not know why you think it's OK to pass to
QImage.loadFromData(). In your original codeurl_imagewas a string of the URL for an image, when did it become binary data? -
@gunraidan
So it is indeed not a byte array, hence the error message. You need to find out what it is. I think:print dict["sprites"]["other"]["official-artwork"]["front_default"].type()and see https://doc.qt.io/qt-5/qjsonvalue.html#Type-enum. You are supposed to know what is there, I do not. If you got this code from somewhere you ought look at that. I previously said I don't see how JSON can have a value which is a byte array, so I do not know why you think it's OK to pass to
QImage.loadFromData(). In your original codeurl_imagewas a string of the URL for an image, when did it become binary data?@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
So it is indeed not a byte array, hence the error message. You need to find out what it is. I think:print dict["sprites"]["other"]["official-artwork"]["front_default"].type()I get this:
Type.StringNow I'm confused why my initial coded didn't work since I initially had it convert it fully to a string
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
I previously said I don't see how JSON can have a value which is a byte array, so I do not know why you think it's OK to pass to
QImage.loadFromData(). In your original codeurl_imagewas a string of the URL for an image, when did it become binary data?I assumed that's what you suggested from the bottom post:
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
image.loadFromData(url_image)apparently expectsurl_imageto be aQByteArrayor in Python somehting like abytesarray. Your value atdict["sprites"]["other"]["official-artwork"]["front_default"]is apparently aQJsonValuewith aQJsonValue::String/strvalue instead. -
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
So it is indeed not a byte array, hence the error message. You need to find out what it is. I think:print dict["sprites"]["other"]["official-artwork"]["front_default"].type()I get this:
Type.StringNow I'm confused why my initial coded didn't work since I initially had it convert it fully to a string
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
I previously said I don't see how JSON can have a value which is a byte array, so I do not know why you think it's OK to pass to
QImage.loadFromData(). In your original codeurl_imagewas a string of the URL for an image, when did it become binary data?I assumed that's what you suggested from the bottom post:
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
@gunraidan
image.loadFromData(url_image)apparently expectsurl_imageto be aQByteArrayor in Python somehting like abytesarray. Your value atdict["sprites"]["other"]["official-artwork"]["front_default"]is apparently aQJsonValuewith aQJsonValue::String/strvalue instead.Type.StringThen
print dict["sprites"]["other"]["official-artwork"]["front_default"].toString()should should you its value.Can we take a step back? You started out with:
url_image = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png" image = QImage() image.loadFromData(requests.get(url_image).content)You did not pass
url_imagedirectly toQImage.loadFromData()did you? You had to pass it torequests.get(url_image).content, to get the actual binary bytes forloadFromData().But now you read
url_imagefrom the JSON you are passing it directly toloadFromData(). But if it's still a string URL you have not done therequest.get()work at all? Hence all the error messages about passing aQJsonValueor "string" where "bytes" are expected.Assuming your value from the JSON file is still a string like
http://...--- only you know this, I do not --- you have to do the sameimage.loadFromData(requests.get(url_image).content)as you did before. -
Type.StringThen
print dict["sprites"]["other"]["official-artwork"]["front_default"].toString()should should you its value.Can we take a step back? You started out with:
url_image = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png" image = QImage() image.loadFromData(requests.get(url_image).content)You did not pass
url_imagedirectly toQImage.loadFromData()did you? You had to pass it torequests.get(url_image).content, to get the actual binary bytes forloadFromData().But now you read
url_imagefrom the JSON you are passing it directly toloadFromData(). But if it's still a string URL you have not done therequest.get()work at all? Hence all the error messages about passing aQJsonValueor "string" where "bytes" are expected.Assuming your value from the JSON file is still a string like
http://...--- only you know this, I do not --- you have to do the sameimage.loadFromData(requests.get(url_image).content)as you did before.@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
Type.StringThen
print dict["sprites"]["other"]["official-artwork"]["front_default"].toString()should should you its value.Can we take a step back? You started out with:
url_image = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png" image = QImage() image.loadFromData(requests.get(url_image).content)You did not pass
url_imagedirectly toQImage.loadFromData()did you? You had to pass it torequests.get(url_image).content, to get the actual binary bytes forloadFromData().But now you read
url_imagefrom the JSON you are passing it directly toloadFromData(). But if it's still a string URL you have not done therequest.get()work at all? Hence all the error messages about passing aQJsonValueor "string" where "bytes" are expected.Assuming your value from the JSON file is still a string like
http://...--- only you know this, I do not --- you have to do the sameimage.loadFromData(requests.get(url_image).content)as you did before.Didn't know I still needed to use
requests. This works:import sys import requests from PyQt6 import QtNetwork from PyQt6.QtGui import* from PyQt6.QtWidgets import* from PyQt6 import QtCore from PyQt6.QtCore import pyqtSignal, QUrl class MainWindow(QWidget): image_get = pyqtSignal(name= 'imageGet') def __init__ (self): super().__init__() self.setWindowTitle("Show Image") self.start_button() self.setGeometry(200,300,400,500) self.image_screen = QLabel(self) self.image_screen.setPixmap(QPixmap()) self.image_screen.setGeometry(180, -25, 200, 300) self.imageGet.connect(self.show_image) self.manager = QtNetwork.QNetworkAccessManager() self.show() def start_button(self): self.button_s = QPushButton(self) self.button_s.clicked.connect(self.start_button_click) self.button_s.setText("Start") self.button_s.setStyleSheet("QPushButton" "{" "background:red;}" "QPushButton:pressed" "{" "background:green;}" ) self.button_s.resize (48,48) self.button_s.move(170,412) def start_button_click(self): print("start") url = "https://pokeapi.co/api/v2/pokemon/25" self.site_request(url) def site_request(self, url): req = QtNetwork.QNetworkRequest(QUrl(url)) self.nam = QtNetwork.QNetworkAccessManager() self.nam.finished.connect(self.handle_request) self.nam.get(req) def handle_request(self, reply): json2qt = QtCore.QJsonDocument.fromJson er = reply.error() if er == QtNetwork.QNetworkReply.NetworkError.NoError: qbyte = reply.readAll() self.json = json2qt(qbyte) self.image_get.emit() self.image_label.show() else: print ("Error") print(reply.errorString()) def sprite_find_official(dict): return dict["sprites"]["other"]["official-artwork"]["front_default"].toString() def show_image(self): json_dict = self.json url_image = MainWindow.sprite_find_official(json_dict) print(url_image) image = QImage() image.loadFromData(requests.get(url_image).content) self.image_label = QLabel() self.image_label.setPixmap(QPixmap(image)) if __name__ == '__main__': app = QApplication(sys.argv) ex = MainWindow() code = app.exec() sys.exit(code) -
@JonB said in How to display a url image in QNetwork Access Manager in PyQt6?:
Type.StringThen
print dict["sprites"]["other"]["official-artwork"]["front_default"].toString()should should you its value.Can we take a step back? You started out with:
url_image = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png" image = QImage() image.loadFromData(requests.get(url_image).content)You did not pass
url_imagedirectly toQImage.loadFromData()did you? You had to pass it torequests.get(url_image).content, to get the actual binary bytes forloadFromData().But now you read
url_imagefrom the JSON you are passing it directly toloadFromData(). But if it's still a string URL you have not done therequest.get()work at all? Hence all the error messages about passing aQJsonValueor "string" where "bytes" are expected.Assuming your value from the JSON file is still a string like
http://...--- only you know this, I do not --- you have to do the sameimage.loadFromData(requests.get(url_image).content)as you did before.Didn't know I still needed to use
requests. This works:import sys import requests from PyQt6 import QtNetwork from PyQt6.QtGui import* from PyQt6.QtWidgets import* from PyQt6 import QtCore from PyQt6.QtCore import pyqtSignal, QUrl class MainWindow(QWidget): image_get = pyqtSignal(name= 'imageGet') def __init__ (self): super().__init__() self.setWindowTitle("Show Image") self.start_button() self.setGeometry(200,300,400,500) self.image_screen = QLabel(self) self.image_screen.setPixmap(QPixmap()) self.image_screen.setGeometry(180, -25, 200, 300) self.imageGet.connect(self.show_image) self.manager = QtNetwork.QNetworkAccessManager() self.show() def start_button(self): self.button_s = QPushButton(self) self.button_s.clicked.connect(self.start_button_click) self.button_s.setText("Start") self.button_s.setStyleSheet("QPushButton" "{" "background:red;}" "QPushButton:pressed" "{" "background:green;}" ) self.button_s.resize (48,48) self.button_s.move(170,412) def start_button_click(self): print("start") url = "https://pokeapi.co/api/v2/pokemon/25" self.site_request(url) def site_request(self, url): req = QtNetwork.QNetworkRequest(QUrl(url)) self.nam = QtNetwork.QNetworkAccessManager() self.nam.finished.connect(self.handle_request) self.nam.get(req) def handle_request(self, reply): json2qt = QtCore.QJsonDocument.fromJson er = reply.error() if er == QtNetwork.QNetworkReply.NetworkError.NoError: qbyte = reply.readAll() self.json = json2qt(qbyte) self.image_get.emit() self.image_label.show() else: print ("Error") print(reply.errorString()) def sprite_find_official(dict): return dict["sprites"]["other"]["official-artwork"]["front_default"].toString() def show_image(self): json_dict = self.json url_image = MainWindow.sprite_find_official(json_dict) print(url_image) image = QImage() image.loadFromData(requests.get(url_image).content) self.image_label = QLabel() self.image_label.setPixmap(QPixmap(image)) if __name__ == '__main__': app = QApplication(sys.argv) ex = MainWindow() code = app.exec() sys.exit(code)@gunraidan said in How to display a url image in QNetwork Access Manager in PyQt6?:
Didn't know I still needed to use
requestsI don't know why you would not think you still needed it!? :) If all you change is you started with a literal string
url_image = "https:..."but now you read that string from a JSON file you still have just a string of the URL which you must request to get the content of the image file.