2017-02-07 46 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)