自定义QScrollArea
Custom QScrollArea
我已经开发了一些生成以下输出行的功能:6 个 QLabels 分配给它们的像素图,以及 6 个额外的 QLabels 和位于像素图 QLabels 上的分配文本。在上面的标签集下方,我在循环重复之前添加了一个包含更多信息的附加 QLabel。下面是一个示例图片:
生成的输出基于函数拉入的列表对象的长度,有时会比 window 中显示的要大。我已经多次尝试创建一个滚动区域来添加我的输出,但是没有任何方法可以重新创建上面显示的布局。 QVBoxLayout 和 QHBoxLayout 将分别垂直或水平堆叠每个单独的 QLabel,这不是我要创建的视觉效果(如上所示)。下面是一个比 window:
中显示的更长的输出示例
不确定是否有其他方法可以创建我正在尝试组合的布局,但是如果有人能想出一个不包含 QVBoxLayout 或 QHBoxLayout 的解决方案来将滚动条添加到 window, 那太好了。以下是生成错误输出的代码:
def create_sample_images(self, sample_numbers):
# example of sample_numbers = [01,18,2022,1,2,3,4,5,6,2.0,0 Million,Roll]
# print(sample_numbers)
# print(len(sample_numbers))
# creating the scroll area, widget and vbox
self.scroll = QScrollArea()
self.widget = QWidget()
self.vbox = QVBoxLayout()
if len(sample_numbers) != 0:
i = 1
x = 40
y = 75
w = 100
h = 100
for item in sample_numbers:
# print("Here is an item")
result = item[3:9]
datevalue = item[:3]
jackpotvalue = item[10]
outcome = item[11]
historylabel = ["DATE: " + str(datevalue[0]) + '-' + str(datevalue[1])
+ '-' + str(datevalue[2])
+ ' | ' + "PRIZE: " + jackpotvalue
+ ' | ' + "ROLL (NO WINNER)"]
result.append(historylabel)
# print(result)
# print(type(result))
# print(datevalue)
# print(jackpotvalue)
# print(outcome)
# print(historylabel)
for obj in result:
# print("Here is an obj in item")
self.outputlabel = QLabel(self)
self.labeltext = QLabel(self)
self.labeltext.setText(str(obj))
self.labeltext.setAlignment(QtCore.Qt.AlignCenter)
self.labeltext.setStyleSheet("QLabel { color : black; }")
if i < 6:
self.pixmap = QPixmap(u":/graphics/Images/lottoball.png")
else:
self.pixmap = QPixmap(u":/graphics/Images/lottoslip.jpg")
self.outputlabel.setPixmap(self.pixmap)
self.outputlabel.resize(self.pixmap.width(),
self.pixmap.height())
self.outputlabel.setGeometry(x, y, w, h)
self.labeltext.setGeometry(x, y, w, h)
# adding labels to vbox
self.vbox.addWidget(self.outputlabel)
self.vbox.addWidget(self.labeltext)
x += 125
i += 1
if i == 7:
i += 1
x = 40
y += 125
elif i > 7:
self.outputlabel.setPixmap(None)
self.labeltext.setText(historylabel[0])
self.labeltext.setStyleSheet("QLabel { color : white; }")
self.labeltext.adjustSize()
# adding label to vbox
self.vbox.addWidget(self.labeltext)
i = 1
x = 40
y += 50
self.widget.setLayout(self.vbox)
# Scroll Area Properties
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.show()
下面是错误输出的示例。所有小部件都堆叠在一起并垂直或水平显示 (vbox/hbox):
您可以使用“gridlayout”或像下面的示例一样使用“setMinimumSize”为您的项目设置限制
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class main(QMainWindow):
def __init__(self):
super().__init__()
self.scroll = QScrollArea()
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
self.widget = QWidget()
self.scroll.setWidgetResizable(True)
# => grid set
self.grid = QGridLayout(self.widget)
self.grid.setContentsMargins(10,40,10,20)
self.grid.setHorizontalSpacing(20)
self.grid.setVerticalSpacing(10)
for i in range(6):
for j in range(3):
if i % 2 == 1:
self.grid.addWidget(QLabel("DateTime => 01.19.2022 | 0 | ROLL"), i,j, 1,3)
break
else:
self.label = QLabel("9")
self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.label.setStyleSheet("background-color: red;")
# => item set minimum size !
self.label.setMinimumSize(120,120)
self.grid.addWidget(self.label, i, j, 1,1)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.resize(600,550)
self.show()
app = QApplication([])
window = main()
app.exec()
使用 SimoN SavioR 的提示和上面的示例代码,我想出了如何重构我的函数来生成我正在寻找的结果,这模仿了 SimoN 在他的示例中生成的结果。首先,我认为我在以前的代码中遇到的最大问题是使用 Vbox 而不是 Grid,并将 Widget 分配给 Vbox 而不是将 Widget 分配给布局。下面是我的函数的新代码,现在可以按需运行,以及我得到的新输出的示例屏幕截图。在研究了 SimoN 的代码并了解它如何产生输出后,我设法将某些代码块集成到我自己的原始代码中,以使该功能正常工作并以我最初想要的方式显示输出。我从 SimoN 借用的主要代码块是 for 循环之前的两个块,以及 for 循环之后的块。我能够保留我的原始代码的所有其余部分,并进行一些细微的修改以使其协同工作。
def create_sample_images(self, sample_numbers):
displaytext = "Displaying " + str(len(sample_numbers)) + " results"
self.setWindowTitle(displaytext)
# print(sample_numbers)
# print(len(sample_numbers))
# self.gridlayout = QGridLayout()
# # self.groupbox = QGroupBox("Results")
# self.vbox = QVBoxLayout()
# self.scroll = QScrollArea()
self.scroll = QScrollArea()
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self.widget = QWidget()
self.scroll.setWidgetResizable(True)
# => grid set
self.gridlayout = QGridLayout(self.widget) # widget is parent widget
self.gridlayout.setContentsMargins(10, 40, 10, 20) # left, top, right, bottom
self.gridlayout.setHorizontalSpacing(20)
self.gridlayout.setVerticalSpacing(10)
if len(sample_numbers) != 0:
i = 1
ballrow = 0
inforow = 1
ballcolumn = 0
infocolumn = 0
for item in sample_numbers:
# print("Here is an item")
result = item[3:9]
datevalue = item[:3]
jackpotvalue = item[10]
outcome = item[11]
if outcome == "Roll":
historylabel = ["Date: " + str(datevalue[0]) + '-' + str(datevalue[1])
+ '-' + str(datevalue[2])
+ ' | ' + "Prize: " + jackpotvalue
+ ' | ' + "Roll (No Winner)"]
else:
historylabel = ["Date: " + str(datevalue[0]) + '-' + str(datevalue[1])
+ '-' + str(datevalue[2])
+ ' | ' + "Prize: " + jackpotvalue
+ ' | ' + "Jackpot Winner(s)"]
result.append(historylabel)
# print(result)
# print(type(result))
# print(datevalue)
# print(jackpotvalue)
# print(outcome)
# print(historylabel)
for obj in result:
# print("Here is an obj in item")
self.outputlabel = QLabel(self)
self.labeltext = QLabel(self)
self.labeltext.setText(str(obj))
self.labeltext.setAlignment(QtCore.Qt.AlignCenter)
self.labeltext.setStyleSheet("QLabel { color : black; }")
self.labeltext.setFont(QFont("Arial", 18))
if i < 6:
self.pixmap = QPixmap(u":/graphics/whiteball.png")
elif i == 6:
self.pixmap = QPixmap(u":/graphics/redball.png")
self.outputlabel.setPixmap(self.pixmap)
self.outputlabel.setScaledContents(Qt.KeepAspectRatio)
# self.outputlabel.resize(self.pixmap.width(),
# self.pixmap.height())
self.outputlabel.setMinimumSize(112, 112)
self.labeltext.setMinimumSize(56, 56)
self.outputlabel.setMaximumSize(112, 112)
self.labeltext.setMaximumSize(800, 800)
self.gridlayout.addWidget(self.outputlabel, ballrow, ballcolumn, 1, 1)
self.gridlayout.addWidget(self.labeltext, ballrow, ballcolumn, 1, 1)
# self.groupbox.setLayout(self.gridlayout)
# self.scroll.setLayout(self.gridlayout)
i += 1
ballcolumn += 1
if i == 7:
i += 1
inforow += 1
elif i > 7:
self.outputlabel.setPixmap(None)
self.labeltext.setText(" " + str(historylabel[0]))
self.labeltext.setStyleSheet("QLabel { color : #7393B3; }") #steel blue 4682B4 bright blue 0096FF denim 6F8FAF royal blue 4169E1 blue gray 7393B3
self.labeltext.setFont(QFont("Arial", 18))
self.labeltext.setAlignment(Qt.AlignmentFlag.AlignLeft)
self.gridlayout.addWidget(self.labeltext, inforow, infocolumn, 1, 10)
i = 1
inforow += 2
ballrow += 3
ballcolumn = 0
# widget is parent widget of grid layout. being added to scroll layout
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
# resize entire window show to display all objects (width, height)
# self.resize(1000, 550)
self.show()
else:
x = 265
y = 225
w = 275
h = 100
self.labeltext = QLabel(self)
self.labeltext.setText("Sorry, no results to display. Please try again.")
self.labeltext.setStyleSheet("QLabel { color : white; }")
self.labeltext.setGeometry(x, y, w, h)
self.show()
感谢 SimoN SavioR 帮助我更好地理解布局;没有他们的贡献,不可能找到最终的解决方案!
我已经开发了一些生成以下输出行的功能:6 个 QLabels 分配给它们的像素图,以及 6 个额外的 QLabels 和位于像素图 QLabels 上的分配文本。在上面的标签集下方,我在循环重复之前添加了一个包含更多信息的附加 QLabel。下面是一个示例图片:
生成的输出基于函数拉入的列表对象的长度,有时会比 window 中显示的要大。我已经多次尝试创建一个滚动区域来添加我的输出,但是没有任何方法可以重新创建上面显示的布局。 QVBoxLayout 和 QHBoxLayout 将分别垂直或水平堆叠每个单独的 QLabel,这不是我要创建的视觉效果(如上所示)。下面是一个比 window:
中显示的更长的输出示例不确定是否有其他方法可以创建我正在尝试组合的布局,但是如果有人能想出一个不包含 QVBoxLayout 或 QHBoxLayout 的解决方案来将滚动条添加到 window, 那太好了。以下是生成错误输出的代码:
def create_sample_images(self, sample_numbers):
# example of sample_numbers = [01,18,2022,1,2,3,4,5,6,2.0,0 Million,Roll]
# print(sample_numbers)
# print(len(sample_numbers))
# creating the scroll area, widget and vbox
self.scroll = QScrollArea()
self.widget = QWidget()
self.vbox = QVBoxLayout()
if len(sample_numbers) != 0:
i = 1
x = 40
y = 75
w = 100
h = 100
for item in sample_numbers:
# print("Here is an item")
result = item[3:9]
datevalue = item[:3]
jackpotvalue = item[10]
outcome = item[11]
historylabel = ["DATE: " + str(datevalue[0]) + '-' + str(datevalue[1])
+ '-' + str(datevalue[2])
+ ' | ' + "PRIZE: " + jackpotvalue
+ ' | ' + "ROLL (NO WINNER)"]
result.append(historylabel)
# print(result)
# print(type(result))
# print(datevalue)
# print(jackpotvalue)
# print(outcome)
# print(historylabel)
for obj in result:
# print("Here is an obj in item")
self.outputlabel = QLabel(self)
self.labeltext = QLabel(self)
self.labeltext.setText(str(obj))
self.labeltext.setAlignment(QtCore.Qt.AlignCenter)
self.labeltext.setStyleSheet("QLabel { color : black; }")
if i < 6:
self.pixmap = QPixmap(u":/graphics/Images/lottoball.png")
else:
self.pixmap = QPixmap(u":/graphics/Images/lottoslip.jpg")
self.outputlabel.setPixmap(self.pixmap)
self.outputlabel.resize(self.pixmap.width(),
self.pixmap.height())
self.outputlabel.setGeometry(x, y, w, h)
self.labeltext.setGeometry(x, y, w, h)
# adding labels to vbox
self.vbox.addWidget(self.outputlabel)
self.vbox.addWidget(self.labeltext)
x += 125
i += 1
if i == 7:
i += 1
x = 40
y += 125
elif i > 7:
self.outputlabel.setPixmap(None)
self.labeltext.setText(historylabel[0])
self.labeltext.setStyleSheet("QLabel { color : white; }")
self.labeltext.adjustSize()
# adding label to vbox
self.vbox.addWidget(self.labeltext)
i = 1
x = 40
y += 50
self.widget.setLayout(self.vbox)
# Scroll Area Properties
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.show()
下面是错误输出的示例。所有小部件都堆叠在一起并垂直或水平显示 (vbox/hbox):
您可以使用“gridlayout”或像下面的示例一样使用“setMinimumSize”为您的项目设置限制
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class main(QMainWindow):
def __init__(self):
super().__init__()
self.scroll = QScrollArea()
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
self.widget = QWidget()
self.scroll.setWidgetResizable(True)
# => grid set
self.grid = QGridLayout(self.widget)
self.grid.setContentsMargins(10,40,10,20)
self.grid.setHorizontalSpacing(20)
self.grid.setVerticalSpacing(10)
for i in range(6):
for j in range(3):
if i % 2 == 1:
self.grid.addWidget(QLabel("DateTime => 01.19.2022 | 0 | ROLL"), i,j, 1,3)
break
else:
self.label = QLabel("9")
self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.label.setStyleSheet("background-color: red;")
# => item set minimum size !
self.label.setMinimumSize(120,120)
self.grid.addWidget(self.label, i, j, 1,1)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
self.resize(600,550)
self.show()
app = QApplication([])
window = main()
app.exec()
使用 SimoN SavioR 的提示和上面的示例代码,我想出了如何重构我的函数来生成我正在寻找的结果,这模仿了 SimoN 在他的示例中生成的结果。首先,我认为我在以前的代码中遇到的最大问题是使用 Vbox 而不是 Grid,并将 Widget 分配给 Vbox 而不是将 Widget 分配给布局。下面是我的函数的新代码,现在可以按需运行,以及我得到的新输出的示例屏幕截图。在研究了 SimoN 的代码并了解它如何产生输出后,我设法将某些代码块集成到我自己的原始代码中,以使该功能正常工作并以我最初想要的方式显示输出。我从 SimoN 借用的主要代码块是 for 循环之前的两个块,以及 for 循环之后的块。我能够保留我的原始代码的所有其余部分,并进行一些细微的修改以使其协同工作。
def create_sample_images(self, sample_numbers):
displaytext = "Displaying " + str(len(sample_numbers)) + " results"
self.setWindowTitle(displaytext)
# print(sample_numbers)
# print(len(sample_numbers))
# self.gridlayout = QGridLayout()
# # self.groupbox = QGroupBox("Results")
# self.vbox = QVBoxLayout()
# self.scroll = QScrollArea()
self.scroll = QScrollArea()
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
self.widget = QWidget()
self.scroll.setWidgetResizable(True)
# => grid set
self.gridlayout = QGridLayout(self.widget) # widget is parent widget
self.gridlayout.setContentsMargins(10, 40, 10, 20) # left, top, right, bottom
self.gridlayout.setHorizontalSpacing(20)
self.gridlayout.setVerticalSpacing(10)
if len(sample_numbers) != 0:
i = 1
ballrow = 0
inforow = 1
ballcolumn = 0
infocolumn = 0
for item in sample_numbers:
# print("Here is an item")
result = item[3:9]
datevalue = item[:3]
jackpotvalue = item[10]
outcome = item[11]
if outcome == "Roll":
historylabel = ["Date: " + str(datevalue[0]) + '-' + str(datevalue[1])
+ '-' + str(datevalue[2])
+ ' | ' + "Prize: " + jackpotvalue
+ ' | ' + "Roll (No Winner)"]
else:
historylabel = ["Date: " + str(datevalue[0]) + '-' + str(datevalue[1])
+ '-' + str(datevalue[2])
+ ' | ' + "Prize: " + jackpotvalue
+ ' | ' + "Jackpot Winner(s)"]
result.append(historylabel)
# print(result)
# print(type(result))
# print(datevalue)
# print(jackpotvalue)
# print(outcome)
# print(historylabel)
for obj in result:
# print("Here is an obj in item")
self.outputlabel = QLabel(self)
self.labeltext = QLabel(self)
self.labeltext.setText(str(obj))
self.labeltext.setAlignment(QtCore.Qt.AlignCenter)
self.labeltext.setStyleSheet("QLabel { color : black; }")
self.labeltext.setFont(QFont("Arial", 18))
if i < 6:
self.pixmap = QPixmap(u":/graphics/whiteball.png")
elif i == 6:
self.pixmap = QPixmap(u":/graphics/redball.png")
self.outputlabel.setPixmap(self.pixmap)
self.outputlabel.setScaledContents(Qt.KeepAspectRatio)
# self.outputlabel.resize(self.pixmap.width(),
# self.pixmap.height())
self.outputlabel.setMinimumSize(112, 112)
self.labeltext.setMinimumSize(56, 56)
self.outputlabel.setMaximumSize(112, 112)
self.labeltext.setMaximumSize(800, 800)
self.gridlayout.addWidget(self.outputlabel, ballrow, ballcolumn, 1, 1)
self.gridlayout.addWidget(self.labeltext, ballrow, ballcolumn, 1, 1)
# self.groupbox.setLayout(self.gridlayout)
# self.scroll.setLayout(self.gridlayout)
i += 1
ballcolumn += 1
if i == 7:
i += 1
inforow += 1
elif i > 7:
self.outputlabel.setPixmap(None)
self.labeltext.setText(" " + str(historylabel[0]))
self.labeltext.setStyleSheet("QLabel { color : #7393B3; }") #steel blue 4682B4 bright blue 0096FF denim 6F8FAF royal blue 4169E1 blue gray 7393B3
self.labeltext.setFont(QFont("Arial", 18))
self.labeltext.setAlignment(Qt.AlignmentFlag.AlignLeft)
self.gridlayout.addWidget(self.labeltext, inforow, infocolumn, 1, 10)
i = 1
inforow += 2
ballrow += 3
ballcolumn = 0
# widget is parent widget of grid layout. being added to scroll layout
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
# resize entire window show to display all objects (width, height)
# self.resize(1000, 550)
self.show()
else:
x = 265
y = 225
w = 275
h = 100
self.labeltext = QLabel(self)
self.labeltext.setText("Sorry, no results to display. Please try again.")
self.labeltext.setStyleSheet("QLabel { color : white; }")
self.labeltext.setGeometry(x, y, w, h)
self.show()
感谢 SimoN SavioR 帮助我更好地理解布局;没有他们的贡献,不可能找到最终的解决方案!