加载 .jpg 图像时,我遇到 QIcon.fromTheme 问题。我使用 QIcon.fromTheme 根据用户选择的主题切换应用程序中的图标。它与 .svg 图标(用于工具栏按钮)配合得很好,但是当我尝试将此方法与我想设置为背景主窗口的 .jpg 图像一起使用时,它不起作用(当用户切换主题时,背景图像也应该更改)。我尝试使用不同的 .jpg 图像,得到相同的结果:图像未显示。 shell 上没有错误信息。
如果我使用 QIcon 使用 .jpg 图像的相对路径,它就可以工作(显示图像,而不是切换图像)。
我使用 QLabel 和 .setPixmap 方法来保存 .jpg 图像。这是我的代码:
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QToolBar,
QStatusBar,
QAction,
QLabel
)
from PyQt5.QtCore import QSize, Qt, QSettings
from PyQt5.QtGui import QIcon, QPixmap
from sqlalchemy import create_engine
from model.models import Base
import resources_rc ## <-- compiled file from resources.qrc
import qtstylish
import sys
import os
root = os.path.dirname(__file__)
ICONS_WIDTH = 32
ICONS_HEIGHT = 32
try:
from ctypes import windll
myappid = "isDev.sistemaGestorUrimare.administrativo.version1.0"
windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
except ImportError:
pass
if not os.path.isfile(root + "/model/database.db"):
engine = create_engine("sqlite:///model/database.db", echo=True)
Base.metadata.create_all(engine)
settings = QSettings("Urimare", "urimareApp")
if not settings.contains("theme"):
settings.setValue("theme", "/resources/light")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Sistema Gestor Urimare")
self.setWindowIcon(QIcon(":/logo/logo.png"))
self.setStatusBar(QStatusBar(parent=self))
if settings.value("theme") == "/resources/light":
self.setStyleSheet(qtstylish.light())
else:
self.setStyleSheet(qtstylish.dark())
# setThemeName must contains the relative path to the diretory where index.theme is
QIcon.setThemeName(settings.value("theme"))
self.image = QIcon.fromTheme("background") ## <-- here is my problem
self.image_pixmap = self.image.pixmap(QSize(700, 700))
self.background = QLabel(parent=self)
self.background.setPixmap(self.image_pixmap)
self.background.setScaledContents(True)
self.new_client = QAction(parent=self, icon=QIcon.fromTheme("new_client"))
self.new_client.setStatusTip("Registrar nuevo cliente")
self.update_client = QAction(parent=self, icon=QIcon.fromTheme("update_client"))
self.update_client.setStatusTip("Actualizar cliente")
self.new_company = QAction(parent=self, icon=QIcon.fromTheme("new_company"))
self.new_company.setStatusTip("Registrar nueva compañía")
self.update_company = QAction(parent=self, icon=QIcon.fromTheme("update_company"))
self.update_company.setStatusTip("Actualizar compañía")
self.new_product = QAction(parent=self, icon=QIcon.fromTheme("new_product"))
self.new_product.setStatusTip("Añadir nuevo producto")
self.update_product = QAction(parent=self, icon=QIcon.fromTheme("update_product"))
self.update_product.setStatusTip("Actualizar producto")
self.new_quotation = QAction(parent=self, icon=QIcon.fromTheme("quotation"))
self.new_quotation.setStatusTip("Crear nueva cotización")
self.update_quotation = QAction(parent=self, icon=QIcon.fromTheme("update_quotation"))
self.update_quotation.setStatusTip("Actualizar cotización")
self.dark_light_theme = QAction(parent=self, icon=QIcon.fromTheme("dark_light_theme"))
self.dark_light_theme.setStatusTip("Cambiar tema de la aplicación")
self.dark_light_theme.triggered.connect(self.switch_theme)
self.toolbar = QToolBar(parent=self)
self.toolbar.setMovable(False)
self.toolbar.setIconSize(QSize(ICONS_WIDTH, ICONS_HEIGHT))
self.addToolBar(Qt.LeftToolBarArea, self.toolbar)
self.toolbar.addActions(
[
self.new_client,
self.update_client,
self.new_company,
self.update_company,
self.new_product,
self.update_product,
self.new_quotation,
self.update_quotation,
self.dark_light_theme
]
)
self.setCentralWidget(self.background)
self.resize(self.image_pixmap.width(), self.image_pixmap.height())
### SLOTS ###
def switch_theme(self):
if settings.value("theme") == "/resources/light":
settings.setValue("theme", "/resources/dark")
self.setStyleSheet(qtstylish.dark())
else:
settings.setValue("theme", "/resources/light")
self.setStyleSheet(qtstylish.light())
QIcon.setThemeName(settings.value("theme"))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
这是我的资源.qrc:
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="icons">
<file>resources/light/iconosSVGAzules/new_client.svg</file>
<file>resources/light/iconosSVGAzules/update_client.svg</file>
<file>resources/light/iconosSVGAzules/new_company.svg</file>
<file>resources/light/iconosSVGAzules/update_company.svg</file>
<file>resources/light/iconosSVGAzules/quotation.svg</file>
<file>resources/light/iconosSVGAzules/update_quotation.svg</file>
<file>resources/light/iconosSVGAzules/dark_light_theme.svg</file>
<file>resources/light/iconosSVGAzules/new_product.svg</file>
<file>resources/light/iconosSVGAzules/update_product.svg</file>
<file>resources/light/iconosSVGAzules/background.jpg</file>
<file>resources/light/iconosSVGAzules/cat.jpg</file>
<file>resources/light/index.theme</file>
<file>resources/dark/iconosSVGAmarillos/new_client.svg</file>
<file>resources/dark/iconosSVGAmarillos/update_client.svg</file>
<file>resources/dark/iconosSVGAmarillos/new_company.svg</file>
<file>resources/dark/iconosSVGAmarillos/update_company.svg</file>
<file>resources/dark/iconosSVGAmarillos/quotation.svg</file>
<file>resources/dark/iconosSVGAmarillos/update_quotation.svg</file>
<file>resources/dark/iconosSVGAmarillos/dark_light_theme.svg</file>
<file>resources/dark/iconosSVGAmarillos/new_product.svg</file>
<file>resources/dark/iconosSVGAmarillos/update_product.svg</file>
<file>resources/dark/iconosSVGAmarillos/background.jpg</file>
<file>resources/dark/iconosSVGAmarillos/cat.jpg</file>
<file>resources/dark/index.theme</file>
</qresource>
<qresource prefix="logo">
<file alias="logo.png">resources/iconosApp/urimareIcono02.png</file>
</qresource>
我错过了什么吗?也许 QIcon.fromTheme 不支持 .jpg 文件?预先感谢!
这是我的主窗口的打印:
fromTheme()
文档暗示它基于freedesktop图标规范(也链接在那里)。目前还不清楚它是如何被实际支持的,最重要的是,受尊重,但规范实际上解释了这方面:
图标文件
图标文件是可以加载并用作图标的图像。支持的图像文件格式为 PNG、XPM 和 SVG。 PNG 是推荐的位图格式,SVG 用于矢量化图标。由于向后兼容的原因,支持 XPM,不建议新主题使用 XPM 文件。对 SVG 的支持是可选的。
这意味着,出于兼容性原因,可能不支持 JPEG 图像(无论 QImageReader 插件是否支持它们,因为在兼容平台上使用
fromTheme()
时,Qt 可能依赖于本机图标主题加载)。
无论如何,出于性能和质量原因,JPEG 格式现在可以被认为是过时的(但仍然有效),并且出于此目的无论如何都应该考虑 PNG 格式,因为它通常提供更好的压缩/质量/速度几乎在任何情况下的比率。 如果可能,将这些 jpg 的源重新转换为 png,否则直接将这些 jpg 转换为 png,最终检查压缩比:大多数时候,您最终会得到相同的图像,但尺寸较小,或者,可能,相同的计算量。
另外,请记住,无论源文件的格式如何,
位图表示(QImage/QPixmap)仍然需要相同数量的进程内存:全白的 500x500 图像无论是否存储为 BMP,都会在磁盘上占用不同的大小、GIF、JPG 或 PNG,但一旦作为实际图像数据加载,将占用内存中的相同大小。