PyQt5 - อินเทอร์เฟซเอกสารหลายรายการ
แอปพลิเคชัน GUI ทั่วไปอาจมีหลายหน้าต่าง วิดเจ็ตแบบแท็บและแบบเรียงซ้อนอนุญาตให้เปิดใช้งานหน้าต่างดังกล่าวได้ครั้งละหนึ่ง อย่างไรก็ตามหลายครั้งวิธีนี้อาจไม่มีประโยชน์เนื่องจากมุมมองของหน้าต่างอื่น ๆ ถูกซ่อนไว้
วิธีหนึ่งในการแสดงหลายหน้าต่างพร้อมกันคือการสร้างเป็นหน้าต่างอิสระ สิ่งนี้เรียกว่า SDI(single Document Interface). สิ่งนี้ต้องการทรัพยากรหน่วยความจำมากขึ้นเนื่องจากแต่ละหน้าต่างอาจมีระบบเมนูแถบเครื่องมือและอื่น ๆ ของตัวเอง
MDI (Multiple Document Interface)แอปพลิเคชันใช้ทรัพยากรหน่วยความจำน้อยลง หน้าต่างย่อยจะถูกวางลงภายในคอนเทนเนอร์หลักโดยมีความสัมพันธ์ซึ่งกันและกัน เรียกว่าวิดเจ็ตคอนเทนเนอร์QMdiArea.
วิดเจ็ต QMdiArea โดยทั่วไปจะใช้วิดเจ็ตส่วนกลางของอ็อบเจ็กต์ QMainWondow หน้าต่างลูกในพื้นที่นี้เป็นกรณีของQMdiSubWindowชั้นเรียน เป็นไปได้ที่จะตั้งค่า QWidget เป็นวิดเจ็ตภายในของวัตถุหน้าต่างย่อย หน้าต่างย่อยในพื้นที่ MDI สามารถจัดเรียงแบบเรียงซ้อนหรือกระเบื้อง
ตารางต่อไปนี้แสดงวิธีการที่สำคัญของคลาส QMdiArea และคลาส QMdiSubWindow -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 |
addSubWindow() เพิ่มวิดเจ็ตเป็นหน้าต่างย่อยใหม่ในพื้นที่ MDI |
2 |
removeSubWindow() ลบวิดเจ็ตที่เป็นวิดเจ็ตภายในของหน้าต่างย่อย |
3 |
setActiveSubWindow() เปิดใช้งานหน้าต่างย่อย |
4 |
cascadeSubWindows() จัดเรียง Windows ย่อยใน MDiArea แบบเรียงซ้อน |
5 |
tileSubWindows() จัดเรียงหน้าต่างย่อยใน MDiArea ในรูปแบบที่เรียงต่อกัน |
6 |
closeActiveSubWindow() ปิดหน้าต่างย่อยที่ใช้งานอยู่ |
7 |
subWindowList() ส่งกลับรายการของ Windows ย่อยในพื้นที่ MDI |
8 |
setWidget() ตั้งค่า QWidget เป็นวิดเจ็ตภายในของอินสแตนซ์ QMdiSubwindow |
วัตถุ QMdiArea ปล่อยสัญญาณ subWindowActivated () ในขณะที่สัญญาณ windowStateChanged () ถูกปล่อยออกมาโดยวัตถุ QMdisubWindow
ตัวอย่าง
ในตัวอย่างต่อไปนี้หน้าต่างระดับบนสุดที่ประกอบด้วย QMainWindow มีเมนูและ MdiArea
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
สัญญาณทริกเกอร์ () ของเมนูเชื่อมต่อกับฟังก์ชัน windowaction ()
file.triggered[QAction].connect(self.windowaction)
การดำเนินการใหม่ของเมนูจะเพิ่มหน้าต่างย่อยในพื้นที่ MDI โดยมีชื่อเรื่องที่มีตัวเลขเพิ่มขึ้น
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
ปุ่มเรียงซ้อนและเรียงต่อกันของเมนูจัดเรียงหน้าต่างย่อยที่แสดงอยู่ในปัจจุบันในรูปแบบเรียงซ้อนและเรียงตามลำดับ
รหัสที่สมบูรณ์มีดังนี้ -
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class MainWindow(QMainWindow):
count = 0
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
file.triggered[QAction].connect(self.windowaction)
self.setWindowTitle("MDI demo")
def windowaction(self, q):
print ("triggered")
if q.text() == "New":
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
if q.text() == "cascade":
self.mdi.cascadeSubWindows()
if q.text() == "Tiled":
self.mdi.tileSubWindows()
def main():
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
เรียกใช้โค้ดด้านบนและสามหน้าต่างในรูปแบบเรียงซ้อนและเรียงต่อกัน -