ต่อจาก
บทที่ ๑
หลังจากที่ในบทที่แล้วได้แนะนำให้รู้จักภาพรวมการใช้งาน และความหมายของ widget แล้ว ในบทนี้จะเป็นเรื่องของการจัดการกับ widget ซึ่งรวมถึง widget หลักที่ใช้เป็นหน้าต่าง และ widget ที่ถูกใส่เป็นส่วนประกอบข้างใน โดยจะใช้ปุ่มกด QPushButton เป็นตัวอย่าง
การใส่ปุ่มกด {QPushButton}
พูดถึง GUI แล้ว สิ่งที่น่าจะเจอบ่อยที่สุดก็คงจะเป็นปุ่มกด ใน qt นั้นปุ่มกดสร้างได้โดยคลาส QPushButton
การใส่ปุ่มกดลงในหน้าต่างทำได้โดยสร้างอินสแตนซ์ของคลาส QPushButton โดยใส่อาร์กิวเมนต์เป็นตัว widget หลัก ที่ต้องการเอาปุ่มไปใส่
QPushButton(widget_หลัก)
แต่ถ้าหากต้องการให้มีข้อความบนปุ่มด้วยก็ให้ใส่ข้อความก่อน แล้วจึงตามด้วย widget หลัก
QPushButton(ข้อความ,widget_หลัก)
ตัวอย่าง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
pumkot = QPushButton('กด กด',natang)
natang.show()
qAp.exec_()
จากนั้นก็จะได้ปุ่มออกมาอยู่ภายในหน้าต่าง ซึ่งลักษณะก็แตกต่างกันไปขึ้นอยู่กับระบบปฏิบัติการที่ใช้
ใน windows10
ใน mac
ใน linux
ดูแล้วใน mac จะสวยที่สุดไม่ว่าจะเป็นตัวหน้าต่างหรือปุ่มกด ดังนั้นในตัวอย่างต่อจากนี้ไปจะแสดงผลการรันใน mac เป็นหลัก
ปุ่มที่ได้ออกมานี้สามารถลองกดดูได้ เพียงแต่ตอนนี้ถึงกดไปก็ไม่มีอะไรเกิดขึ้น เพราะเราแค่สร้างปุ่มขึ้นมาเฉยๆ ยังไม่ได้กำหนดหน้าที่การทำงานให้มัน
เรื่องของการให้ปุ่มทำงานได้นั้นจะเขียนถึงในบทที่ ๔
การตั้งรูปให้ปุ่ม {QIcon}
นอกจากจะใส่ข้อความลงบนปุ่มแล้ว ยังสามารถใส่รูปลงบนปุ่มได้ด้วย โดยหากต้องการใส่รูป เวลาที่สร้างปุ่มให้เพิ่มอาร์กิวเมนต์อีกตัว นำหน้าข้อความ
QPushButton(รูป,ข้อความ,widget_หลัก)
โดยรูปที่ใส่นั้นต้องเป็นออบเจ็กต์ของคลาส QIcon ซึ่งเรียกใช้จากมอดูล PyQt5.QtGui
ในที่นี้ขอใช้ภาพนี้เป็นตัวอย่าง
qbicon.png
ตัวอย่างการใช้
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
from PyQt5.QtGui import QIcon
qAp = QApplication(sys.argv)
natang = QWidget()
pumkot = QPushButton(QIcon('qbicon.png'),'qb',natang)
natang.show()
qAp.exec_()
แล้วก็จะได้ออกมาเป็นแบบนี้ มีทั้งภาพและตัวหนังสืออยู่บนปุ่ม
การกำหนดตำแหน่งและขนาดของ widget หรือหน้าต่าง {.setGeometry}
ในตัวอย่างที่ผ่านมาเราแค่สั่งให้สร้างหน้าต่างกับปุ่มขึ้นมาโดยไม่ได้กำหนดว่าให้มันวางตรงไหนหรือมีขนาดเท่าไหร่ ดังนั้นขนาดกับตำแหน่งก็จะถูกกำหนดเองตามความเหมาะสม โดยอาจขึ้นกับสภาวะแวดล้อมหรือค่าตั้งต้นในนั้น
โดยทั่วไปแล้วเราควรจะกำหนดตำแหน่งหรือขนาดของ widget ให้ ซึ่งก็มีอยู่หลายวิธี แต่วิธีที่เข้าใจง่ายที่สุดก็คือการกำหนดค่าตำแหน่งและขนาดโดยตรง โดยใช้เมธอด .setGeometry
วิธีการใช้
ตัว_widget.setGeometry(ระยะห่างจากขอบบน,ระยะห่างจากขอบซ้าย,ขนาดแนวนอน,ขนาดแนวตั้ง)
ตัวอย่าง ลองใช้เพื่อปรับขนาดและตำแหน่งหน้าต่าง
import sys
from PyQt5.QtWidgets import QApplication,QWidget
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setGeometry(200,200,160,80)
natang.show()
qAp.exec_()
ก็จะได้หน้าต่างขนาด 160×80 แบบนี้ออกมา ส่วนตำแหน่งก็จะอยู่ที่ 200,200 จากมุมซ้ายบนของหน้าจอ
เมธอดนี้ใช้ได้กับ widget ทั้งหมด ซึ่งส่วนประกอบต่างๆภายในหน้าต่างเช่น QPushButton เองก็เป็น widget เช่นกัน จึงสามารถจัดวางได้ด้วยวิธีเดียวกันนี้
ในกรณีที่ใช้กับ widget ที่เป็นส่วนประกอบด้านใน ตำแหน่งในที่นี้จะเป็นตำแหน่งจากมุมบนซ้ายของ widget หลัก
ตัวอย่าง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setGeometry(200,200,250,120)
pumkot = QPushButton('กฎหมายกดปรากฏ',natang)
pumkot.setGeometry(20,10,210,100)
natang.show()
qAp.exec_()
จะได้ปุ่มขนาด 210×100 ที่มีมุมซ้ายบนอยู่ที่ตำแหน่ง 20,10 จากขอบซ้ายบนของหน้าต่าง
กรณีที่ลองทำเป็นคลาส
ในบทที่แล้วก็ได้มีพูดถึงไปเล็กน้อยว่าในกรณีทั่วไปการใช้ pyqt นั้นมักจะเขียนในรูปแบบเป็นคลาส
ในบทเรียนนี้เพื่อความง่ายจะเน้นเขียนแบบไม่ทำเป็นคลาสเป็นหลัก แต่ก็จะขอยกวิธีการเขียนในแบบที่ทำเป็นคลาสมาเทียบไปด้วย
ตัวอย่างที่แล้ว หากเขียนเป็นแบบทำเป็นคลาสก็จะเขียนได้แบบนี้
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
class Natang(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(200,200,250,120)
pumkot = QPushButton('กฎหมายกดปรากฏ',self)
pumkot.setGeometry(20,10,210,100)
self.show()
qAp = QApplication(sys.argv)
natang = Natang()
qAp.exec_()
ผลที่ได้ก็จะออกมาเหมือนเดิม (เลื่อนขึ้นไปดูภาพข้างบนเอา)
จะเห็นว่าเมื่อทำเป็นคลาส ส่วนที่กำหนดขนาดของหน้าต่างและการสร้างและกำหนดขนาดปุ่มจะทำภายใน __init__ ของคลาส แต่เนื้อหาก็เขียนเหมือนกับ เพียงแต่เมื่ออยู่ในคลาส ออบเจ็กต์ตังหน้าต่างจะแทนด้วย self เพราะตัวคลาสที่กำลังสร้างอยู่นี้คือตัวหน้าต่างนั้นเอง
การจัดวางตำแหน่ง widget {.move}
เมธอด .setGeometry นั้นจะเป็นการปรับทั้งขนาดและตำแหน่งของ widget ไปพร้อมกัน แต่ถ้าหากต้องการกำหนดแค่ตำแหน่งก็อาจใช้เมธอด .move แทน
วิธีการใช้ก็คล้ายกับ .setGeometry แค่ใส่แต่ค่าตำแหน่ง
ตัว_widget.move(ระยะห่างจากขอบบน,ระยะห่างจากขอบซ้าย)
ตัวอย่าง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
natang.move(120,120)
pumkot = QPushButton('กด กฎ',natang)
pumkot.move(50,20)
natang.show()
qAp.exec_()
จะได้ปุ่มอยู่ที่ตำแหน่ง 50,20 จากมุมซ้ายบนของหน้าต่าง ส่วนขนาดของปุ่มไม่ได้กำหนดไว้ จึงถูกกำหนดให้เองออกมาเป็นค่าตั้งต้นตามความเหมาะสม
การกำหนดขนาด widget {.resize}
เช่นเดียวกับที่ตำแหน่งกำหนดโดย .move หากต้องการกำหนดขนาดของ widget ทำได้โดยใช้ .resize ซึ่งผลจะเหมือนกับ setGeometry เพียงแต่จะไไม่มีการย้ายตำแหน่ง
วิธีใช้
ตัว_widget.resize(ขนาดแนวนอน,ขนาดแนวตั้ง)
ตัวอย่าง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
natang.resize(300,200)
pumkot1 = QPushButton('กดโกรธ',natang)
pumkot1.resize(210,160)
pumkot2 = QPushButton('กดชอบ',natang)
pumkot2.resize(130,70)
natang.show()
qAp.exec_()
ในที่นี้กำหนดแต่ขนาดแต่ว่าไม่ได้กำหนดตำแหน่ง แบบนี้ปุ่มก็จะอยู่ที่มุมซ้ายบน ส่วนหน้าต่างจะปรากฏขึ้นมากลางหน้าจอ
การกำหนดขนาด widget ตายตัว {.setFixedSize .setFixedWidth .setFixedHeight}
ปกติแล้วหน้าต่างที่สร้างขึ้นมานั้นจะสามารถปรับขนาดได้ แต่หากต้องการให้มีขนาดแน่นอนก็อาจทำได้โดยกำหนดขนาดด้วยเมธอด .setFixedSize หรือถ้าจะกำหนดแค่แนวนอนหรือแนวตั้งก็ใช้ .setFixedWidth กับ .setFixedHeight
วิธีการใช้ก็เหมือนกับ .resize เพียงแต่กรณีที่ใช้กับ widget ตัวหน้าต่างนั้นหน้าต่างที่ได้จะปรับขนาดไม่ได้ ส่วนถ้าใช้กับส่วนประกอบภายในที่แต่ไหนแต่ไรก็ปรับขนาดไม่ได้อยู่แล้วก็มีผลไม่ต่างจากการใช้ .resize คือแค่ทำการปรับขนาดไปเป็นขนาดที่กำหนด
ตัวอย่าง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setFixedSize(250,220)
pumkot1 = QPushButton('กดหมด',natang)
pumkot1.setFixedWidth(240)
pumkot1.setFixedHeight(210)
pumkot2 = QPushButton('กดบน',natang)
pumkot2.setFixedSize(170,100)
natang.show()
qAp.exec_()
ในกรณีที่ใช้ mac จะเห็นว่าหน้าต่างที่ได้ไม่มีปุ่มสีเขียวซึ่งใช้สำหรับขยายเต็มจอ เหลือแค่ปุ่มปิด (สีแดง) กับปุ่มย่อหน้าต่าง (สีเหลือง) นั่นเพราะหน้าต่างที่ได้นี้ปรับขนาดไม่ได้ ถ้าลองเอาเมาส์ไปวางที่ขอบก็จะไม่มีอะไรเกิดขึ้น
การกำหนดขอบเขตขนาดย่อขยายหน้าต่าง {.setMinimumSize .setMaximumSize}
หากต้องการให้หน้าต่างมีขนาดอยู่ในขอบเขตที่กำหนดก็อาจทำได้โดยใช้ .setMinimumSize เพื่อกำหนดขนาดเล็กสุดและใช้ .setMaximumSize เพื่อกำหนดขนาดใหญ่สุด
และในทำนองเดียวกันถ้าต้องการกำหนดแค่แนวนอนหรือแนวตั้งก็มี .setMinimumWidth .setMaxmumWidth .setMinimumHeight .setMaximumHeight ซึ่งวิธีใช้ก็เช่นเดียวกัน
ตัวอย่างการใช้ .setMinimumSize กับ .setMaximumSize
import sys
from PyQt5.QtWidgets import QApplication,QWidget
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setMinimumSize(200,100)
natang.setMaximumSize(333,222)
natang.show()
qAp.exec_()
ผลที่ได้จะออกมาเป็นหน้าต่างที่มีขนาดเท่ากับที่กำหนดใน .setMaximumSize คือ 333×222 แต่สามารถปรับย่อลงได้ จนเหลือขนาดเล็กสุดตามที่กำหนดใน .setMinimumSize
สรุปท้ายบท
ในบทนี้ได้พูดถึงเรื่องการปรับแต่งจัดวาง widget เป็นหลัก โดยได้ถือโอกาสแสดงวิธีการสร้าง widget ที่สำคัญตัวหนึ่งคือปุ่มกด QPushButton ไปด้วยเพื่อใช้เป็นตัวอย่าง
เมธอดที่ใช้ปรับแต่ง widget เหล่านี้สามารถใช้กับ widget ชนิดอื่นๆที่จะเขียนถึงในบทต่อๆไปหลังจากนี้ได้เช่นกัน
สำหรับเรื่องการวางตำแหน่งของ widget นั้นในที่นี้ใช้ .setGeometry หรือ .move แต่นอกจากนี้แล้วก็ยังมีวิธีการจัดวางเป็นโครง layout แบบต่างๆ เช่น QHBoxLayout, QVBoxLayout, QGridLayout ซึ่งก็จะกล่าวถึงต่อไป
อ่านบทถัดไป >>
บทที่ ๓