2017-02-07 41 views
1

所以我试图抓住Qt(更具体地说,Pyqt),并且我想创建一个简单的反馈表单。它应该有Pyqt5 - 网格布局行为不便

  • 标题
  • 的名称( '作者')
  • 消息
  • 的发送和取消按钮

让我们试着不用按钮,第一个(在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_()) 

enter image description here

好吧,看看正确。行编辑和文本编辑之间的间距太大,但是因为我想在它下面添加一些按钮,所以这应该是个问题。

所以我补充一下:

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) 

这将产生

enter image description here

现在很明显,我忘了舒展标题和作者在线编辑新近出台的列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) 

与该弹出然后实际开始寻找更接近一些可以接受的:

enter image description here

但是,有没有办法解决这在网格布局中,而不是?

回答

2

您好像误解了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)