PyQt5 - 如何将滚动条添加到 QMessageBox
PyQt5 - How to add a scrollbar to a QMessageBox
我有一个基于用户输入生成的列表。
我正在尝试在 QMessageBox 中显示此列表。但是,我无法知道这个列表的长度。清单可能很长。
因此,我需要给 QMessageBox 添加一个滚动条。
有趣的是,我到处都找了,但我还没有找到任何解决方案。
下面是,我希望是一个“最小的,完整的和可验证的例子”,当然没有用户输入;我刚刚创建了一个列表作为示例。
感谢任何建议。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class W(QWidget):
def __init__(self):
super().__init__()
self.initUi()
def initUi(self):
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.lst = list(range(2000))
self.show()
def buttonClicked(self):
result = QMessageBox(self)
result.setText('%s' % self.lst)
result.exec_()
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
您不能直接添加滚动条,因为负责显示文本的小部件是 QLabel
。解决方法是加一个QScrollArea
。大小可能不够,因此必须使用样式表来设置最小值。
class ScrollMessageBox(QMessageBox):
def __init__(self, l, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
scroll = QScrollArea(self)
scroll.setWidgetResizable(True)
self.content = QWidget()
scroll.setWidget(self.content)
lay = QVBoxLayout(self.content)
for item in l:
lay.addWidget(QLabel(item, self))
self.layout().addWidget(scroll, 0, 0, 1, self.layout().columnCount())
self.setStyleSheet("QScrollArea{min-width:300 px; min-height: 400px}")
class W(QWidget):
def __init__(self):
super().__init__()
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.lst = [str(i) for i in range(2000)]
self.show()
def buttonClicked(self):
result = ScrollMessageBox(self.lst, None)
result.exec_()
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
输出:
这是覆盖小部件行为的另一种方法。
您可以使用 'children()' 获取对小部件子项的引用。
然后您可以像操作任何其他小部件一样操作它们。
这里我们在原来的widget的QGridLayout中添加了一个QScrollArea和QLabel。我们从原始小部件的标签中获取文本并将其复制到我们的新标签中,最后我们从原始标签中清除文本以使其不显示(因为它在我们的新标签旁边)。
我们的新标签是可滚动的。我们必须设置scrollArea的最小尺寸,否则会难以阅读。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ScrollMessageBox(QMessageBox):
def __init__(self, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
chldn = self.children()
scrll = QScrollArea(self)
scrll.setWidgetResizable(True)
grd = self.findChild(QGridLayout)
lbl = QLabel(chldn[1].text(), self)
lbl.setWordWrap(True)
scrll.setWidget(lbl)
scrll.setMinimumSize (400,200)
grd.addWidget(scrll,0,1)
chldn[1].setText('')
self.exec_()
class W(QWidget):
def __init__(self):
super(W,self).__init__()
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.message = ("""We have encountered an error.
The following information may be useful in troubleshooting:
1
2
3
4
5
6
7
8
9
10
Here is the bottom.
""")
self.show()
def buttonClicked(self):
result = ScrollMessageBox(QMessageBox.Critical,"Error!",self.message)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
我有一个基于用户输入生成的列表。
我正在尝试在 QMessageBox 中显示此列表。但是,我无法知道这个列表的长度。清单可能很长。
因此,我需要给 QMessageBox 添加一个滚动条。
有趣的是,我到处都找了,但我还没有找到任何解决方案。
下面是,我希望是一个“最小的,完整的和可验证的例子”,当然没有用户输入;我刚刚创建了一个列表作为示例。
感谢任何建议。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class W(QWidget):
def __init__(self):
super().__init__()
self.initUi()
def initUi(self):
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.lst = list(range(2000))
self.show()
def buttonClicked(self):
result = QMessageBox(self)
result.setText('%s' % self.lst)
result.exec_()
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
您不能直接添加滚动条,因为负责显示文本的小部件是 QLabel
。解决方法是加一个QScrollArea
。大小可能不够,因此必须使用样式表来设置最小值。
class ScrollMessageBox(QMessageBox):
def __init__(self, l, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
scroll = QScrollArea(self)
scroll.setWidgetResizable(True)
self.content = QWidget()
scroll.setWidget(self.content)
lay = QVBoxLayout(self.content)
for item in l:
lay.addWidget(QLabel(item, self))
self.layout().addWidget(scroll, 0, 0, 1, self.layout().columnCount())
self.setStyleSheet("QScrollArea{min-width:300 px; min-height: 400px}")
class W(QWidget):
def __init__(self):
super().__init__()
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.lst = [str(i) for i in range(2000)]
self.show()
def buttonClicked(self):
result = ScrollMessageBox(self.lst, None)
result.exec_()
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())
输出:
这是覆盖小部件行为的另一种方法。
您可以使用 'children()' 获取对小部件子项的引用。 然后您可以像操作任何其他小部件一样操作它们。
这里我们在原来的widget的QGridLayout中添加了一个QScrollArea和QLabel。我们从原始小部件的标签中获取文本并将其复制到我们的新标签中,最后我们从原始标签中清除文本以使其不显示(因为它在我们的新标签旁边)。 我们的新标签是可滚动的。我们必须设置scrollArea的最小尺寸,否则会难以阅读。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ScrollMessageBox(QMessageBox):
def __init__(self, *args, **kwargs):
QMessageBox.__init__(self, *args, **kwargs)
chldn = self.children()
scrll = QScrollArea(self)
scrll.setWidgetResizable(True)
grd = self.findChild(QGridLayout)
lbl = QLabel(chldn[1].text(), self)
lbl.setWordWrap(True)
scrll.setWidget(lbl)
scrll.setMinimumSize (400,200)
grd.addWidget(scrll,0,1)
chldn[1].setText('')
self.exec_()
class W(QWidget):
def __init__(self):
super(W,self).__init__()
self.btn = QPushButton('Show Message', self)
self.btn.setGeometry(10, 10, 100, 100)
self.btn.clicked.connect(self.buttonClicked)
self.message = ("""We have encountered an error.
The following information may be useful in troubleshooting:
1
2
3
4
5
6
7
8
9
10
Here is the bottom.
""")
self.show()
def buttonClicked(self):
result = ScrollMessageBox(QMessageBox.Critical,"Error!",self.message)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = W()
sys.exit(app.exec_())