How can I make the QDialog to resize according to the content, and, if the content is larger than the screen size, resize the dialog to the screen size and display scrollbars (horizontal and vertical)?
To provide some context:
I created class inheriting from QDialog that I use as a generic dialog (from which I create curstom error, warning and info dialogs), and I want to add a QScrollArea, so when the content is larger than the screen size, the dialog resizes to the screen size (whether it's the width, the height or both that extend).
In order to make the dialog flexible to the content, I use adjustSize(). But when I have a content that is bigger than the screen size, the QScrollArea does not take the screen size even if I override the sizeHint to be self.screen().size().
I will create a small sample and update the post tomorrow morning (but wanted to have it written in case someone has an idea of how to do it).
CodePudding user response:
This is how I fixed it, following the approach mentioned in this other post Cannot automatically resize a QScrollArea
import sys
import os
from PySide2.QtCore import QFile, QIODevice, QTextStream, QSize, QTimer
from PySide2.QtWidgets import QWidget, QHBoxLayout, QLabel, QDialog, QScrollArea, QFrame, QApplication, QStyle
_SAMPLE_FILE_PATH: str = 'sample.txt'
def get_text_from_file(file_path: str) -> str:
text: str = ""
file_path = os.path.join(os.path.dirname(__file__), file_path)
if QFile.exists(file_path):
file = QFile(file_path)
if file.open(QIODevice.ReadOnly | QIODevice.Text):
stream = QTextStream(file)
text = stream.readAll()
file.close()
else:
print('file does not exist')
return text
class ScrollBaseDialog(QDialog):
def __init__(
self,
title: str,
content: QWidget):
super(ScrollBaseDialog, self).__init__()
self.setWindowTitle(title)
self._scroll_area = QScrollArea(self)
self._scroll_area.setWidget(content)
self._content = content
self._scroll_area.setWidgetResizable(True)
self._scroll_area.setFrameShape(QFrame.NoFrame)
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self._scroll_area)
self.setLayout(layout)
self.adjustSize()
QTimer.singleShot(0, self._adjust_geometry)
def _adjust_geometry(self) -> None:
header_height = self.style().pixelMetric(QStyle.PM_TitleBarHeight)
scroll_width = self.style().pixelMetric(QStyle.PM_ScrollBarExtent)
max_size = self.screen().availableSize() - QSize(scroll_width, header_height) # screen_size - header
width = min(max_size.width(), self._content.width()) scroll_width # scrollbar width
height = min(max_size.height(), self._content.height())
x: int = self.screen().geometry().x() scroll_width/2 (max_size.width() - width) / 2
y: int = self.screen().geometry().y() header_height (max_size.height() - height) / 2
self.setGeometry(x, y, width, height)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = ScrollBaseDialog(title='Sample Dialog', content=QLabel(get_text_from_file(_SAMPLE_FILE_PATH)))
dialog.show()
sys.exit(app.exec_())