一、背景
最近要開一門新課,數據庫綜合實習,需要實現一個圖形化界面程序對SqlServer數據庫進行操作,在安裝好Sqlserver之後選擇使用pyqt實現圖形化界面。
初步設計在主界面中分爲左邊菜單欄和右邊顯示欄,需要在主窗口中嵌套一個窗口,即右邊顯示欄。並且需要動態改變右邊的窗口。
在查相關博客時只發現兩篇博客,鏈接地址如下:PYQT5 實現界面的嵌套、pyqt窗口嵌套。但是他們的代碼太多太雜,包含了很多無關緊要的代碼,而且他們的UI似乎是使用qtdesign實現的,直接導致部分代碼我沒看懂。。。因此我打算寫下這篇博客,希望使用簡介、易懂的代碼介紹窗口嵌套的功能的實現。
二、思路
首選新建一個主界面mainWindow,在mainWindow中加入一個左側佈局、一個初始widget1。
在左側佈局中有兩個button,通過這兩個button改變右側是顯示widget1還是widget2。
三、代碼
import sys
from PyQt5.Qt import *;
from PyQt5.QtWidgets import *;
if __name__ == "__main__":
app = QApplication(sys.argv)
# 主窗口
mainWin = QMainWindow()
mainWin.setGeometry(300, 300, 800, 800)
mainWin.setWindowTitle("nest windows")
# 右側的widget 默認初始是win1 點擊button切換
win1 = QWidget()
win1.setStyleSheet("background-color:red;")
win2 = QWidget()
win2.setStyleSheet("background-color:white;")
# centralWidget用來對mainWin進行佈局
centralWidget = QWidget()
# 水平佈局 用來放左側菜單欄與可變的widget
hbox = QHBoxLayout()
# 垂直佈局 用來放置切換widget的button
vboxLeft = QVBoxLayout()
# 兩個button 用來切換右側的 widget
btn1 = QPushButton("win1", centralWidget)
btn2 = QPushButton("win2", centralWidget)
# 將兩個button放入垂直佈局中
vboxLeft.addWidget(btn1)
vboxLeft.addWidget(btn2)
# hbox中加入垂直佈局vboxLeft
hbox.addLayout(vboxLeft)
# hbox中加入默認的win1
hbox.addWidget(win1)
# btn1 btn2綁定點擊事件
# 點擊btn1 先將hbox中的第二個(下標爲1)的控件的parent設置爲None 再將hbox的下標1處插入一個我們希望顯示的控件
btn1.clicked.connect(lambda :(hbox.itemAt(1).widget().setParent(None), hbox.insertWidget(1, win2)))
btn2.clicked.connect(lambda :(hbox.itemAt(1).widget().setParent(None), hbox.insertWidget(1, win1)))
# 將hbox佈局設給centralWidget
centralWidget.setLayout(hbox)
# 將centralWidget設給mainWin
mainWin.setCentralWidget(centralWidget)
mainWin.show()
sys.exit(app.exec_())
四、最終效果
如gif圖顯示,點擊第一個button 右側切換爲win2,點擊第二個button右側切換爲win1。這裏的切換是通過改變mainWin右側的widget實現的,而不是同過改變mainWin右側的背景色實現的。
五、注意的問題
1、之所以在新建mainWin只後還另外新建了一個centralWidget(QWidget),是因爲QMainWindow類不支持設置自定義佈局,需要新建一個QWidget實例,將自定義佈局給QWIdget實例,再將該實例設置爲QMainWindow的centralWidget。
2、在綁定button點擊事件時使用了lambda函數,lambda函數一般用來實現簡單的操作,比如只有一個語句的操作,如果要實現多個語句的操作,需要將多個語句放在一個括號中,語句間使用逗號分隔。
3、在更改widget時,需要先將原來的widget的parent設爲None,然後再將需要顯示的widget放入hbox佈局中。
4、hbox.itemAt()返回的是QWidgetItem類型,沒有.setParent()方法,使用hbox.itemAt().widget()即可返回widget類型。