繁体   English   中英

Pyqt5-网格布局行为异常

[英]Pyqt5 - grid layout misbehaving

因此,我试图掌握Qt(更具体地说是Pyqt),并希望创建一个简单的反馈表。 应该有

  • 一个标题
  • 名称(“作者”)
  • 一个消息
  • 发送和取消按钮

首先,让我们尝试不使用按钮( App类仅提供一个用于创建弹出窗口的按钮。问题涉及其下方的Form类):

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QDesktopWidget,\
    QHBoxLayout, QVBoxLayout, QGridLayout,\
    QPushButton, QLabel,QLineEdit, QTextEdit,\
    qApp
from PyQt5.QtGui import QIcon


class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 Layout Demo'
        self.popup = None

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setWindowIcon(QIcon('imgs/python3.png'))

        formButton = QPushButton("show form")
        formButton.clicked.connect(self.showPopup)

        formBox = QHBoxLayout()
        formBox.addWidget(formButton)
        formBox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addLayout(formBox)
        vbox.addStretch(1)

        # self.setLayout(vbox)  # would work if this was a QWidget

        # instead, define new central widget
        window = QWidget()
        window.setLayout(vbox)
        self.setCentralWidget(window)

        self.center(self)
        self.show()

    @staticmethod
    def center(w: QWidget):
        qr = w.frameGeometry()  # get a rectangle for the entire window

        # center point = center of screen resolution
        cp = QDesktopWidget().availableGeometry().center()

        qr.moveCenter(cp)  # move center of rectangle to cp
        w.move(qr.topLeft())  # move top-left point of window to top-let point of rectangle

    def showPopup(self):
        if self.popup is None:
            self.popup = Form(self)
            self.popup.setGeometry(10, 10, 300, 400)
            self.center(self.popup)

        self.popup.show()


class Form(QWidget):
    def __init__(self, main):
        super().__init__()
        self.initUI()
        self.main = main

    def initUI(self):
        self.setWindowTitle('Feedback')
        self.setWindowIcon(QIcon('imgs/python3.png'))

        title = QLabel('Title')
        author = QLabel('Author')
        message = QLabel('Message')

        titleEdit = QLineEdit()
        authorEdit = QLineEdit()
        messageEdit = QTextEdit()

        grid = QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(title, 1, 0)
        grid.addWidget(titleEdit,1, 1)

        grid.addWidget(author, 2, 0)
        grid.addWidget(authorEdit,2, 1)

        grid.addWidget(message, 3, 0)
        grid.addWidget(messageEdit, 4, 0, 6, 0)

        self.setLayout(grid)

    # probably should delegate to self.main, but bear with me
    def send(self):
        self.main.popup = None
        self.hide()

    def cancel(self):
        self.hide()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

在此处输入图片说明

好吧,看起来不错。 行编辑和文本编辑之间的间距太大,但是由于我想在其下方添加一些按钮,因此应该是一个问题。

所以我添加:

    sendBtn = QPushButton("send")
    cancelBtn = QPushButton("cancel")

    sendBtn.clicked.connect(self.send)
    cancelBtn.clicked.connect(self.cancel)

    grid.addWidget(sendBtn, 7, 1)
    grid.addWidget(cancelBtn, 7, 2)

产生

在此处输入图片说明

现在显然,我忘记了将标题和作者行的编辑内容扩展到新引入的第2列。虽然很容易修复,但真正困扰我的是按钮的位置。

为什么它们显示在文本编辑的中间? 我可以看到Qt如何选择列大小,以及为什么这会导致按钮的大小不同,但是由于本教程实际上并未在表单中添加按钮,因此我不知道如何解决该问题。

我当然可以简单地添加框:

sendBtn = QPushButton("send")
cancelBtn = QPushButton("cancel")

sendBtn.clicked.connect(self.send)
cancelBtn.clicked.connect(self.cancel)

btns = QHBoxLayout()
btns.addStretch(1)
btns.addWidget(sendBtn)
btns.addWidget(cancelBtn)

l = QVBoxLayout()
l.addLayout(grid)
l.addLayout(btns)

self.setLayout(l)

通过该弹出窗口,实际上实际上开始看起来更接近可接受的对象:

在此处输入图片说明

但是,有没有办法在网格布局中解决此问题呢?

您似乎误解了addWidget的签名。 第二个和第三个参数指定放置小部件的行和列,而第三个和第四个参数指定行跨度和列跨度。

在您的示例中,问题从这里开始:

    grid.addWidget(message, 3, 0)
    grid.addWidget(messageEdit, 4, 0, 6, 0)

您在其中进行文本编辑的范围为六行零列-我怀疑这是您的意图。 相反,您可能想要这样:

    grid.addWidget(message, 3, 0, 1, 2)
    grid.addWidget(messageEdit, 4, 0, 1, 2)

这将使消息标签和文本编辑跨越上方标题和作者字段创建的两列。

现在,当您添加按钮时,它们必须具有自己的布局,因为最上面的两行已经确定了两列的宽度。 如果将按钮直接添加到网格,则它们将被迫具有与顶部两行中的小部件相同的宽度(反之亦然)。 所以应该这样添加按钮:

    hbox = QHBoxLayout()

    sendBtn = QPushButton("send")
    cancelBtn = QPushButton("cancel")

    sendBtn.clicked.connect(self.send)
    cancelBtn.clicked.connect(self.cancel)

    hbox.addStretch()
    hbox.addWidget(sendBtn)
    hbox.addWidget(cancelBtn)

    grid.addLayout(hbox, 5, 0, 1, 2)

暂无
暂无

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

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