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, QtPrintSupportQtWidgets โมดูล

ในคลาส 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()

แสดงไอคอนที่กำหนดไว้ล่วงหน้าที่สอดคล้องกับความรุนแรงของข้อความ

  • Question
  • Information
  • Warning
  • Critical
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()

รหัสด้านบนสร้างผลลัพธ์ต่อไปนี้ -