PYQT6设置输入字段和按钮的位置

发布于 2025-02-11 16:44:38 字数 424 浏览 2 评论 0原文

我正在尝试在pyqt6中创建一个输入字段(位置:窗口的右下角),然后在右侧的“ Enter”按钮(我正在使用pg.graphicview())。由于与我的其余代码的某些相互作用问题,我无法使用Pyside库。我该如何实现?

我正在使用以下代码来生成一个按钮,但是我不知道如何将其放在当前窗口的右下角:

view = pg.GraphicsView()
l = pg.GraphicsLayout()
view.setCentralItem(l)
view.show()

proxy = QGraphicsProxyWidget()
button = QPushButton("ENTER")
proxy.setWidget(button)

view.addItem(proxy)

关于输入字段,我尝试实现不同的东西而不使用Pyside,但它们没有工作。

I'm trying to create in PyQt6 an input field (location: bottom right of the window) and next to It on the right an "Enter" button (I'm using pg.GraphicView()). I can't use the PySide library because of some interaction problems with the rest of my code. How can I achieve that?

I'm using the following code for generating a button but I can't figure out how to place It at the bottom right of the current window:

view = pg.GraphicsView()
l = pg.GraphicsLayout()
view.setCentralItem(l)
view.show()

proxy = QGraphicsProxyWidget()
button = QPushButton("ENTER")
proxy.setWidget(button)

view.addItem(proxy)

Regarding the input field I tried to implement different things without using PySide but they didn't worked.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长不大的小祸害 2025-02-18 16:44:38

pg.graphicsview实际上是 qgraphicsview ,这是从qabstractscrollarea sarasenction qwidget

这意味着我们可以将任何 child 小部件添加到它的情况下,而不会干扰场景的内容,也可以忽略可能的转换(缩放,旋转等)。

实际上,解决方案非常简单:将视图设置为窗口小部件的父(通过将视图用作构造函数中的参数,或通过调用setParent())。然后,剩下的是确保窗口小部件的几何形状始终与视图一致,因此我们需要等待调整事件大小并根据新大小设置新的几何形状。为了实现这一目标,最简单的解决方案是创建一个子类。

出于说明目的,我已经实施了一个系统,该系统允许为视图的任何“角”设置小部件,并默认为右下角。

注意:由于此问题也可能对QT5有效,因此在以下代码中,我使用的是“旧”枚举样式(qt.Align ...),用于QT的较新版本(以及强制性的对于pyqt6),您需要更改为qt.Alignment.Align ...

class CustomGraphicsView(pg.GraphicsView):
    toolWidgets = None
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.toolWidgets = {}

    def setToolWidget(self, widget, position=Qt.AlignBottom|Qt.AlignRight):
        position = Qt.AlignmentFlag(position)
        current = self.toolWidgets.get(position)
        if current:
            current.deleteLater()
        self.toolWidgets[position] = widget

        widget.resize(widget.sizeHint())

        # ensure that the widget is reparented
        widget.setParent(self)

        # setParent() automatically hides widgets, we need to
        # explicitly call show()
        widget.show()

        self._updateToolWidgets()

    def _updateToolWidgets(self):
        if not self.toolWidgets:
            return
        viewGeo = self.rect()
        for pos, widget in self.toolWidgets.items():
            rect = widget.rect()
            if pos & Qt.AlignLeft:
                rect.moveLeft(0)
            elif pos & Qt.AlignRight:
                rect.moveRight(viewGeo.right())
            elif pos & Qt.AlignHCenter:
                rect.moveLeft(viewGeo.center().x() - rect.width() / 2)
            if pos & Qt.AlignTop:
                rect.moveTop(0)
            elif pos & Qt.AlignBottom:
                rect.moveBottom(viewGeo.bottom())
            elif pos & Qt.AlignVCenter:
                rect.moveTop(viewGeo.center().y() - rect.height() / 2)
            widget.setGeometry(rect)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self._updateToolWidgets()


