简体   繁体   English

在 PyQt 的网格布局中使用 QPainter 制作小部件可滚动

[英]Make widget with QPainter in grid layout in PyQt scrollable

I just started using PyQt and I struggle with the layout and making the content scrollable.我刚开始使用 PyQt,我在布局和使内容可滚动方面遇到了困难。 I have a MainWindow where I want to place multiple widgets.我有一个MainWindow ,我想在其中放置多个小部件。

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.top = 0
        self.left = 0
        self.width = 500
        self.height = 500

        layout = QtWidgets.QGridLayout()
        layout.addWidget(WidgetOne(), 0, 0)
        layout.addWidget(WidgetTwo(), 1, 1)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.initMainWindow()

    def initMainWindow(self):
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.show()

And in WidgetOne I draw something with QPainterWidgetOne我用QPainter画了一些东西

class WidgetOne(QtWidgets.QWidget):
    def __init__(self):
        super(WidgetOne, self).__init__()

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)

        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(QtCore.Qt.red)
        painter.setBrush(QtCore.Qt.green)
        # draw something
        painter.end()

And now I want to make WidgetOne where I drew something scrollable.现在我想制作WidgetOne ,在那里我画了一些可滚动的东西。 The area where I draw is larger than the ẁindow on the screen, so I want to be able to scroll over everything I have drawn.我绘制的区域比屏幕上的ẁindow 大,所以我希望能够滚动我绘制的所有内容。 I know it is done with QScrollArea but I only found examples where the scrolling area is the whole grid and not just one cell of the grid.我知道它是用QScrollArea完成的,但我只发现滚动区域是整个网格而不仅仅是网格的一个单元格的示例。

I already appreciate help.我已经感谢帮助。 Thank you (Any advice and improvements are also welcome.)谢谢(也欢迎任何建议和改进。)

EDIT: I think I am getting there.编辑:我想我快到了。 Now I have scrollbars around the drawn stuff, but I cant scroll.现在我在绘制的东西周围有滚动条,但我不能滚动。 I would guess I need to set a size somewhere, but I do not know where.我想我需要在某个地方设置一个大小,但我不知道在哪里。 I added this to the __init__() of MainWindow我将此添加到MainWindow__init__()

        self.scroll = QtWidgets.QScrollArea()
        self.scroll.setWidgetResizable(True)
        self.scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.scrollWidget = WidgetOne()
        self.scroll.setWidget(self.scrollWidget)

        layout.addWidget(self.scroll, 0, 0)

As you point out the solution is to use QScrollArea but its viewport takes the minimum size of the widget, but in your case there is no minimum size so just set the minimumSizeHint, the minimumSize or fixedSize:正如您所指出的,解决方案是使用 QScrollArea,但它的视口采用小部件的最小尺寸,但在您的情况下,没有最小尺寸,所以只需设置 minimumSizeHint、minimumSize 或 fixedSize:

import sys

from PyQt5 import QtCore, QtGui, QtWidgets


class WidgetOne(QtWidgets.QWidget):
    def paintEvent(self, event):
        painter = QtGui.QPainter(self)

        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(QtCore.Qt.red)
        painter.setBrush(QtCore.Qt.green)

    def minimumSizeHint(self):
        return QtCore.QSize(1000, 1000)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        widget = QtWidgets.QWidget()
        layout = QtWidgets.QGridLayout(widget)

        widget_one = WidgetOne()
        # or
        # widget_one.setFixedSize(1000, 1000)
        # or
        # widget_one.setMinimumSize(1000, 1000)
        scroll = QtWidgets.QScrollArea(widgetResizable=True)
        scroll.setWidget(widget_one)

        layout.addWidget(scroll, 0, 0)
        # layout.addWidget(WidgetTwo(), 1, 1)
        self.setCentralWidget(widget)
        self.resize(500, 500)


def main():
    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication([])

    w = MainWindow()
    w.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM