PyQt5 - คู่มือฉบับย่อ
PyQt เป็นชุดเครื่องมือวิดเจ็ต GUI เป็นอินเตอร์เฟซ Python สำหรับQtซึ่งเป็นหนึ่งในไลบรารี GUI ข้ามแพลตฟอร์มที่ทรงพลังและเป็นที่นิยมมากที่สุด PyQt ได้รับการพัฒนาโดย RiverBank Computing Ltd. เวอร์ชันล่าสุดของ PyQt สามารถดาวน์โหลดได้จากเว็บไซต์ทางการ - riverbankcomputing.com
PyQt API คือชุดโมดูลที่มีคลาสและฟังก์ชันจำนวนมาก ในขณะที่QtCore โมดูลมีฟังก์ชันที่ไม่ใช่ GUI สำหรับการทำงานกับไฟล์และไดเร็กทอรีเป็นต้น QtGuiโมดูลประกอบด้วยการควบคุมแบบกราฟิกทั้งหมด นอกจากนี้ยังมีโมดูลสำหรับการทำงานกับ XML(QtXml), SVG (QtSvg)และ SQL (QtSql)ฯลฯ
รายชื่อโมดูลที่ใช้บ่อยแสดงไว้ด้านล่าง -
QtCore - คลาสที่ไม่ใช่ GUI หลักที่ใช้โดยโมดูลอื่น
QtGui - ส่วนประกอบอินเทอร์เฟซผู้ใช้แบบกราฟิก
QtMultimedia - ชั้นเรียนสำหรับการเขียนโปรแกรมมัลติมีเดียระดับต่ำ
QtNetwork - คลาสสำหรับการเขียนโปรแกรมเครือข่าย
QtOpenGL - คลาสรองรับ OpenGL
QtScript - คลาสสำหรับการประเมิน Qt Scripts
QtSql - คลาสสำหรับการรวมฐานข้อมูลโดยใช้ SQL
QtSvg - คลาสสำหรับการแสดงเนื้อหาของไฟล์ SVG
QtWebKit - คลาสสำหรับการแสดงผลและแก้ไข HTML
QtXml - คลาสสำหรับการจัดการ XML
QtWidgets - คลาสสำหรับการสร้าง UI สไตล์เดสก์ท็อปคลาสสิก
QtDesigner - คลาสสำหรับขยาย Qt Designer
รองรับสภาพแวดล้อม
PyQt เข้ากันได้กับระบบปฏิบัติการยอดนิยมทั้งหมดรวมถึง Windows, Linux และ Mac OS เป็นใบอนุญาตคู่พร้อมใช้งานภายใต้ GPL และใบอนุญาตเชิงพาณิชย์ เวอร์ชันเสถียรล่าสุดคือPyQt5-5.13.2.
Windows
ล้อสำหรับสถาปัตยกรรม 32 บิตหรือ 64 บิตมีให้ซึ่งเข้ากันได้กับ Python เวอร์ชัน 3.5 หรือใหม่กว่า วิธีที่แนะนำในการติดตั้งคือใช้PIP ยูทิลิตี้ -
pip3 install PyQt5
ในการติดตั้งเครื่องมือการพัฒนาเช่น Qt Designer เพื่อรองรับล้อ PyQt5 คำสั่งต่อไปนี้คือ -
pip3 install pyqt5-tools
คุณยังสามารถสร้าง PyQt5 บน Linux / macOS จากซอร์สโค้ดwww.riverbankcomputing.com/static/Downloads/PyQt5
PyQt5 API ไม่สามารถทำงานร่วมกับเวอร์ชันก่อนหน้าได้โดยอัตโนมัติ ดังนั้นโค้ด Python ที่เกี่ยวข้องกับโมดูล PyQt4 ควรได้รับการอัปเกรดด้วยตนเองโดยทำการเปลี่ยนแปลงที่เกี่ยวข้อง ในบทนี้มีการระบุความแตกต่างหลักระหว่าง PyQt4 และ PyQt5
PyQt5 ไม่รองรับ Python เวอร์ชันก่อนหน้า v2.6
PyQt5 ไม่รองรับเมธอด connect () ของคลาส QObject สำหรับการเชื่อมต่อระหว่างสัญญาณและสล็อต ดังนั้นจึงไม่สามารถใช้การใช้งานได้อีกต่อไป -
QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)
กำหนดเฉพาะไวยากรณ์ต่อไปนี้ -
widget.signal.connect(slot_function)
คลาสที่กำหนดไว้ในโมดูล QtGui ก่อนหน้านี้ได้รับการแจกจ่ายในรูปแบบ QtGui, QtPrintSupport ก QtWidgets โมดูล
ในคลาส QFileDialog ใหม่ The getOpenFileNameAndFilter() วิธีการถูกแทนที่ด้วย getOpenFileName(), getOpenFileNamesAndFilter() โดย getOpenFileNames() และ getSaveFileNameAndFilter() โดย getSaveFileName(). ลายเซ็นที่เก่ากว่าของวิธีการเหล่านี้ก็มีการเปลี่ยนแปลงเช่นกัน
PyQt5 ไม่มีบทบัญญัติเพื่อกำหนดคลาสที่แบ่งย่อยจากคลาส Qt มากกว่าหนึ่งคลาส
pyuic5 ยูทิลิตี้ (เพื่อสร้างโค้ด Python จากไฟล์ XML ของนักออกแบบ) ไม่สนับสนุนแฟล็ก --pyqt3-wrapper
pyrcc5ไม่สนับสนุนแฟล็ก -py2 และ -py3 เอาต์พุตของ pyrcc5 เข้ากันได้กับ Python v2.6 ทุกเวอร์ชันเป็นต้นไป
PyQt5 จะเรียกใช้เสมอ sip.setdestroyonexit() โดยอัตโนมัติและเรียกตัวทำลาย C ++ ของอินสแตนซ์ที่รวมไว้ทั้งหมดที่เป็นเจ้าของ
การสร้างแอปพลิเคชัน GUI อย่างง่ายโดยใช้ PyQt มีขั้นตอนต่อไปนี้ -
นำเข้าโมดูล QtCore, QtGui และ QtWidgets จากแพ็คเกจ PyQt5
สร้างแอปพลิเคชันอ็อบเจ็กต์ของคลาส QApplication
วัตถุ QWidget สร้างหน้าต่างระดับบนสุด เพิ่มวัตถุ QLabel ในนั้น
ตั้งคำบรรยายของป้ายกำกับเป็น "hello world"
กำหนดขนาดและตำแหน่งของหน้าต่างโดยวิธี setGeometry ()
เข้าสู่ mainloop ของแอปพลิเคชันโดย app.exec_() วิธี.
ต่อไปนี้เป็นรหัสสำหรับรันโปรแกรม Hello World ใน PyQt -
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
w = QWidget()
b = QLabel(w)
b.setText("Hello World!")
w.setGeometry(100,100,200,50)
b.move(50,20)
w.setWindowTitle("PyQt5")
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -
นอกจากนี้ยังเป็นไปได้ที่จะพัฒนาโซลูชันเชิงวัตถุของโค้ดข้างต้น
นำเข้าโมดูล QtCore, QtGui และ QtWidgets จากแพ็คเกจ PyQt5
สร้างแอปพลิเคชันอ็อบเจ็กต์ของคลาส QApplication
ประกาศคลาสหน้าต่างตามคลาส QWidget
เพิ่มวัตถุ QLabel และตั้งค่าคำบรรยายของป้ายกำกับเป็น "สวัสดีชาวโลก"
กำหนดขนาดและตำแหน่งของหน้าต่างโดยวิธี setGeometry ()
เข้าสู่ mainloop ของแอปพลิเคชันโดย app.exec_() วิธี.
ต่อไปนี้เป็นรหัสที่สมบูรณ์ของโซลูชันเชิงวัตถุ -
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class window(QWidget):
def __init__(self, parent = None):
super(window, self).__init__(parent)
self.resize(200,50)
self.setWindowTitle("PyQt5")
self.label = QLabel(self)
self.label.setText("Hello World")
font = QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.label.setFont(font)
self.label.move(50,20)
def main():
app = QApplication(sys.argv)
ex = window()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
PyQt APIเป็นชุดคลาสและวิธีการมากมาย คลาสเหล่านี้กำหนดไว้มากกว่า 20 โมดูล
ต่อไปนี้เป็นโมดูลที่ใช้บ่อย -
ซีเนียร์ | โมดูลและคำอธิบาย |
---|---|
1 | QtCore คลาสที่ไม่ใช่ GUI หลักที่ใช้โดยโมดูลอื่น |
2 | QtGui ส่วนประกอบส่วนติดต่อผู้ใช้แบบกราฟิก |
3 | QtMultimedia ชั้นเรียนสำหรับการเขียนโปรแกรมมัลติมีเดียระดับต่ำ |
4 | QtNetwork คลาสสำหรับการเขียนโปรแกรมเครือข่าย |
5 | QtOpenGL คลาสรองรับ OpenGL |
6 | QtScript คลาสสำหรับการประเมิน Qt Scripts |
7 | QtSql คลาสสำหรับการรวมฐานข้อมูลโดยใช้ SQL |
8 | QtSvg คลาสสำหรับการแสดงเนื้อหาของไฟล์ SVG |
9 | QtWebKit คลาสสำหรับการแสดงผลและแก้ไข HTML |
10 | QtXml คลาสสำหรับการจัดการ XML |
11 | QtWidgets คลาสสำหรับการสร้าง UI สไตล์เดสก์ท็อปคลาสสิก |
12 | QtDesigner คลาสสำหรับการขยาย Qt Designer |
13 | QtAssistant การสนับสนุนสำหรับความช่วยเหลือออนไลน์ |
เครื่องมือพัฒนา PyQt5 คือชุดยูทิลิตี้ที่มีประโยชน์สำหรับการพัฒนา Qt ต่อไปนี้เป็นรายการยูทิลิตี้ที่เลือกไว้ -
ซีเนียร์ | ชื่อเครื่องมือและคำอธิบาย |
---|---|
1 | assistant เครื่องมือเอกสาร Qt Assistant |
2 | pyqt5designer เครื่องมือเค้าโครง Qt Designer GUI |
3 | linguist เครื่องมือแปลภาษา Qt Linguist |
4 | lrelease รวบรวมไฟล์ ts เป็นไฟล์ qm |
5 | pylupdate5 แยกสตริงการแปลและสร้างหรืออัปเดตไฟล์ ts |
6 | qmake เครื่องมือสร้างซอฟต์แวร์ Qt |
7 | pyqt5qmlscene โปรแกรมดูไฟล์ QML |
8 | pyqmlviewer โปรแกรมดูไฟล์ QML |
9 | pyrcc5 คอมไพเลอร์ไฟล์ทรัพยากร Qt |
10 | pyuic5 Qt User Interface Compiler สำหรับสร้างโค้ดจากไฟล์ ui |
11 | pyqmltestrunner เรียกใช้การทดสอบหน่วยบนรหัส QML |
12 | qdbus เครื่องมือบรรทัดคำสั่งเพื่อแสดงรายการบริการ D-Bus |
13 | QDoc เครื่องกำเนิดเอกสารสำหรับโครงการซอฟต์แวร์ |
14 | Qhelpgenerator การสร้างและดูไฟล์วิธีใช้ Qt |
15 | qmlimportscanner แยกวิเคราะห์และรายงานเกี่ยวกับการนำเข้า QML |
PyQt API มีคลาสมากกว่า 400 คลาส QObjectชั้นเรียนอยู่ที่ด้านบนสุดของลำดับชั้นชั้น เป็นคลาสพื้นฐานของอ็อบเจ็กต์ Qt ทั้งหมด นอกจากนี้QPaintDevice คลาสเป็นคลาสพื้นฐานสำหรับอ็อบเจ็กต์ทั้งหมดที่สามารถทาสีได้
QApplicationคลาสจัดการการตั้งค่าหลักและขั้นตอนการควบคุมของแอปพลิเคชัน GUI ประกอบด้วยการวนซ้ำเหตุการณ์หลักซึ่งเหตุการณ์ที่สร้างโดยองค์ประกอบของหน้าต่างและแหล่งที่มาอื่น ๆ จะถูกประมวลผลและจัดส่ง นอกจากนี้ยังจัดการการตั้งค่าทั้งระบบและทั่วทั้งแอปพลิเคชัน
QWidget คลาสที่ได้มาจากคลาส QObject และ QPaintDevice เป็นคลาสพื้นฐานสำหรับอ็อบเจ็กต์ส่วนติดต่อผู้ใช้ทั้งหมด QDialog และ QFrameคลาสยังมาจากคลาส QWidget พวกเขามีระบบคลาสย่อยของตัวเอง
นี่คือรายการวิดเจ็ตที่เลือกใช้บ่อย
ซีเนียร์ | วิดเจ็ตและคำอธิบาย |
---|---|
1 | QLabel ใช้เพื่อแสดงข้อความหรือรูปภาพ |
2 | QLineEdit อนุญาตให้ผู้ใช้ป้อนข้อความหนึ่งบรรทัด |
3 | QTextEdit อนุญาตให้ผู้ใช้ป้อนข้อความหลายบรรทัด |
4 | QPushButton ปุ่มคำสั่งเพื่อเรียกใช้การกระทำ |
5 | QRadioButton ช่วยให้สามารถเลือกหนึ่งจากตัวเลือกต่างๆ |
6 | QCheckBox เปิดใช้งานตัวเลือกมากกว่าหนึ่งตัวเลือก |
7 | QSpinBox ช่วยเพิ่ม / ลดค่าจำนวนเต็ม |
8 | QScrollBar ช่วยให้เข้าถึงเนื้อหาของวิดเจ็ตนอกเหนือจากรูรับแสงที่แสดง |
9 | QSlider เปิดใช้งานเพื่อเปลี่ยนค่าขอบเขตเชิงเส้น |
10 | QComboBox แสดงรายการแบบหล่นลงของรายการที่จะเลือก |
11 | QMenuBar แถบแนวนอนถือวัตถุ QMenu |
12 | QStatusBar โดยปกติจะอยู่ที่ด้านล่างของ QMainWindow ให้ข้อมูลสถานะ |
13 | QToolBar โดยปกติจะอยู่ด้านบนของ QMainWindow หรือแบบลอย ประกอบด้วยปุ่มการดำเนินการ |
14 | QListView จัดเตรียมรายการที่เลือกได้ใน ListMode หรือ IconMode |
15 | QPixmap การแสดงภาพนอกจอเพื่อแสดงบนวัตถุ QLabel หรือ QPushButton |
16 | QDialog หน้าต่าง Modal หรือ modeless ซึ่งสามารถส่งคืนข้อมูลไปยังหน้าต่างหลัก |
หน้าต่างระดับบนสุดของแอปพลิเคชันที่ใช้ GUI ทั่วไปถูกสร้างขึ้นโดย QMainWindowวัตถุวิดเจ็ต วิดเจ็ตบางรายการตามที่ระบุไว้ข้างต้นจะถูกกำหนดไว้ในหน้าต่างหลักนี้ในขณะที่วิดเจ็ตอื่น ๆ จะถูกวางไว้ในพื้นที่วิดเจ็ตส่วนกลางโดยใช้ตัวจัดการโครงร่างต่างๆ
แผนภาพต่อไปนี้แสดงกรอบ QMainWindow -
ตัวติดตั้ง PyQt มาพร้อมกับเครื่องมือสร้าง GUI ที่เรียกว่า Qt Designer. ด้วยการใช้อินเทอร์เฟซการลากและวางที่เรียบง่ายสามารถสร้างอินเทอร์เฟซ GUI ได้อย่างรวดเร็วโดยไม่ต้องเขียนโค้ด อย่างไรก็ตามไม่ใช่ IDE เช่น Visual Studio ดังนั้น Qt Designer ไม่มีสิ่งอำนวยความสะดวกในการดีบักและสร้างแอปพลิเคชัน
เริ่มแอปพลิเคชัน Qt Designer ซึ่งเป็นส่วนหนึ่งของเครื่องมือการพัฒนาและติดตั้งในโฟลเดอร์สคริปต์ของสภาพแวดล้อมเสมือน
เริ่มออกแบบอินเทอร์เฟซ GUI โดยเลือกไฟล์→เมนูใหม่
จากนั้นคุณสามารถลากและวางวิดเจ็ตที่ต้องการจากกล่องวิดเจ็ตในบานหน้าต่างด้านซ้าย คุณยังสามารถกำหนดค่าให้กับคุณสมบัติของวิดเจ็ตที่วางบนแบบฟอร์ม
แบบฟอร์มที่ออกแบบจะถูกบันทึกเป็น demo.ui ไฟล์ ui นี้มีการแสดง XML ของวิดเจ็ตและคุณสมบัติในการออกแบบ การออกแบบนี้ถูกแปลเป็น Python ที่เทียบเท่าโดยใช้ยูทิลิตี้บรรทัดคำสั่ง pyuic5 ยูทิลิตี้นี้เป็นเครื่องห่อสำหรับโมดูล uic ของชุดเครื่องมือ Qt การใช้งาน pyuic5 มีดังนี้ -
pyuic5 -x demo.ui -o demo.py
ในคำสั่งด้านบนสวิตช์ -x จะเพิ่มโค้ดเพิ่มเติมเล็กน้อยให้กับสคริปต์ Python ที่สร้างขึ้น (จาก XML) เพื่อให้กลายเป็นแอปพลิเคชันแบบสแตนด์อโลนที่ดำเนินการได้เอง
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
สคริปต์ python ที่เป็นผลลัพธ์ถูกเรียกใช้เพื่อแสดงกล่องโต้ตอบต่อไปนี้ -
python demo.py
ผู้ใช้สามารถป้อนข้อมูลในช่องป้อนข้อมูล แต่การคลิกที่ปุ่มเพิ่มจะไม่สร้างการดำเนินการใด ๆ เนื่องจากไม่เกี่ยวข้องกับฟังก์ชันใด ๆ การตอบสนองต่อการตอบสนองที่ผู้ใช้สร้างขึ้นเรียกว่าเป็นevent handling.
แตกต่างจากแอปพลิเคชันโหมดคอนโซลซึ่งดำเนินการในลักษณะตามลำดับแอปพลิเคชันที่ใช้ GUI จะขับเคลื่อนด้วยเหตุการณ์ ฟังก์ชันหรือวิธีการทำงานเพื่อตอบสนองต่อการกระทำของผู้ใช้เช่นการคลิกที่ปุ่มเลือกรายการจากคอลเลกชันหรือการคลิกเมาส์เป็นต้นเรียกว่าevents.
วิดเจ็ตที่ใช้สร้างอินเทอร์เฟซ GUI ทำหน้าที่เป็นแหล่งที่มาของเหตุการณ์ดังกล่าว วิดเจ็ต PyQt แต่ละตัวซึ่งมาจากคลาส QObject ได้รับการออกแบบมาเพื่อปล่อย‘signal’เพื่อตอบสนองต่อเหตุการณ์อย่างน้อยหนึ่งเหตุการณ์ สัญญาณในตัวเองไม่ได้ดำเนินการใด ๆ แต่จะ 'เชื่อมต่อ' กับไฟล์‘slot’. สล็อตสามารถเป็นอย่างไรก็ได้callable Python function.
การใช้ตัวแก้ไขสัญญาณ / สล็อตของนักออกแบบ Qt
ขั้นแรกให้ออกแบบรูปแบบง่ายๆด้วยตัวควบคุม LineEdit และ PushButton
เป็นที่ต้องการว่าหากกดปุ่มเนื้อหาของกล่องข้อความควรถูกลบ วิดเจ็ต QLineEdit มีเมธอด clear () สำหรับวัตถุประสงค์นี้ ดังนั้นปุ่มclicked สัญญาณจะเชื่อมต่อกับ clear() วิธีการของกล่องข้อความ
ในการเริ่มต้นให้เลือกแก้ไขสัญญาณ / สล็อตจากเมนูแก้ไข (หรือกด F4) จากนั้นไฮไลต์ปุ่มด้วยเมาส์แล้วลากเคอร์เซอร์ไปที่กล่องข้อความ
เมื่อปล่อยเมาส์กล่องโต้ตอบที่แสดงสัญญาณของปุ่มและวิธีการของสล็อตจะปรากฏขึ้น เลือก clicked signal และ clear () method
หน้าต่าง Signal / Slot Editor ที่ด้านล่างขวาจะแสดงผลลัพธ์ -
บันทึกรหัส ui และ Build และ Python จากไฟล์ ui ดังที่แสดงในโค้ดด้านล่าง -
pyuic5 -x signalslot.ui -o signalslot.py
รหัส Python ที่สร้างขึ้นจะมีการเชื่อมต่อระหว่างสัญญาณและสล็อตโดยคำสั่งต่อไปนี้ -
self.pushButton.clicked.connect(self.lineEdit.clear)
เรียกใช้ signallot.py และป้อนข้อความใน LineEdit ข้อความจะถูกล้างหากกดปุ่ม
การสร้างการเชื่อมต่อช่องสัญญาณ
แทนที่จะใช้ Designer คุณสามารถสร้างการเชื่อมต่อช่องสัญญาณได้โดยตรงโดยทำตามไวยากรณ์ -
widget.signal.connect(slot_function)
สมมติว่าจะเรียกใช้ฟังก์ชันเมื่อมีการคลิกปุ่ม ที่นี่สัญญาณที่คลิกจะเชื่อมต่อกับฟังก์ชันที่โทรได้ สามารถทำได้โดยใช้เทคนิคต่อไปนี้ -
button.clicked.connect(slot_function)
ตัวอย่าง
ในตัวอย่างต่อไปนี้อ็อบเจ็กต์ QPushButton สองตัว (b1 และ b2) ถูกเพิ่มในหน้าต่าง QDialog เราต้องการเรียกใช้ฟังก์ชัน b1_clicked () และ b2_clicked () เมื่อคลิก b1 และ b2 ตามลำดับ
เมื่อคลิก b1 สัญญาณคลิก () จะเชื่อมต่อกับฟังก์ชัน b1_clicked () -
b1.clicked.connect(b1_clicked())
เมื่อคลิก b2 สัญญาณคลิก () จะเชื่อมต่อกับฟังก์ชัน b2_clicked ()
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
win = QDialog()
b1 = QPushButton(win)
b1.setText("Button1")
b1.move(50,20)
b1.clicked.connect(b1_clicked)
b2 = QPushButton(win)
b2.setText("Button2")
b2.move(50,50)
b2.clicked.connect(b2_clicked)
win.setGeometry(100,100,200,100)
win.setWindowTitle("PyQt5")
win.show()
sys.exit(app.exec_())
def b1_clicked():
print ("Button 1 clicked")
def b2_clicked():
print ("Button 2 clicked")
if __name__ == '__main__':
window()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -
เอาต์พุต
Button 1 clicked
Button 2 clicked
คุณสามารถวางวิดเจ็ต GUI ไว้ในหน้าต่างคอนเทนเนอร์ได้โดยระบุพิกัดสัมบูรณ์ที่วัดเป็นพิกเซล พิกัดสัมพันธ์กับขนาดของหน้าต่างที่กำหนดโดยเมธอด setGeometry ()
setGeometry () ไวยากรณ์
QWidget.setGeometry(xpos, ypos, width, height)
ในข้อมูลโค้ดต่อไปนี้หน้าต่างระดับบนสุดที่มีขนาด 300 คูณ 200 พิกเซลจะแสดงที่ตำแหน่ง (10, 10) บนจอภาพ
import sys
from PyQt4 import QtGui
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
b = QtGui.QPushButton(w)
b.setText("Hello World!")
b.move(50,20)
w.setGeometry(10,10,300,200)
w.setWindowTitle(“PyQt”)
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
ก PushButton เพิ่มวิดเจ็ตในหน้าต่างและวางไว้ที่ตำแหน่ง 50 พิกเซลไปทางขวาและ 20 พิกเซลด้านล่างตำแหน่งซ้ายบนของหน้าต่าง
อย่างไรก็ตามตำแหน่งที่แน่นอนนี้ไม่เหมาะสมเนื่องจากเหตุผลต่อไปนี้ -
ตำแหน่งของวิดเจ็ตไม่เปลี่ยนแปลงแม้ว่าจะปรับขนาดหน้าต่างแล้วก็ตาม
ลักษณะที่ปรากฏอาจไม่เหมือนกันในอุปกรณ์แสดงผลต่างๆที่มีความละเอียดต่างกัน
การปรับเปลี่ยนเค้าโครงทำได้ยากเนื่องจากอาจต้องออกแบบแบบฟอร์มใหม่ทั้งหมด
PyQt API มีคลาสเลย์เอาต์สำหรับการจัดการตำแหน่งวิดเจ็ตภายในคอนเทนเนอร์ที่สวยงามยิ่งขึ้น ข้อดีของผู้จัดการเค้าโครงเหนือตำแหน่งที่แน่นอนคือ -
วิดเจ็ตภายในหน้าต่างจะถูกปรับขนาดโดยอัตโนมัติ
ตรวจสอบให้แน่ใจว่ามีลักษณะสม่ำเสมอบนอุปกรณ์แสดงผลที่มีความละเอียดแตกต่างกัน
การเพิ่มหรือลบวิดเจ็ตแบบไดนามิกสามารถทำได้โดยไม่ต้องออกแบบใหม่
ชุดเครื่องมือ Qt กำหนดเค้าโครงต่างๆที่สามารถใช้ได้กับยูทิลิตี้ Qt Designer
นี่คือรายชื่อชั้นเรียนที่เราจะพูดถึงทีละคนในบทนี้
ซีเนียร์ | ชั้นเรียนและคำอธิบาย |
---|---|
1 | QBoxLayout คลาส QBoxLayout จัดวางวิดเจ็ตในแนวตั้งหรือแนวนอน คลาสที่ได้รับมาคือ QVBoxLayout (สำหรับการจัดเรียงวิดเจ็ตในแนวตั้ง) และ QHBoxLayout (สำหรับการจัดเรียงวิดเจ็ตในแนวนอน) |
2 | QGridLayout วัตถุคลาส GridLayout นำเสนอด้วยตารางของเซลล์ที่จัดเรียงเป็นแถวและคอลัมน์ คลาสนี้มีเมธอด addWidget () สามารถเพิ่มวิดเจ็ตใด ๆ ได้โดยระบุจำนวนแถวและคอลัมน์ของเซลล์ |
3 | QFormLayout QFormLayout เป็นวิธีที่สะดวกในการสร้างฟอร์มคอลัมน์สองคอลัมน์โดยแต่ละแถวประกอบด้วยฟิลด์อินพุตที่เกี่ยวข้องกับเลเบล ตามแบบแผนคอลัมน์ด้านซ้ายมีป้ายกำกับและคอลัมน์ด้านขวาประกอบด้วยฟิลด์อินพุต |
นี่คือรายการวิดเจ็ตที่เราจะพูดถึงทีละรายการในบทนี้
ซีเนียร์ No | วิดเจ็ตและคำอธิบาย |
---|---|
1 | QLabel ออบเจ็กต์ QLabel ทำหน้าที่เป็นตัวยึดเพื่อแสดงข้อความหรือรูปภาพที่ไม่สามารถแก้ไขได้หรือภาพยนตร์ GIF แบบเคลื่อนไหว นอกจากนี้ยังสามารถใช้เป็นคีย์ช่วยในการจำสำหรับวิดเจ็ตอื่น ๆ |
2 | QLineEdit ออบเจ็กต์ QLineEdit เป็นช่องป้อนข้อมูลที่ใช้บ่อยที่สุด มีช่องสำหรับป้อนข้อความหนึ่งบรรทัด ในการป้อนข้อความหลายบรรทัดจำเป็นต้องใช้วัตถุ QTextEdit |
3 | QPushButton ใน PyQt API อ็อบเจ็กต์คลาส QPushButton จะแสดงปุ่มซึ่งเมื่อคลิกแล้วสามารถตั้งโปรแกรมให้เรียกใช้ฟังก์ชันบางอย่างได้ |
4 | QRadioButton อ็อบเจ็กต์คลาส QRadioButton แสดงปุ่มที่เลือกได้พร้อมป้ายข้อความ ผู้ใช้สามารถเลือกหนึ่งในหลาย ๆ ตัวเลือกที่นำเสนอในแบบฟอร์ม คลาสนี้มาจากคลาส QAbstractButton |
5 | QCheckBox กล่องสี่เหลี่ยมก่อนป้ายข้อความจะปรากฏขึ้นเมื่อมีการเพิ่มวัตถุ QCheckBox ในหน้าต่างหลัก เช่นเดียวกับ QRadioButton ก็เป็นปุ่มที่เลือกได้เช่นกัน |
6 | QComboBox ออบเจ็กต์ QComboBox แสดงรายการแบบหล่นลงของรายการที่จะเลือก ใช้พื้นที่หน้าจอขั้นต่ำในแบบฟอร์มที่ต้องการเพื่อแสดงเฉพาะรายการที่เลือกในปัจจุบัน |
7 | QSpinBox ออบเจ็กต์ QSpinBox นำเสนอผู้ใช้ด้วยกล่องข้อความซึ่งแสดงจำนวนเต็มพร้อมปุ่มขึ้น / ลงทางด้านขวา |
8 | QSlider Widget & Signal ออบเจ็กต์คลาส QSlider นำเสนอผู้ใช้ด้วยร่องที่สามารถเคลื่อนย้ายที่จับได้ เป็นวิดเจ็ตคลาสสิกในการควบคุมค่าที่มีขอบเขต |
9 | QMenuBar, QMenu และ QAction QMenuBar แนวนอนที่อยู่ใต้แถบหัวเรื่องของวัตถุ QMainWindow สงวนไว้สำหรับการแสดงวัตถุ QMenu |
10 | QToolBar วิดเจ็ต QToolBar คือพาเนลที่เคลื่อนย้ายได้ซึ่งประกอบด้วยปุ่มข้อความปุ่มพร้อมไอคอนหรือวิดเจ็ตอื่น ๆ |
11 | QInputDialog นี่คือกล่องโต้ตอบที่กำหนดค่าไว้ล่วงหน้าพร้อมช่องข้อความและปุ่มสองปุ่มตกลงและยกเลิก หน้าต่างหลักจะรวบรวมข้อมูลในกล่องข้อความหลังจากที่ผู้ใช้คลิกที่ปุ่ม Ok หรือกด Enter |
12 | QFontDialog อีกไดอะล็อกที่ใช้กันทั่วไปวิดเจ็ตตัวเลือกฟอนต์คือลักษณะที่มองเห็นของคลาส QDialog ผลลัพธ์ของไดอะล็อกนี้คืออ็อบเจ็กต์ Qfont ซึ่งหน้าต่างพาเรนต์สามารถใช้งานได้ |
13 | QFileDialog วิดเจ็ตนี้เป็นไดอะล็อกตัวเลือกไฟล์ ช่วยให้ผู้ใช้สามารถนำทางผ่านระบบไฟล์และเลือกไฟล์เพื่อเปิดหรือบันทึก กล่องโต้ตอบถูกเรียกใช้ผ่านฟังก์ชันแบบคงที่หรือโดยการเรียกฟังก์ชัน exec_ () บนวัตถุโต้ตอบ |
14 | QTab หากฟอร์มมีเขตข้อมูลจำนวนมากเกินไปที่จะแสดงพร้อมกันสามารถจัดเรียงในหน้าต่างๆที่วางไว้ใต้แต่ละแท็บของวิดเจ็ตแบบแท็บ QTabWidget มีแถบแท็บและพื้นที่หน้า |
15 | QStacked การทำงานของ QStackedWidget นั้นคล้ายกับ QTabWidget นอกจากนี้ยังช่วยในการใช้พื้นที่ไคลเอนต์ของหน้าต่างอย่างมีประสิทธิภาพ |
16 | QSplitter นี่คือตัวจัดการเลย์เอาต์ขั้นสูงอีกตัวหนึ่งซึ่งช่วยให้ขนาดของวิดเจ็ตลูกสามารถเปลี่ยนแปลงได้แบบไดนามิกโดยการลากขอบเขตระหว่างพวกเขา ตัวควบคุม Splitter มีจุดจับที่สามารถลากเพื่อปรับขนาดตัวควบคุม |
17 | QDock หน้าต่างที่เชื่อมต่อได้คือหน้าต่างย่อยที่สามารถคงอยู่ในสถานะลอยหรือสามารถติดกับหน้าต่างหลักในตำแหน่งที่ระบุ ออบเจ็กต์หน้าต่างหลักของคลาส QMainWindow มีพื้นที่ที่สงวนไว้สำหรับหน้าต่างที่เชื่อมต่อได้ |
18 | QStatusBar วัตถุ QMainWindow สงวนแถบแนวนอนที่ด้านล่างเป็นแถบสถานะ ใช้เพื่อแสดงข้อมูลสถานะถาวรหรือตามบริบท |
19 | QList คลาส QListWidget คืออินเทอร์เฟซที่ใช้ไอเท็มเพื่อเพิ่มหรือลบไอเท็มออกจากรายการ แต่ละรายการในรายการคือวัตถุ QListWidgetItem ListWidget สามารถตั้งค่าให้เลือกได้หลายแบบ |
20 | QScrollBar การควบคุมแถบเลื่อนช่วยให้ผู้ใช้สามารถเข้าถึงส่วนต่างๆของเอกสารที่อยู่นอกพื้นที่ที่สามารถดูได้ ให้ตัวบ่งชี้ที่มองเห็นไปยังตำแหน่งปัจจุบัน |
21 | QCalendar วิดเจ็ต QCalendar เป็นตัวควบคุมตัวเลือกวันที่ที่มีประโยชน์ มีมุมมองตามเดือน ผู้ใช้สามารถเลือกวันที่โดยใช้เมาส์หรือแป้นพิมพ์โดยค่าเริ่มต้นคือวันที่ของวันนี้ |
ก QDialogวิดเจ็ตแสดงหน้าต่างระดับบนสุดที่ส่วนใหญ่ใช้เพื่อรวบรวมการตอบสนองจากผู้ใช้ สามารถกำหนดค่าให้เป็นModal (โดยที่บล็อกหน้าต่างหลัก) หรือ Modeless (สามารถข้ามหน้าต่างโต้ตอบได้)
PyQt API มีวิดเจ็ต Dialog ที่กำหนดค่าไว้ล่วงหน้าจำนวนหนึ่งเช่น InputDialog, FileDialog, FontDialog เป็นต้น
ตัวอย่าง
ในตัวอย่างต่อไปนี้ WindowModalityแอตทริบิวต์ของหน้าต่าง Dialog ตัดสินใจว่าจะเป็นโมดอลหรือไม่มีโหมด ปุ่มใดปุ่มหนึ่งบนกล่องโต้ตอบสามารถตั้งเป็นค่าเริ่มต้นได้ กล่องโต้ตอบจะถูกยกเลิกโดยQDialog.reject() วิธีการเมื่อผู้ใช้กดปุ่ม Escape
PushButton บนหน้าต่าง QWidget ระดับบนสุดเมื่อคลิกจะสร้างหน้าต่าง Dialog กล่องโต้ตอบไม่มีการควบคุมย่อและขยายใหญ่สุดบนแถบชื่อเรื่อง
ผู้ใช้ไม่สามารถยกเลิกกล่องโต้ตอบนี้ในเบื้องหลังได้เนื่องจาก WindowModality ถูกตั้งค่าเป็น ApplicationModal.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
w = QWidget()
btn = QPushButton(w)
btn.setText("Hello World!")
btn.move(100,50)
btn.clicked.connect(showdialog)
w.setWindowTitle("PyQt Dialog demo")
w.show()
sys.exit(app.exec_())
def showdialog():
dlg = QDialog()
b1 = QPushButton("ok",dlg)
b1.move(50,50)
dlg.setWindowTitle("Dialog") 9. PyQt5 — QDialog Class
dlg.setWindowModality(Qt.ApplicationModal)
dlg.exec_()
if __name__ == '__main__':
window()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ คลิกที่ปุ่มในหน้าต่างหลักและกล่องโต้ตอบจะปรากฏขึ้น -
QMessageBoxเป็นกล่องโต้ตอบโมดอลที่ใช้กันทั่วไปเพื่อแสดงข้อความให้ข้อมูลและขอให้ผู้ใช้ตอบกลับโดยคลิกปุ่มมาตรฐานปุ่มใดปุ่มหนึ่ง ปุ่มมาตรฐานแต่ละปุ่มมีคำอธิบายภาพที่กำหนดไว้ล่วงหน้าบทบาทและส่งกลับตัวเลขฐานสิบหกที่กำหนดไว้ล่วงหน้า
วิธีการและการแจงนับที่สำคัญที่เกี่ยวข้องกับคลาส QMessageBox มีให้ในตารางต่อไปนี้ -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | setIcon() แสดงไอคอนที่กำหนดไว้ล่วงหน้าที่สอดคล้องกับความรุนแรงของข้อความ
|
2 | setText() ตั้งค่าข้อความของข้อความหลักที่จะแสดง |
3 | setInformativeText() แสดงข้อมูลเพิ่มเติม |
4 | setDetailText() กล่องโต้ตอบแสดงปุ่มรายละเอียด ข้อความนี้ปรากฏขึ้นเมื่อคลิก |
5 | setTitle() แสดงหัวเรื่องที่กำหนดเองของไดอะล็อก |
6 | setStandardButtons() รายการปุ่มมาตรฐานที่จะแสดง แต่ละปุ่มเชื่อมโยงกับ QMessageBox ตกลง 0x00000400 QMessageBox เปิด 0x00002000 QMessageBox บันทึก 0x00000800 QMessageBox ยกเลิก 0x00400000 QMessageBox ปิด 0x00200000 QMessageBox ใช่ 0x00004000 QMessageBox ไม่มี 0x00010000 QMessageBox.Abort 0x00040000 QMessageBox.Retry 0x00080000 QMessageBox ละเว้น 0x00100000 |
7 | setDefaultButton() ตั้งค่าปุ่มเป็นค่าเริ่มต้น จะส่งสัญญาณคลิกหากกด Enter |
8 | setEscapeButton() ตั้งค่าปุ่มให้ถือว่าเป็นคลิกหากกดแป้น Escape |
ตัวอย่าง
ในตัวอย่างต่อไปนี้คลิกสัญญาณของปุ่มบนหน้าต่างระดับบนสุดฟังก์ชันที่เชื่อมต่อจะแสดงกล่องโต้ตอบกล่องข้อความ
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("This is a message box")
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
msg.setDetailedText("The details are as follows:")
ฟังก์ชัน setStandardButton () จะแสดงปุ่มที่ต้องการ
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
buttonClicked () สัญญาณเชื่อมต่อกับฟังก์ชั่นสล็อตซึ่งระบุคำอธิบายของแหล่งที่มาของสัญญาณ
msg.buttonClicked.connect(msgbtn)
โค้ดที่สมบูรณ์สำหรับตัวอย่างมีดังนี้ -
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
w = QWidget()
b = QPushButton(w)
b.setText("Show message!")
b.move(100,50)
b.clicked.connect(showdialog)
w.setWindowTitle("PyQt MessageBox demo")
w.show()
sys.exit(app.exec_())
def showdialog():
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("This is a message box")
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
msg.setDetailedText("The details are as follows:")
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msg.buttonClicked.connect(msgbtn)
retval = msg.exec_()
def msgbtn(i):
print ("Button pressed is:",i.text())
if __name__ == '__main__':
window()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ กล่องข้อความจะปรากฏขึ้นเมื่อคลิกปุ่มหน้าต่างหลัก -
หากคุณคลิกที่ปุ่มตกลงหรือยกเลิกบน MessageBox ผลลัพธ์ต่อไปนี้จะถูกสร้างขึ้นบนคอนโซล -
Button pressed is: OK
Button pressed is: Cancel
แอปพลิเคชัน 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()
เรียกใช้โค้ดด้านบนและสามหน้าต่างในรูปแบบเรียงซ้อนและเรียงต่อกัน -
ข้อกำหนดของ drag and dropเป็นเรื่องง่ายมากสำหรับผู้ใช้ พบได้ในแอปพลิเคชันเดสก์ท็อปจำนวนมากที่ผู้ใช้สามารถคัดลอกหรือย้ายวัตถุจากหน้าต่างหนึ่งไปยังอีกหน้าต่างหนึ่งได้
การถ่ายโอนข้อมูลแบบลากและวางแบบ MIME ขึ้นอยู่กับ QDrag ชั้นเรียน QMimeDataออบเจ็กต์เชื่อมโยงข้อมูลกับประเภท MIME ที่สอดคล้องกัน จะถูกเก็บไว้ในคลิปบอร์ดแล้วใช้ในกระบวนการลากและวาง
ฟังก์ชันคลาส QMimeData ต่อไปนี้อนุญาตให้ตรวจจับและใช้ประเภท MIME ได้อย่างสะดวก
ผู้ทดสอบ | Getter | Setter | ประเภท MIME |
---|---|---|---|
hasText () | ข้อความ () | setText () | ข้อความ / ธรรมดา |
hasHtml () | html () | setHtml () | ข้อความ / html |
hasUrls () | URL () | setUrls () | ข้อความ / uri-list |
hasImage () | imageData () | setImageData () | ภาพ/ * |
hasColor () | colorData () | setColorData () | ใบสมัคร / x-color |
วัตถุ QWidget จำนวนมากรองรับกิจกรรมการลากและวาง ผู้ที่อนุญาตให้ลากข้อมูลได้ setDragEnabled () ซึ่งต้องตั้งค่าเป็น true ในทางกลับกันวิดเจ็ตควรตอบสนองต่อเหตุการณ์ลากและวางเพื่อจัดเก็บข้อมูลที่ลากเข้ามา
DragEnterEvent จัดเตรียมเหตุการณ์ที่ถูกส่งไปยังวิดเจ็ตเป้าหมายเมื่อการดำเนินการลากเข้ามา
DragMoveEvent ใช้เมื่อการดำเนินการลากและวางกำลังดำเนินการ
DragLeaveEvent ถูกสร้างขึ้นเมื่อการดำเนินการลากแล้วปล่อยออกจากวิดเจ็ต
DropEventในทางกลับกันเกิดขึ้นเมื่อการดร็อปเสร็จสิ้น การดำเนินการที่เสนอของกิจกรรมสามารถยอมรับหรือปฏิเสธได้ตามเงื่อนไข
ตัวอย่าง
ในรหัสต่อไปนี้ไฟล์ DragEnterEventตรวจสอบว่าข้อมูล MIME ของเหตุการณ์มีข้อความหรือไม่ ถ้าใช่จะยอมรับการดำเนินการที่เสนอของเหตุการณ์และข้อความจะถูกเพิ่มเป็นรายการใหม่ใน ComboBox
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class combo(QComboBox):
def __init__(self, title, parent):
super(combo, self).__init__( parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, e):
print (e)
if e.mimeData().hasText():
e.accept()
else:
e.ignore()
def dropEvent(self, e):
self.addItem(e.mimeData().text())
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
lo = QFormLayout()
lo.addRow(QLabel("Type some text in textbox and drag it into combo box"))
edit = QLineEdit()
edit.setDragEnabled(True)
com = combo("Button", self)
lo.addRow(edit,com)
self.setLayout(lo)
self.setWindowTitle('Simple drag and drop')
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
if __name__ == '__main__':
main()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -
PyQt5 ไลบรารีประกอบด้วยไฟล์ QtSqlโมดูล. เป็นระบบคลาสที่ซับซ้อนในการสื่อสารกับฐานข้อมูลที่ใช้ SQL จำนวนมาก มันQSqlDatabaseให้การเข้าถึงผ่านวัตถุการเชื่อมต่อ ต่อไปนี้เป็นรายการไดรเวอร์ SQL ที่มีอยู่ในปัจจุบัน -
ซีเนียร์ | ประเภทไดรเวอร์และคำอธิบาย |
---|---|
1 | QDB2 IBM DB2 |
2 | QIBASE ไดรเวอร์ Borland InterBase |
3 | QMYSQL ไดร์เวอร์ MySQL |
4 | QOCI ไดรเวอร์ Oracle Call Interface |
5 | QODBC ODBC Driver (รวมถึง Microsoft SQL Server) |
6 | QPSQL ไดร์เวอร์ PostgreSQL |
7 | QSQLITE SQLite เวอร์ชัน 3 ขึ้นไป |
8 | QSQLITE2 SQLite เวอร์ชัน 2 |
ตัวอย่าง
สำหรับบทนี้การเชื่อมต่อกับฐานข้อมูล SQLite ถูกสร้างขึ้นโดยใช้วิธีการแบบคงที่ -
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')
วิธีอื่น ๆ ของคลาส QSqlDatabase มีดังนี้ -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | setDatabaseName() ตั้งชื่อฐานข้อมูลที่ต้องการการเชื่อมต่อ |
2 | setHostName() ตั้งชื่อของโฮสต์ที่ติดตั้งฐานข้อมูล |
3 | setUserName() ระบุชื่อผู้ใช้สำหรับการเชื่อมต่อ |
4 | setPassword() ตั้งรหัสผ่านของวัตถุการเชื่อมต่อถ้ามี |
5 | commit() ทำธุรกรรมและส่งคืนจริงหากสำเร็จ |
6 | rollback() ย้อนกลับธุรกรรมฐานข้อมูล |
7 | close() ปิดการเชื่อมต่อ |
QSqlQueryคลาสมีฟังก์ชันในการดำเนินการและจัดการคำสั่ง SQL สามารถเรียกใช้แบบสอบถาม SQL ทั้งประเภท DDL และ DML ได้ ขั้นตอนแรกคือการสร้างฐานข้อมูล SQlite โดยใช้คำสั่งต่อไปนี้ -
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sportsdatabase.db')
ถัดไปรับวัตถุแบบสอบถามด้วย QSqlQuery() method และเรียก method ที่สำคัญที่สุด exec_ () ซึ่งใช้เป็นอาร์กิวเมนต์สตริงที่มีคำสั่ง SQL ที่จะดำเนินการ
query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key, " "firstname varchar(20), lastname varchar(20))")
สคริปต์ต่อไปนี้สร้างฐานข้อมูล SQLite sports.db ด้วยตารางของ sportsperson ที่เติมด้วยเร็กคอร์ดห้ารายการ
import sys
from PyQt5.QtSql import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def createDB():
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sportsdatabase.db')
if not db.open():
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setText("Error in Database Creation")
retval = msg.exec_()
return False
query = QSqlQuery()
query.exec_("create table sportsmen(
id int primary key, ""firstname varchar(20), lastname varchar(20))")
query.exec_("insert into sportsmen values(101, 'Roger', 'Federer')")
query.exec_("insert into sportsmen values(102, 'Christiano', 'Ronaldo')")
query.exec_("insert into sportsmen values(103, 'Ussain', 'Bolt')")
query.exec_("insert into sportsmen values(104, 'Sachin', 'Tendulkar')")
query.exec_("insert into sportsmen values(105, 'Saina', 'Nehwal')")
return True
if __name__ == '__main__':
app = QApplication(sys.argv)
createDB()
เพื่อยืนยันว่าฐานข้อมูล SQLite ถูกสร้างขึ้นพร้อมกับบันทึกด้านบนที่เพิ่มในตารางนักกีฬาในนั้นให้ใช้ยูทิลิตี้ SQLite Gui ที่เรียกว่า SQLiteStudio.
QSqlTableModelคลาสใน PyQt เป็นอินเทอร์เฟซระดับสูงที่จัดเตรียมโมเดลข้อมูลที่สามารถแก้ไขได้สำหรับการอ่านและเขียนเรกคอร์ดในตารางเดียว โมเดลนี้ใช้เพื่อเติมข้อมูลไฟล์QTableViewวัตถุ. นำเสนอมุมมองแบบเลื่อนและแก้ไขให้กับผู้ใช้ซึ่งสามารถวางไว้บนหน้าต่างระดับบนสุดใดก็ได้
อ็อบเจ็กต์ QSqlTableModel ถูกประกาศในลักษณะต่อไปนี้ -
model = QtSql.QSqlTableModel()
กลยุทธ์การแก้ไขสามารถตั้งค่าได้ดังต่อไปนี้ -
QSqlTableModel OnFieldChange | การเปลี่ยนแปลงทั้งหมดจะมีผลทันที |
---|---|
QSqlTableModel OnRowChange | การเปลี่ยนแปลงจะถูกนำไปใช้เมื่อผู้ใช้เลือกแถวอื่น |
QSqlTableModel OnManualSubmit | การเปลี่ยนแปลงทั้งหมดจะถูกแคชจนกว่าจะมีการเรียก submitAll () หรือ revertAll () |
ตัวอย่าง
ในตัวอย่างต่อไปนี้ใช้ตาราง sportsperson เป็นต้นแบบและกำหนดกลยุทธ์เป็น -
model.setTable('sportsmen')
model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
model.select()
คลาส QTableView เป็นส่วนหนึ่งของเฟรมเวิร์ก Model / View ใน PyQt วัตถุ QTableView ถูกสร้างขึ้นดังนี้ -
view = QtGui.QTableView()
view.setModel(model)
view.setWindowTitle(title)
return view
ออบเจ็กต์ QTableView นี้และวิดเจ็ต QPushButton สองรายการจะถูกเพิ่มลงในหน้าต่าง QDialog ระดับบนสุด สัญญาณคลิก () ของปุ่มเพิ่มเชื่อมต่อกับ addrow () ซึ่งทำหน้าที่ insertRow () บนตารางโมเดล
button.clicked.connect(addrow)
def addrow():
print model.rowCount()
ret = model.insertRows(model.rowCount(), 1)
print ret
ช่องที่เกี่ยวข้องกับปุ่มลบเรียกใช้ฟังก์ชันแลมบ์ดาที่ลบแถวซึ่งผู้ใช้เลือกไว้
btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
รหัสที่สมบูรณ์มีดังนี้ -
import sys
from PyQt5.QtSql import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def initializeModel(model):
model.setTable('sportsmen')
model.setEditStrategy(QSqlTableModel.OnFieldChange)
model.select()
model.setHeaderData(0, Qt.Horizontal, "ID")
model.setHeaderData(1, Qt.Horizontal, "First name")
model.setHeaderData(2, Qt.Horizontal, "Last name")
def createView(title, model):
view = QTableView()
view.setModel(model)
view.setWindowTitle(title)
return view
def addrow():
print (model.rowCount())
ret = model.insertRows(model.rowCount(), 1)
print (ret)
def findrow(i):
delrow = i.row()
if __name__ == '__main__':
app = QApplication(sys.argv)
db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sportsdatabase.db')
model = QSqlTableModel()
delrow = -1
initializeModel(model)
view1 = createView("Table Model (View 1)", model)
view1.clicked.connect(findrow)
dlg = QDialog()
layout = QVBoxLayout()
layout.addWidget(view1)
button = QPushButton("Add a row")
button.clicked.connect(addrow)
layout.addWidget(button)
btn1 = QPushButton("del a row")
btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
layout.addWidget(btn1)
dlg.setLayout(layout)
dlg.setWindowTitle("Database Demo")
dlg.show()
sys.exit(app.exec_())
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -
ลองเพิ่มและลบระเบียนสองสามรายการแล้วกลับไปที่ SQLiteStudio เพื่อยืนยันธุรกรรม
ทั้งหมด QWidgetคลาสใน PyQt เป็นคลาสย่อยจากคลาส QPaintDevice กQPaintDeviceเป็นนามธรรมของพื้นที่สองมิติที่สามารถวาดโดยใช้ QPainter ขนาดของอุปกรณ์ทาสีวัดเป็นพิกเซลโดยเริ่มจากมุมซ้ายบน
QPainterคลาสทำการวาดภาพระดับต่ำบนวิดเจ็ตและอุปกรณ์ที่ทาสีอื่น ๆ เช่นเครื่องพิมพ์ โดยปกติจะใช้ในเหตุการณ์สีของวิดเจ็ต QPaintEvent เกิดขึ้นเมื่อใดก็ตามที่มีการอัปเดตลักษณะของวิดเจ็ต
จิตรกรเปิดใช้งานโดยการเรียกไฟล์ begin() วิธีการในขณะที่ end()วิธีการปิดใช้งาน ระหว่างนั้นลวดลายที่ต้องการจะถูกวาดด้วยวิธีการที่เหมาะสมดังแสดงในตารางต่อไปนี้
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | begin() เริ่มวาดภาพบนอุปกรณ์เป้าหมาย |
2 | drawArc() วาดส่วนโค้งระหว่างมุมเริ่มต้นและมุมสิ้นสุด |
3 | drawEllipse() วาดวงรีภายในสี่เหลี่ยมผืนผ้า |
4 | drawLine() ลากเส้นพร้อมระบุพิกัดปลายทาง |
5 | drawPixmap() แยก pixmap ออกจากไฟล์รูปภาพและแสดงในตำแหน่งที่ระบุ |
6 | drwaPolygon() วาดรูปหลายเหลี่ยมโดยใช้พิกัดอาร์เรย์ |
7 | drawRect() วาดรูปสี่เหลี่ยมผืนผ้าเริ่มต้นที่พิกัดด้านซ้ายบนพร้อมกับความกว้างและความสูงที่กำหนด |
8 | drawText() แสดงข้อความตามพิกัดที่กำหนด |
9 | fillRect() เติมสี่เหลี่ยมด้วยพารามิเตอร์ QColor |
10 | setBrush() กำหนดรูปแบบแปรงสำหรับการวาดภาพ |
11 | setPen() กำหนดสีขนาดและรูปแบบของปากกาที่จะใช้สำหรับการวาดภาพ |
ตัวอย่าง
ในโค้ดต่อไปนี้จะใช้วิธีการวาดรูปแบบต่างๆของ PyQt
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.text = "hello world"
self.setGeometry(100,100, 400,300)
self.setWindowTitle('Draw Demo')
self.show()
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
qp.setPen(QColor(Qt.red))
qp.setFont(QFont('Arial', 20))
qp.drawText(10,50, "hello Python")
qp.setPen(QColor(Qt.blue))
qp.drawLine(10,100,100,100)
qp.drawRect(10,150,150,100)
qp.setPen(QColor(Qt.yellow))
qp.drawEllipse(100,50,100,50)
qp.drawPixmap(220,10,QPixmap("pythonlogo.png"))
qp.fillRect(20,175,130,70,QBrush(Qt.SolidPattern))
qp.end()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -
ในบทนี้เราจะเรียนรู้ Brush Style Constants
ค่าคงที่สไตล์แปรง
ด้านล่างนี้คือค่าคงที่รูปแบบแปรง -
Qt. NoBrush | ไม่มีรูปแบบแปรง |
Qt.SolidPattern | สีสม่ำเสมอ |
Qt.Dense1Pattern | รูปแบบแปรงที่หนาแน่นมาก |
Qt.HorPattern | เส้นแนวนอน |
Qt.VerPattern | เส้นแนวตั้ง |
Qt.CrossPattern | ข้ามเส้นแนวนอนและแนวตั้ง |
Qt.BDiagPattern | เส้นทแยงมุมถอยหลัง |
Qt.FDiagPattern | ส่งต่อเส้นทแยงมุม |
Qt.DiagCrossPattern | ข้ามเส้นทแยงมุม |
รูปแบบสี QC ที่กำหนดไว้ล่วงหน้า
ด้านล่างนี้คือรูปแบบสี QC ที่กำหนดไว้ล่วงหน้า -
Qt. NoBrush | ไม่มีรูปแบบแปรง |
Qt.SolidPattern | สีสม่ำเสมอ |
Qt.Dense1Pattern | รูปแบบแปรงที่หนาแน่นมาก |
Qt.HorPattern | เส้นแนวนอน |
Qt.VerPattern | เส้นแนวตั้ง |
Qt.CrossPattern | ข้ามเส้นแนวนอนและแนวตั้ง |
Qt.BDiagPattern | เส้นทแยงมุมถอยหลัง |
Qt.FDiagPattern | ส่งต่อเส้นทแยงมุม |
Qt.DiagCrossPattern | ข้ามเส้นทแยงมุม |
วัตถุ QColor ที่กำหนดไว้ล่วงหน้า
ด้านล่างนี้เป็นวัตถุ QColor ที่กำหนดไว้ล่วงหน้า -
Qt.white |
Qt.black |
Qt.red |
Qt.darkRed |
Qt.green |
Qt. DarkGreen |
Qt.blue |
Qt.cyan |
Qt. สีม่วง |
Qt. สีเหลือง |
Qt. มืดเหลือง |
Qt.gray |
QClipboardclass ให้การเข้าถึงคลิปบอร์ดทั้งระบบซึ่งมีกลไกง่ายๆในการคัดลอกและวางข้อมูลระหว่างแอปพลิเคชัน การกระทำของมันคล้ายกับQDrag คลาสและใช้ชนิดข้อมูลที่คล้ายกัน
คลาส QApplication มีวิธีการแบบคงที่ clipboard()ซึ่งส่งคืนการอ้างอิงไปยังวัตถุคลิปบอร์ด คุณสามารถคัดลอกหรือวาง MimeData ประเภทใดก็ได้จากคลิปบอร์ด
ต่อไปนี้เป็นวิธีการคลาสคลิปบอร์ดที่ใช้กันทั่วไป -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | clear() ล้างเนื้อหาคลิปบอร์ด |
2 | setImage() คัดลอก QImage ลงในคลิปบอร์ด |
3 | setMimeData() ตั้งค่าข้อมูล MIME ลงในคลิปบอร์ด |
4 | setPixmap() คัดลอกวัตถุ Pixmap ในคลิปบอร์ด |
5 | setText() คัดลอก QString ในคลิปบอร์ด |
6 | text() ดึงข้อความจากคลิปบอร์ด |
สัญญาณที่เกี่ยวข้องกับวัตถุคลิปบอร์ดคือ -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | dataChanged() เมื่อใดก็ตามที่ข้อมูลคลิปบอร์ดเปลี่ยนแปลง |
ตัวอย่าง
ในตัวอย่างต่อไปนี้วัตถุ TextEdit สองรายการและปุ่มกดสองปุ่มจะถูกเพิ่มลงในหน้าต่างระดับบนสุด
ในการเริ่มต้นด้วยวัตถุคลิปบอร์ดจะถูกสร้างอินสแตนซ์ คัดลอก () วิธีการของวัตถุ textedit คัดลอกข้อมูลไปยังคลิปบอร์ดของระบบ เมื่อคลิกปุ่ม Paste จะดึงข้อมูลคลิปบอร์ดและวางลงในออบเจ็กต์ textedit อื่น
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QVBoxLayout()
self.edit1=QTextEdit()
hbox.addWidget(self.edit1)
self.btn1=QPushButton("Copy")
hbox.addWidget(self.btn1)
self.edit2=QTextEdit()
self.btn2=QPushButton("Paste")
hbox.addWidget(self.edit2)
hbox.addWidget(self.btn2)
self.btn1.clicked.connect(self.copytext)
self.btn2.clicked.connect(self.pastetext)
self.setLayout(hbox)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Clipboard')
self.show()
def copytext(self):
#clipboard.setText(self.edit1.copy())
self.edit1.copy()
print (clipboard.text())
msg=QMessageBox()
msg.setText(clipboard.text()+" copied on clipboard")
msg.exec_()
def pastetext(self):
self.edit2.setText(clipboard.text())
app = QApplication(sys.argv)
clipboard=app.clipboard()
ex = Example()
ex.setWindowTitle("clipboard Example")
sys.exit(app.exec_())
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -
QPixmapคลาสให้การแสดงภาพนอกหน้าจอ สามารถใช้เป็นอ็อบเจ็กต์ QPaintDevice หรือสามารถโหลดลงในวิดเจ็ตอื่นโดยทั่วไปจะเป็นป้ายกำกับหรือปุ่ม
Qt API มีคลาสอื่นที่คล้ายกัน QImageซึ่งเหมาะสำหรับ I / O และการปรับแต่งพิกเซลอื่น ๆ ในทางกลับกัน Pixmap ได้รับการปรับให้เหมาะกับการแสดงบนหน้าจอ ทั้งสองรูปแบบสามารถแปลงกลับกันได้
ประเภทของไฟล์รูปภาพที่สามารถอ่านลงในออบเจ็กต์ QPixmap มีดังนี้ -
BMP | บิตแมปของ Windows |
GIF | รูปแบบการแลกเปลี่ยนกราฟิก (ไม่บังคับ) |
JPG | กลุ่มผู้เชี่ยวชาญด้านการถ่ายภาพร่วม |
JPEG | กลุ่มผู้เชี่ยวชาญด้านการถ่ายภาพร่วม |
PNG | กราฟิกเครือข่ายแบบพกพา |
PBM | บิตแมปแบบพกพา |
PGM | Graymap แบบพกพา |
พีพีเอ็ม | Pixmap แบบพกพา |
XBM | X11 บิตแมป |
XPM | X11 Pixmap |
วิธีการต่อไปนี้มีประโยชน์ในการจัดการวัตถุ QPixmap -
ซีเนียร์ | วิธีการและคำอธิบาย |
---|---|
1 | copy() คัดลอกข้อมูล pixmap จากออบเจ็กต์ QRect |
2 | fromImage() แปลงวัตถุ QImage เป็น QPixmap |
3 | grabWidget() สร้าง pixmap จากวิดเจ็ตที่กำหนด |
4 | grabWindow() สร้าง pixmap ของข้อมูลในหน้าต่าง |
5 | Load() โหลดไฟล์รูปภาพเป็น pixmap |
6 | save() บันทึกอ็อบเจ็กต์ QPixmap เป็นไฟล์ |
7 | toImage แปลง QPixmap เป็น QImage |
การใช้ QPixmap โดยทั่วไปคือการแสดงภาพบนป้าย / ปุ่ม
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงภาพที่แสดงบน QLabel โดยใช้ไฟล์ setPixmap() วิธี.
รหัสที่สมบูรณ์มีดังนี้ -
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():
app = QApplication(sys.argv)
win = QWidget()
l1 = QLabel()
l1.setPixmap(QPixmap("python.png"))
vbox = QVBoxLayout()
vbox.addWidget(l1)
win.setLayout(vbox)
win.setWindowTitle("QPixmap Demo")
win.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -