I am trying to display an image from a URL in pyside6, but can't get anything to work.
def getIcon(data):
iconID = data['weather'][0]['icon']
icon = QPixmap("http://openweathermap.org/img/w/" + iconID + ".png");
return icon
And
self.temperatureIcon = QtWidgets.QLabel(self).setPixmap(getIcon(self.weatherData))
is the code I have.
QPixmap does not download the image from a url so you must download it for example using QNetworkAccessManager:
import sys
from functools import cached_property
from PySide6.QtCore import Signal, QObject, Qt, QUrl
from PySide6.QtGui import QImage, QPixmap
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
from PySide6.QtWidgets import (
QApplication,
QGridLayout,
QLabel,
QLineEdit,
QPushButton,
QWidget,
)
class ImageDownloader(QObject):
finished = Signal(QImage)
def __init__(self, parent=None):
super().__init__(parent)
self.manager.finished.connect(self.handle_finished)
#cached_property
def manager(self):
return QNetworkAccessManager()
def start_download(self, url):
self.manager.get(QNetworkRequest(url))
def handle_finished(self, reply):
if reply.error() != QNetworkReply.NoError:
print("error: ", reply.errorString())
return
image = QImage()
image.loadFromData(reply.readAll())
self.finished.emit(image)
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.lineedit = QLineEdit()
self.button = QPushButton("Start")
self.label = QLabel(alignment=Qt.AlignCenter)
lay = QGridLayout(self)
lay.addWidget(self.lineedit, 0, 0)
lay.addWidget(self.button, 0, 1)
lay.addWidget(self.label, 1, 0, 1, 2)
self.downloader = ImageDownloader()
self.downloader.finished.connect(self.handle_finished)
self.button.clicked.connect(self.handle_clicked)
self.lineedit.setText("http://openweathermap.org/img/wn/01d#2x.png")
self.resize(640, 480)
def handle_finished(self, image):
pixmap = QPixmap.fromImage(image)
self.label.setPixmap(pixmap)
def handle_clicked(self):
url = QUrl.fromUserInput(self.lineedit.text())
self.downloader.start_download(url)
def main():
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
Here's another simple solution\example:
import sys
import requests
from PySide6.QtGui import QPixmap, QScreen
from PySide6.QtWidgets import QApplication, QWidget, QLabel
URL = 'https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_(test_image).png'
class App(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('getAndSetImageFromURL()')
self.label = QLabel(self)
self.pixmap = QPixmap()
self.getAndSetImageFromURL(URL)
self.resize(self.pixmap.width(),self.pixmap.height())
screenSize = QScreen.availableGeometry(QApplication.primaryScreen())
frmX = (screenSize.width () - self.width ())/2
frmY = (screenSize.height() - self.height())/2
self.move(frmX, frmY)
self.show()
def getAndSetImageFromURL(self,imageURL):
request = requests.get(imageURL)
self.pixmap.loadFromData(request.content)
self.label.setPixmap(self.pixmap)
#QApplication.processEvents() # uncoment if executed on loop
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = App()
sys.exit(app.exec())
which outputs:
import sys
import requests
import PySide6
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
from PySide6.QtWidgets import QTableView, QWidget, QApplication, QGridLayout, QHeaderView
from PySide6.QtCore import Qt, QAbstractTableModel, QObject, Signal, QUrl
from PySide6.QtGui import QColor, QIcon, QPixmap, QImage
from datetime import datetime
class MagicIcon():
def __init__(self, link):
self.link = link
self.icon = QIcon()
try:
response = requests.get(self.link)
pixmap = QPixmap()
pixmap.loadFromData(response.content)
self.icon = QIcon(pixmap)
except:
pass
class MainWindow(QWidget):
def __init__():
super().__init__()
self.setWindowIcon(MagicIcon(
"https://img.icons8.com/external-flatarticons-blue-flatarticons/65/000000/external-analysis-digital-marketing-flatarticons-blue-flatarticons-1.png"
).icon)
if __name__ == "__main__":
app = QApplication(sys.argv)
wid = MainWindow()
wid.show()
sys.exit(app.exec())
Use requests module to fetch image and store them.
Related
I found the icon of QPushButon is blurry when DPI scaling is enabled. Even if replaced by SVG, the icon is still blurred. Is there any way to make the icon clearer?
Here is the code:
# coding:utf-8
import os
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget
class Demo(QWidget):
def __init__(self):
super().__init__(parent=None)
self.button = QPushButton(' Shuffle all', self)
imagePath = "app/resource/images/random_play_all/Shuffle_normal.png"
self.button.setIcon(QIcon(imagePath))
self.button.move(self.width()//2-self.button.width() //
2, self.height()//2-self.button.height()//2)
if __name__ == '__main__':
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0"
os.environ["QT_SCALE_FACTOR"] = '1.25'
app = QApplication(sys.argv)
demo = Demo()
demo.show()
app.exec_()
The running result is shown in the figure below
I solved this problem by rewriting QIconEngine and setting Qt.AA_UseHighDpiPixmaps flag.
# coding:utf-8
import os
import sys
from PyQt5.QtCore import QPoint, QRect, QSize, Qt
from PyQt5.QtGui import QIcon, QIconEngine, QImage, QPainter, QPixmap
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget
class PixmapIconEngine(QIconEngine):
""" Pixmap icon engine """
def __init__(self, iconPath: str):
self.iconPath = iconPath
super().__init__()
def paint(self, painter: QPainter, rect: QRect, mode: QIcon.Mode, state: QIcon.State):
painter.setRenderHints(QPainter.Antialiasing |
QPainter.SmoothPixmapTransform)
painter.drawImage(rect, QImage(self.iconPath))
def pixmap(self, size: QSize, mode: QIcon.Mode, state: QIcon.State) -> QPixmap:
pixmap = QPixmap(size)
pixmap.fill(Qt.transparent)
self.paint(QPainter(pixmap), QRect(QPoint(0, 0), size), mode, state)
return pixmap
class Icon(QIcon):
def __init__(self, iconPath: str):
self.iconPath = iconPath
super().__init__(PixmapIconEngine(iconPath))
class Demo(QWidget):
def __init__(self):
super().__init__(parent=None)
self.button = QPushButton(' Shuffle all', self)
imagePath = "resource/images/random_play_all/Shuffle_normal.png"
self.button.setIcon(Icon(imagePath))
self.button.move(self.width()//2-self.button.width() //
2, self.height()//2-self.button.height()//2)
if __name__ == '__main__':
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0"
os.environ["QT_SCALE_FACTOR"] = '1.25'
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv)
demo = Demo()
demo.show()
app.exec_()
Here is the result
i would like to embed the glb file to pyqt gui with vtk python library. I wrote pieces of code but it does not embed the sketch to the pyqt gui. Everytime there have been placing in the second windows form. Here is the example:
And here is the my source code that i am trying to embed it to gui:
import sys
import vtk
try:
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtWidgets import QWidget, QSizePolicy, QPushButton, QVBoxLayout, QFrame
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, pyqtSignal, QTimer, QObject, QSize, QEvent
except ImportError:
raise ImportError("Cannot load either PyQt5")
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class Menu(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
importer = vtk.vtkGLTFImporter()
importer.SetFileName("uydu.glb")
importer.Read()
global vtk_render_window
vtk_renderer = importer.GetRenderer()
vtk_render_window = importer.GetRenderWindow()
self.setGeometry(190, 300, 300, 200)
self.setWindowTitle('Simple menu')
self.show()
self.frame = QFrame()
self.vl = QVBoxLayout()
vtk_render_window_interactor = QVTKRenderWindowInteractor(self.frame)
vtk_render_window_interactor.SetRenderWindow(vtk_render_window)
colors = vtk.vtkNamedColors()
vtk_renderer.SetBackground(colors.GetColor3d('White'))
actor = vtk.vtkActor()
actor.GetProperty().SetDiffuse(0.8)
actor.GetProperty().SetDiffuseColor(colors.GetColor3d('Black'))
actor.GetProperty().SetSpecular(0.3)
actor.GetProperty().SetSpecularPower(60.0)
vtk_render_window.SetSize(600, 600)
vtk_render_window.SetWindowName('3D Visualizer')
vtk_render_window_interactor.Initialize()
# Add callback for getting data from Arduino
#vtk_render_window_interactor.CreateRepeatingTimer(1000)
#vtk_render_window_interactor.AddObserver("TimerEvent", information_callback)
global vtk_actors
vtk_actors = vtk_renderer.GetActors
self.vl.addWidget(vtk_render_window_interactor)
self.renderer = vtk.vtkRenderer()
self.renderer.SetBackground(.3, .4, .5 )
self.renwin = vtk_render_window_interactor.GetRenderWindow()
self.renwin.AddRenderer(self.renderer)
# An interactor
self.inter = self.renwin.GetInteractor()
# add the custom style
self.style = MouseInteractorHighLightActor()
self.style.SetDefaultRenderer(self.renderer)
vtk_render_window_interactor.GetRenderWindow().AddRenderer(self.renderer)
#self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.inter.SetInteractorStyle(self.style)
#self.iren.SetInteractorStyle(self.inter)
#self.iren = self.vtkWidget.GetRenderWindow().SetInteractor(self.inter)
self.renderer.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.inter.Initialize()
self.inter.Start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Menu()
sys.exit(app.exec_())
You have to pass the renderWindow of vtkGLTFImporter as rw parameter to the QVTKRenderWindowInteractor widget:
import sys
import vtk
try:
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtWidgets import QWidget, QVBoxLayout
except ImportError:
raise ImportError("Cannot load either PyQt5")
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class Menu(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(190, 300, 300, 200)
self.setWindowTitle("Simple menu")
self.container = QWidget()
vl = QVBoxLayout(self.container)
self.setCentralWidget(self.container)
self.resize(640, 480)
importer = vtk.vtkGLTFImporter()
importer.SetFileName("uydu.glb")
importer.Read()
renderer = importer.GetRenderer()
render_window = importer.GetRenderWindow()
vtk_widget = QVTKRenderWindowInteractor(rw=render_window)
vl.addWidget(vtk_widget)
vtk_widget.Initialize()
vtk_widget.Start()
colors = vtk.vtkNamedColors()
renderer.SetBackground(colors.GetColor3d("White"))
renderer.ResetCamera()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Menu()
ex.show()
sys.exit(app.exec_())
I am trying to create a PyQt5 - QLabel with both image and text. I would like to have a text at the bottom of the image. Below is a part of the code
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Window(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
l4=QLabel()
l4.setText('delete')
l4.setAlignment(Qt.AlignBottom)
pixmap = QPixmap("/home/moh/Documents/My_GUI/Icons/Delete.png")
l4.setPixmap(pixmap)
l4.setAlignment(Qt.AlignTop)
self.layout = QGridLayout()
self.layout.addWidget(l4, 0, 0)
self.setLayout(self.layout)
self.show()
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
You have to use 2 QLabel in a QVBoxLayout:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
class Window(QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
pixmap_label = QLabel(
pixmap=QPixmap("/home/moh/Documents/My_GUI/Icons/Delete.png")
)
text_label = QLabel(text="delete")
lay = QVBoxLayout(self)
lay.addWidget(pixmap_label, alignment=Qt.AlignCenter)
lay.addWidget(text_label, alignment=Qt.AlignCenter)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
If you want to use a circle Qlabel image, use this code:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainterPath, QPainter
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
class Label(QLabel):
def __init__(self, *args, antialiasing=True, **kwargs):
super(Label, self).__init__(*args, **kwargs)
self.Antialiasing = antialiasing
self.setMaximumSize(90, 90)
self.setMinimumSize(90, 90)
self.radius = 45
self.target = QPixmap(self.size())
self.target.fill(Qt.transparent)
p = QPixmap("Image.jpg").scaled(
90, 90, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
painter = QPainter(self.target)
if self.Antialiasing:
painter.setRenderHint(QPainter.Antialiasing, True)
painter.setRenderHint(QPainter.HighQualityAntialiasing, True)
painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
path = QPainterPath()
path.addRoundedRect(
0, 0, self.width(), self.height(), self.radius, self.radius)
painter.setClipPath(path)
painter.drawPixmap(0, 0, p)
self.setPixmap(self.target)
class Window(QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
pixmap_label = Label()
text_label = QLabel(text="delete")
lay = QVBoxLayout(self)
lay.addWidget(pixmap_label, alignment=Qt.AlignCenter)
lay.addWidget(text_label, alignment=Qt.AlignCenter)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
I am making a very simple browser with a search box using PyQt5 WebKit. This is the code I'm using:
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebKitWidgets import QWebView
class App(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.searchbox = QLineEdit("", self)
self.go = QPushButton('Go', self)
self.go.clicked.connect(self.gourl)
self.webview = Browser()
self.grid = QGridLayout(centralWidget)
self.grid.addWidget(self.webview, 0, 0, 1, 4)
self.grid.addWidget(self.searchbox, 1, 0)
self.grid.addWidget(self.go, 1, 1)
def gourl(self):
url = self.searchbox.text()
self.webview.load(QUrl(url))
class Browser(QWebView): #(QWebView):
windowList = []
def createWindow(self, QWebEnginePage_WebWindowType):
App.setCentralWidget(Browser())
#new_window.show()
self.windowList.append(App())
return Browser()
if __name__ == "__main__":
app = QApplication(sys.argv)
box = App()
box.setWindowTitle('Browser')
box.resize(600, 500)
box.show()
sys.exit(app.exec_())
I want to keep the URL in the box updated with whatever current URL the user is on. I have no idea how to go about this, any help would be appreciated.
Below is a re-write of your example which should do what you want.
The Browser class has been fixed so that it creates a new instance of App when a new window is requested. You can test this by right-clicking on a link and selecting Open in New Window. The search box will automatically update with the new url whenever it changes.
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebKitWidgets import QWebView
class App(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.searchbox = QLineEdit("", self)
self.go = QPushButton('Go', self)
self.go.clicked.connect(self.gourl)
self.webview = Browser()
self.webview.urlChanged.connect(self.handleUrlChanged)
self.grid = QGridLayout(centralWidget)
self.grid.addWidget(self.webview, 0, 0, 1, 4)
self.grid.addWidget(self.searchbox, 1, 0)
self.grid.addWidget(self.go, 1, 1)
def gourl(self):
url = self.searchbox.text()
self.webview.load(QUrl(url))
def handleUrlChanged(self, url):
self.searchbox.setText(url.toString())
class Browser(QWebView):
windowList = []
def createWindow(self, wintype):
window = App()
self.windowList.append(window)
window.show()
return window.webview
def closeEvent(self, event):
self.windowList.remove(self)
super().closeEvent(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
box = App()
box.setWindowTitle('Browser')
box.resize(600, 500)
box.show()
sys.exit(app.exec_())
how can i set Qicon from a url in PYQT , can you give me an example?
a basic example would be:
from PyQt4.QtGui import *
from PyQt4.QtCore import QUrl
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest
app = QApplication([])
url = "http://www.google.com/favicon.ico"
lbl = QLabel("loading...")
nam = QNetworkAccessManager()
def finishRequest(reply):
img = QImage()
img.loadFromData(reply.readAll())
lbl.setPixmap(QPixmap(img))
nam.finished.connect(finishRequest)
nam.get(QNetworkRequest(QUrl(url)))
lbl.show()
app.exec_()
use requests.get method to download the image and create a QIcon from it.
import sys
import requests
import PySide6
from PySide6.QtWidgets import QTableView, QWidget, QApplication, QGridLayout, QHeaderView
from PySide6.QtCore import Qt, QAbstractTableModel
from PySide6.QtGui import QColor, QIcon, QPixmap
from datetime import datetime
class MagicIcon():
def __init__(self, link):
self.link = link
self.icon = QIcon()
try:
response = requests.get(self.link)
pixmap = QPixmap()
pixmap.loadFromData(response.content)
self.icon = QIcon(pixmap)
except:
pass
class MainWindow(QWidget):
def __init__():
super().__init__()
self.setWindowIcon(MagicIcon(
"https://img.icons8.com/external-flatarticons-blue-flatarticons/65/000000/external-analysis-digital-marketing-flatarticons-blue-flatarticons-1.png"
).icon)
if __name__ == "__main__":
app = QApplication(sys.argv)
wid = MainWindow()
wid.show()
sys.exit(app.exec())