PyQt5 — как добавить полосу прокрутки в 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_())

person U11-Forward    schedule 17.11.2017    source источник
comment
Я не думаю, что QMessageBox достаточно гибок, чтобы позволить это. Возможно, вам придется использовать более общий QDialog, который содержит QScrollArea.   -  person BrenBarn    schedule 17.11.2017
comment
@BrenBarn Большое спасибо, да, вы абсолютно правы.   -  person U11-Forward    schedule 17.11.2017


Ответы (2)


Вы не можете добавить полосу прокрутки напрямую, так как виджет, отвечающий за отображение текста, — это 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_())

Выход:

введите здесь описание изображения

person eyllanesc    schedule 17.11.2017
comment
Большое спасибо, я ценю это. - person U11-Forward; 17.11.2017

Вот еще один способ переопределить поведение виджетов.

Вы можете получить ссылки на дочерние элементы виджета, используя 'children()'. Затем вы можете манипулировать ими, как любым другим виджетом.

Здесь мы добавляем QScrollArea и QLabel к QGridLayout исходного виджета. Мы получаем текст из метки исходного виджета и копируем его в нашу новую метку, наконец, мы удаляем текст из исходной метки, чтобы он не отображался (потому что он находится рядом с нашей новой меткой). Наш новый ярлык можно прокручивать. Мы должны установить минимальный размер области прокрутки, иначе его будет трудно читать.

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_())
person Chris Morley    schedule 21.10.2018