# ...

view = CustomGraphicsView()
l = pg.GraphicsLayout()
view.setCentralItem(l)
view.show()

container = QFrame(autoFillBackground=True, objectName='container')
container.setStyleSheet('''
    QFrame#container {
        background: palette(window);
        border: 1px outset palette(mid); 
        border-radius: 2px;
    }
''')
lineEdit = QLineEdit()
button = QPushButton("ENTER")
frameLayout = QHBoxLayout(container)
frameLayout.setContentsMargins(0, 0, 0, 0)
frameLayout.addWidget(lineEdit)
frameLayout.addWidget(button)
view.setToolWidget(container)

bottomLeftButton = QPushButton('Something')
view.setToolWidget(bottomLeftButton, Qt.AlignLeft|Qt.AlignBottom)

The pg.GraphicsView class is actually a subclass of QGraphicsView, which is a standard QWidget that inherits from QAbstractScrollArea.

This means that we can potentially add any child widget to it without interfering with the contents of the scene and also ignoring possible transformations (scaling, rotation, etc.).

The solution, in fact, is quite simple: set the view as parent of the widget (either by using the view as argument in the constructor, or by calling setParent()). Then, what's left is to ensure that the widget geometry is always consistent with the view, so we need to wait for resize events and set the new geometry based on the new size. To achieve this, the simplest solution is to create a subclass.

For explanation purposes, I've implemented a system that allows to set widgets for any "corner" of the view, and defaults to the bottom right corner.

Note: since this question could also be valid for Qt5, in the following code I'm using the "old" enum style (Qt.Align...), for newer versions of Qt (and mandatory for PyQt6), you need to change to Qt.Alignment.Align....

class CustomGraphicsView(pg.GraphicsView):
    toolWidgets = None
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.toolWidgets = {}

    def setToolWidget(self, widget, position=Qt.AlignBottom|Qt.AlignRight):
        position = Qt.AlignmentFlag(position)
        current = self.toolWidgets.get(position)
        if current:
            current.deleteLater()
        self.toolWidgets[position] = widget

        widget.resize(widget.sizeHint())

        # ensure that the widget is reparented
        widget.setParent(self)

        # setParent() automatically hides widgets, we need to
        # explicitly call show()
        widget.show()

        self._updateToolWidgets()

    def _updateToolWidgets(self):
        if not self.toolWidgets:
            return
        viewGeo = self.rect()
        for pos, widget in self.toolWidgets.items():
            rect = widget.rect()
            if pos & Qt.AlignLeft:
                rect.moveLeft(0)
            elif pos & Qt.AlignRight:
                rect.moveRight(viewGeo.right())
            elif pos & Qt.AlignHCenter:
                rect.moveLeft(viewGeo.center().x() - rect.width() / 2)
            if pos & Qt.AlignTop:
                rect.moveTop(0)
            elif pos & Qt.AlignBottom:
                rect.moveBottom(viewGeo.bottom())
            elif pos & Qt.AlignVCenter:
                rect.moveTop(viewGeo.center().y() - rect.height() / 2)
            widget.setGeometry(rect)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self._updateToolWidgets()


# ...

view = CustomGraphicsView()
l = pg.GraphicsLayout()
view.setCentralItem(l)
view.show()

container = QFrame(autoFillBackground=True, objectName='container')
container.setStyleSheet('''
    QFrame#container {
        background: palette(window);
        border: 1px outset palette(mid); 
        border-radius: 2px;
    }
''')
lineEdit = QLineEdit()
button = QPushButton("ENTER")
frameLayout = QHBoxLayout(container)
frameLayout.setContentsMargins(0, 0, 0, 0)
frameLayout.addWidget(lineEdit)
frameLayout.addWidget(button)
view.setToolWidget(container)

bottomLeftButton = QPushButton('Something')
view.setToolWidget(bottomLeftButton, Qt.AlignLeft|Qt.AlignBottom)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文