在另一个 class 中为小部件设置背景图像
setting background image for a widget in another class
我最近一直在学习 pyqt5 作为我的第一个 gui 框架。到目前为止,我一直在试验 QtStackedLayout。我目前有两个 window 屏幕,一个在 UI class 中创建,另一个在另一个单独的 class 中创建。我有两个顾虑:
- 一切正常,直到我开始尝试为 Window 添加背景图片 1. 没有显示图片,但代码运行正常。
- 开始时有一小段时间 window 会先显示一个,直到它加载到主 window,我尝试在实例化期间传递
self
对象作为某种父级来防止这种情况,但我认为我做得不对。
看下面的代码(我有错误的导入语句,我会整理一下)
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Ui(QWidget):
def setupUi(self, Main, width, height):
self.stack = QStackedLayout()
self.window_1 = WindowOne(width, height)
self.window_2 = QWidget(self)
self.window_2_UI()
self.stack.addWidget(self.window_1)
self.stack.addWidget(self.window_2)
# Only one button
self.btn = QPushButton("Change window", self)
# Create the central widget of your Main Window
self.main_widget = QWidget(self)
layout = QVBoxLayout(self.main_widget)
layout.addLayout(self.stack)
layout.addWidget(self.btn)
self.setCentralWidget(self.main_widget)
self.btn.clicked.connect(self.change_window)
def change_window(self):
if self.stack.currentIndex() == 0:
self.stack.setCurrentIndex(1)
else:
self.stack.setCurrentIndex(0)
def window_2_UI(self):
label = QLabel("In Window 2", self.window_2)
class WindowOne(QWidget):
def __init__(self, width, height):
super().__init__()
self.set_bg(width, height)
self.set_label()
# self.setStyleSheet("background-image: url(:resource/images/blue_bg.jpg)")
def set_label(self):
label = QLabel("In Window 1", self)
def set_bg(self, w, h):
oImage = QImage("resource/images/blue_bg.jpg")
sImage = oImage.scaled(QSize(w, h))
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
class Main(QMainWindow, Ui):
def __init__(self):
super().__init__()
self.w_width = 480
self.w_height = 720
self.resize(self.w_width, self.w_height)
self.init_ui()
self.setupUi(self, self.w_width, self.w_height)
def init_ui(self):
self.center()
self.setWindowTitle('Main Window')
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
if __name__ == "__main__":
app = QApplication(sys.argv)
M = Main()
M.show()
sys.exit(app.exec())
默认只有window(与widget不同)会使用QPalette的背景色,如果你想让widget使用QPalette的背景色你必须启用autoFillBackground
属性.
# ...
self.set_label(width, height)
self.setAutoFillBackground(True)
# ...
虽然你的代码有点乱,比如你建立了某些方法接收某些参数但你从不使用它们。最后我想你希望图像的背景是 re-scale 使用 window 的大小所以我重写了 resizeEvent() 方法以便缩放采用 window 的大小。
考虑到以上所有,我改进了你的代码:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.m_stacked_layout = QtWidgets.QStackedLayout()
self.widget_1 = WidgetOne()
self.widget_2 = QtWidgets.QWidget()
self.widget_2_UI()
self.m_stacked_layout.addWidget(self.widget_1)
self.m_stacked_layout.addWidget(self.widget_2)
button = QtWidgets.QPushButton(
"Change window", clicked=self.change_window
)
lay = QtWidgets.QVBoxLayout(self)
lay.addLayout(self.m_stacked_layout)
lay.addWidget(button)
@QtCore.pyqtSlot()
def change_window(self):
ix = self.m_stacked_layout.currentIndex()
self.m_stacked_layout.setCurrentIndex(1 if ix == 0 else 0)
def widget_2_UI(self):
label = QtWidgets.QLabel("In Window 2", self.widget_2)
class WidgetOne(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setAutoFillBackground(True)
self.set_label()
self.m_image = QtGui.QImage("resource/images/blue_bg.jpg")
def set_label(self):
label = QtWidgets.QLabel("In Window 1", self)
def resizeEvent(self, event):
palette = self.palette()
sImage = self.m_image.scaled(event.size())
palette.setBrush(10, QtGui.QBrush(sImage))
self.setPalette(palette)
super(WidgetOne, self).resizeEvent(event)
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
widget = Widget()
self.setCentralWidget(widget)
self.resize(480, 720)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec())
我最近一直在学习 pyqt5 作为我的第一个 gui 框架。到目前为止,我一直在试验 QtStackedLayout。我目前有两个 window 屏幕,一个在 UI class 中创建,另一个在另一个单独的 class 中创建。我有两个顾虑:
- 一切正常,直到我开始尝试为 Window 添加背景图片 1. 没有显示图片,但代码运行正常。
- 开始时有一小段时间 window 会先显示一个,直到它加载到主 window,我尝试在实例化期间传递
self
对象作为某种父级来防止这种情况,但我认为我做得不对。
看下面的代码(我有错误的导入语句,我会整理一下)
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Ui(QWidget):
def setupUi(self, Main, width, height):
self.stack = QStackedLayout()
self.window_1 = WindowOne(width, height)
self.window_2 = QWidget(self)
self.window_2_UI()
self.stack.addWidget(self.window_1)
self.stack.addWidget(self.window_2)
# Only one button
self.btn = QPushButton("Change window", self)
# Create the central widget of your Main Window
self.main_widget = QWidget(self)
layout = QVBoxLayout(self.main_widget)
layout.addLayout(self.stack)
layout.addWidget(self.btn)
self.setCentralWidget(self.main_widget)
self.btn.clicked.connect(self.change_window)
def change_window(self):
if self.stack.currentIndex() == 0:
self.stack.setCurrentIndex(1)
else:
self.stack.setCurrentIndex(0)
def window_2_UI(self):
label = QLabel("In Window 2", self.window_2)
class WindowOne(QWidget):
def __init__(self, width, height):
super().__init__()
self.set_bg(width, height)
self.set_label()
# self.setStyleSheet("background-image: url(:resource/images/blue_bg.jpg)")
def set_label(self):
label = QLabel("In Window 1", self)
def set_bg(self, w, h):
oImage = QImage("resource/images/blue_bg.jpg")
sImage = oImage.scaled(QSize(w, h))
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
class Main(QMainWindow, Ui):
def __init__(self):
super().__init__()
self.w_width = 480
self.w_height = 720
self.resize(self.w_width, self.w_height)
self.init_ui()
self.setupUi(self, self.w_width, self.w_height)
def init_ui(self):
self.center()
self.setWindowTitle('Main Window')
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
if __name__ == "__main__":
app = QApplication(sys.argv)
M = Main()
M.show()
sys.exit(app.exec())
默认只有window(与widget不同)会使用QPalette的背景色,如果你想让widget使用QPalette的背景色你必须启用autoFillBackground
属性.
# ...
self.set_label(width, height)
self.setAutoFillBackground(True)
# ...
虽然你的代码有点乱,比如你建立了某些方法接收某些参数但你从不使用它们。最后我想你希望图像的背景是 re-scale 使用 window 的大小所以我重写了 resizeEvent() 方法以便缩放采用 window 的大小。
考虑到以上所有,我改进了你的代码:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.m_stacked_layout = QtWidgets.QStackedLayout()
self.widget_1 = WidgetOne()
self.widget_2 = QtWidgets.QWidget()
self.widget_2_UI()
self.m_stacked_layout.addWidget(self.widget_1)
self.m_stacked_layout.addWidget(self.widget_2)
button = QtWidgets.QPushButton(
"Change window", clicked=self.change_window
)
lay = QtWidgets.QVBoxLayout(self)
lay.addLayout(self.m_stacked_layout)
lay.addWidget(button)
@QtCore.pyqtSlot()
def change_window(self):
ix = self.m_stacked_layout.currentIndex()
self.m_stacked_layout.setCurrentIndex(1 if ix == 0 else 0)
def widget_2_UI(self):
label = QtWidgets.QLabel("In Window 2", self.widget_2)
class WidgetOne(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setAutoFillBackground(True)
self.set_label()
self.m_image = QtGui.QImage("resource/images/blue_bg.jpg")
def set_label(self):
label = QtWidgets.QLabel("In Window 1", self)
def resizeEvent(self, event):
palette = self.palette()
sImage = self.m_image.scaled(event.size())
palette.setBrush(10, QtGui.QBrush(sImage))
self.setPalette(palette)
super(WidgetOne, self).resizeEvent(event)
class Main(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
widget = Widget()
self.setCentralWidget(widget)
self.resize(480, 720)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec())