ต่อจาก
บทที่ ๘
หลังจากที่ในบทก่อนหน้านี้ได้แนะนำ widget ตัวสำคัญตัวหนึ่งคือปุ่มกด QPushButton ไปแล้ว ตั้งแต่บทนี้จะแนะนำ widget ต่างๆที่ใช้สำหรับป้อนข้อมูล
โดยจะเริ่มจาก QLineEdit และ QTextEdit ซึ่งเป็น Widget ที่เอาไว้ป้อนข้อความ
การสร้างช่องกรอกข้อความ {QLineEdit}
QLineEdit นั้นคือช่องเล็กๆที่เอาไว้พิมพ์ข้อความใส่
วิธีการสร้างก็เหมือนกับ QPushButton หรือ QLabel คือให้ใส่ข้อความตั้งต้นไปเป็นพารามิเตอร์ตัวแรก นอกจากนี้หากไม่ใช้โครงก็ให้ใส่ออบเจ็กต์ widget หลักลงไปด้วย
ตัวอย่างการสร้างช่องง่ายๆขึ้นมาง่ายๆโดยไม่ใช้โครง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit
qAp = QApplication(sys.argv)
natang = QWidget()
chongkrok = QLineEdit('/人◕ ‿‿ ◕人\',natang)
chongkrok.setGeometry(10,10,200,30)
natang.show()
qAp.exec_()
ลองสร้างแบบใช้โครง เวลาสร้างไม่ต้องใส่ออบเจ็กต์ widget หลักลงไป แต่ต้องมาใช้ .addWidget เพื่อจับวางใส่โครง
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QHBoxLayout
qAp = QApplication(sys.argv)
natang = QWidget()
khrong = QHBoxLayout()
natang.setLayout(khrong)
chongkrok1 = QLineEdit('@@@')
khrong.addWidget(chongkrok1)
chongkrok1.setFixedSize(180,30)
chongkrok2 = QLineEdit('###')
khrong.addWidget(chongkrok2)
chongkrok2.setFixedSize(160,40)
natang.show()
qAp.exec_()
การปรับรูปแบบ {.setFont .setStyleSheet}
QLineEdit ก็สามารถปรับรูปแบบอักษรได้โดยใช้ .setFont หรือ .setStyleSheetเช่นเดียวกับ QPushButton หรือ QLabel
ตัวอย่างปรับรูปแบบด้วย .setFont
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit
from PyQt5.QtGui import QFont
qAp = QApplication(sys.argv)
natang = QWidget()
chongkrok = QLineEdit('ข้อความ',natang)
chongkrok.setGeometry(10,10,150,30)
font = QFont()
font.setFamily('Tahoma') # ตั้งสกุลฟอนต์
font.setPointSize(20) # กำหนดขนาด
chongkrok.setFont(font)
natang.show()
qAp.exec_()
ตัวอย่างการใช้ .setStyleSheet ซึ่งสามารถปรับอะไรได้หลากหลายกว่า นอกจากปรับตัวหนังสือแล้วก็ยังปรับสีฉากหลังได้ด้วย
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit
qAp = QApplication(sys.argv)
natang = QWidget()
chongkrok = QLineEdit('ข้อความ',natang)
chongkrok.setGeometry(10,10,150,30)
css = '''
background-color: #e5cbfd;
color: #55690e;
font-family: Tahoma;
font-size: 21px;
'''
chongkrok.setStyleSheet(css)
natang.show()
qAp.exec_()
การทำคำสั่งเมื่อกด enter {.returnPressed .text}
เมื่อต้องการที่จะเอาข้อความจากกล่องข้อความนั้นสามารถเอาได้โดยเมธอด .text
ฟังก์ชันที่ต้องการให้ทำเมื่อมีการกด enter สามารถตั้งได้โดย .returnPressed
ตัวอย่างเช่นสร้างกล่องข้อความที่ให้ print แสดงข้อความที่กรอกไปในนั้นออกมาเมื่อกด enter ทำได้ดังนี้
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit
qAp = QApplication(sys.argv)
natang = QWidget()
chongkrok = QLineEdit('',natang)
chongkrok.setGeometry(10,10,120,25)
chongkrok.returnPressed.connect(lambda: print(chongkrok.text()))
natang.show()
qAp.exec_()
ลองพิมพ์อะไรลงไปแล้วกด enter ข้อความในนั้นก็จะถูก print ออกมา
การทำคำสั่งเมื่อพิมพ์เสร็จ {.editingFinished}
ฟังก์ชันที่กำหนดใน .returnPressed นั้นจะทำงานเมื่อเรากด enter เท่านั้น แต่ถ้าต้องการให้ทำงานเมื่อไหร่ก็ตามที่พิมพ์เสร็จก็อาจใช้ .editingFinished
ความหมายของการพิมพ์เสร็จในที่นี้อาจหมายถึงกด enter หรือไม่ก็เอาเมาส์ไปคลิกที่ widget อื่นหรือกด tab ทำให้ไปโฟกัสที่ตัวอื่นแทน
ยกตัวอย่างเช่น ลองสร้างกล่องข้อความขึ้นมา ๒ กล่อง เวลาพิมพ์กล่องหนึ่งแล้วไปกดอีกกล่องก็ให้พิมพ์ข้อความในกล่องเดิมออกมา
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit
qAp = QApplication(sys.argv)
natang = QWidget()
chongkrok1 = QLineEdit('',natang) # ช่องด้านบน
chongkrok1.setGeometry(20,10,130,30)
chongkrok1.editingFinished.connect(lambda: print(f'1: "{chongkrok1.text()}"'))
chongkrok2 = QLineEdit('',natang) # ช่องด้านล่าง
chongkrok2.setGeometry(10,50,150,30)
chongkrok2.editingFinished.connect(lambda: print(f'2: "{chongkrok2.text()}"'))
natang.show()
qAp.exec_()
การทำคำสั่งเมื่อพิมพ์ {.textEdited}
หากต้องการให้ฟังก์ชันทำงานทุกครั้งเมื่อมีการพิมพ์ข้อความลงในกล่องก็อาจใช้ .textEdited
โดยฟังก์ชันที่กำหนดให้ .textEdited นี้อาจใส่พารามิเตอร์ลงไป และพารามิเตอร์นั้นก็จะเก็บค่าข้อความหลังเปลี่ยนแปลงไว้ด้วย สามารถนำมาใช้ได้ทันที โดยไม่ต้องมาใช้ .text() เพื่อดูข้อความในนั้นอีกที
เช่นลองสร้างช่องที่ให้พิมพ์ข้อความแล้วมีข้อความเหมือนกันปรากฏขึ้นที่ด้านบน
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QLabel,QVBoxLayout
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setStyleSheet('font-family: Tahoma;')
khrong = QVBoxLayout()
natang.setLayout(khrong)
khokhwam = QLabel('') # ข้อความด้านบน
khrong.addWidget(khokhwam)
khokhwam.setFixedSize(250,25)
def lokkhokhwam(x): # ในที่นี้ x กลายเป็นข้อความใหม่ที่ถูกเขียน
khokhwam.setText(x)
chongkrok = QLineEdit('ข้อความนี้จะปรากฏด้านบนด้วย') # ช่องกรอกด้านล่าง
khrong.addWidget(chongkrok)
chongkrok.setFixedSize(250,25)
chongkrok.textEdited.connect(lokkhokhwam)
lokkhokhwam()
natang.show()
qAp.exec_()
ก็จะได้ช่องด้านล่างกับข้อความด้านบนแบบนี้ ลองพิมพ์แก้ช่องด้านล่าง ข้อความด้านบนก็จะเปลี่ยนไปตามนั้น
การทำคำสั่งเมื่อข้อความเปลี่ยน {.textChanged}
.textChanged จะคล้ายกับ .textEdited เพียงแต่จะทำงานไม่ว่าในกรณีที่ผู้ใช้แก้ข้อความในช่องเองโดยตรง หรือเมื่อข้อความถูกเปลี่ยนด้วยสาเหตุอื่น
เช่นลองสร้างกล่องข้อความที่ให้เวลาพิมพ์แก้ข้อความมีการ print ข้อความในนั้นออกมาทุกครั้ง แล้วมีปุ่มที่กดแล้วข้อความถูกลบ
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setStyleSheet('font-family: Tahoma; font-size: 17px')
chongkrok = QLineEdit('',natang) # ช่องกรอกข้อความ
chongkrok.setGeometry(10,10,150,30)
# ให้พิมพ์ข้อความออกมาเมื่อข้อความมีการเปลี่ยนแปลง
chongkrok.textChanged.connect(lambda x: print(f'ข้อความ: "{x}"',))
chongkrok.setText('พิมพ์มาเลย')
pumkot = QPushButton('ลบทิ้งซะ',natang) # ปุ่มสำหรับกดแล้วลบ
pumkot.setGeometry(30,40,110,50)
pumkot.clicked.connect(lambda: chongkrok.setText(''))
natang.show()
qAp.exec_()
แบบนี้ไม่ว่าจะพิมพ์แก้ข้อความหรือกดปุ่มเพื่อลบข้อความ ก็จะเกิดการกระทำฟังก์ชันที่กำหนดไว้
ในตัวอย่างนี้ใช้ lambda ในการสร้างฟังก์ชันแทน แต่หลักการก็เหมือนกัน คือทำเป็นฟังก์ชันที่มีพารามิเตอร์ตัวหนึ่ง ซึ่งตัวนั้นจะแทนข้อความหลังถูกเปลี่ยน
การทำคำสั่งเมื่อเลื่อนตำแหน่ง {.cursorPositionChanged .setCursorPosition
.cursorPosition}
หากต้องการให้มีการทำคำสั่งเมื่อเกิดการเลื่อนตำแหน่งที่พิมพ์อยู่ภายในช่องก็อาจทำได้โดยใช้ .cursorPositionChanged
โดยพารามิเตอร์ของฟังก์ชันนี้จะได้มา ๒ ตัว ซึ่งจะแทนด้วยค่าตำแหน่งเก่าและตำแหน่งปัจจุบัน ตามลำดับ
ตัวอย่างเช่น ลองให้ข้อความในกล่องข้อความพร้อมกับตำแหน่งที่พิมพ์อยู่ไปปรากฏในพื้นที่ด้านบน
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QLabel
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setStyleSheet('font-family: Courier New; font-size: 17px')
khokhwam = QLabel('',natang)
khokhwam.setGeometry(10,10,150,30)
def khian(a,b):
# ในที่นี้ a จะเป็นตำแหน่งเก่า b เป็นตำแหน่งปัจจุบัน
s = chongkrok.text()
khokhwam.setText(s[:b]+' | '+s[b:]) # สร้างแท่งกั้นที่ตำแหน่งปัจจุบัน
chongkrok = QLineEdit('กาเบกาเบ',natang)
chongkrok.setGeometry(10,50,150,30)
chongkrok.cursorPositionChanged.connect(khian)
chongkrok.setCursorPosition(4) # ปรับตำแหน่งที่พิมพ์อยู่
natang.show()
qAp.exec_()
ในที่นี้ตอนที่ใช้ .setCursorPosition เพื่อปรับตำแหน่งที่พิมพ์อยู่ ฟังก์ชันที่กำหนดไปใน .cursorPositionChanged ก็ทำงานเช่นกัน ข้อความจึงปรากฏตั้งแต่แรก และหลังจากนั้นถ้าพิมพ์แก้ก็จะเปลี่ยนตามกันไป
การเลื่อนตำแหน่งไปข้างหน้าและถอยหลัง {.cursorBackward .cursorForward}
เมธอด .cursorForward และ .cursorBackward ใช้เลื่อนตำแหน่งที่พิมพ์อยู่ไปข้างหน้าหรือหลัง
ค่าที่ต้องใส่คือ True False ซึ่งเป็นตัวกำหนดว่าจะลากคลุมหรือไม่ ถ้า True จะเป็นการเลื่อนไปลากคลุมไป
ตัวอย่าง ลองสร้างปุ่มสำหรับให้เกิดการเลื่อนตำแหน่งที่พิมพ์อยู่ไปซ้ายขวาเมื่อกด
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QPushButton
qAp = QApplication(sys.argv)
natang = QWidget()
chongkrok = QLineEdit('ujiujiuji',natang)
chongkrok.setCursorPosition(2)
chongkrok.setGeometry(10,10,150,30)
# เลื่อนไปทางซ้ายโดยไม่ลากคลุม
pum1 = QPushButton('«',natang)
pum1.setGeometry(10,50,50,50)
pum1.clicked.connect(lambda: chongkrok.cursorBackward(False))
# เลื่อนไปทางขวาโดยไม่ลากคลุม
pum2 = QPushButton('»',natang)
pum2.setGeometry(100,50,50,50)
pum2.clicked.connect(lambda: chongkrok.cursorForward(False))
# เลื่อนไปทางซ้ายพร้อมลากคลุม
pum3 = QPushButton('«~',natang)
pum3.setGeometry(30,90,50,50)
pum3.clicked.connect(lambda: chongkrok.cursorBackward(True))
# เลื่อนไปทางขวาพร้อมลากคลุม
pum4 = QPushButton('~»',natang)
pum4.setGeometry(80,90,50,50)
pum4.clicked.connect(lambda: chongkrok.cursorForward(True))
natang.show()
qAp.exec_()
การทำคำสั่งเมื่อลากคลุมข้อความ {.selectionChanged .selectedText
.selectionStart .setSelection}
หากต้องการจะให้ทำคำสั่งอะไรเมื่อเวลาที่มีการลากคลุมเพื่อเลือกข้อความให้กำหนดที่ .selectionChanged
ข้อมูลตำแหน่งเริ่มต้นถูกเลือกดูได้จากเมธอด .selectionStart ส่วนสายอักขระที่ถูกเลือกอยู่จะได้จากเมธอด .selectedText
การเปลี่ยนตำแหน่งส่วนที่คลุมอยู่อาจทำได้โดยเมธอด .setSelection
ตัวอย่าง ลองทำให้แสดงข้อความและตำแหน่งที่ถูกลากคลุมภายในช่องกรอกข้อความ
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QLabel
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setStyleSheet('font-family: Courier New; font-size: 18px')
khokhwam = QLabel('',natang)
khokhwam.setGeometry(10,50,150,30)
tamnaeng = QLabel('',natang)
tamnaeng.setGeometry(10,90,130,30)
def khian():
s = chongkrok.selectedText() # ตัวหนังสือที่ถูกคลุมอยู่
khokhwam.setText(s)
roem = chongkrok.selectionStart() # ตำแหน่งที่เริ่มต้นคลุม
plai = roem+len(s) # ตำแหน่งปลายสุดที่คลุม
if(roem!=-1):
tamnaeng.setText(str(roem)+'~'+str(plai))
else:
tamnaeng.setText('----')
chongkrok = QLineEdit('นากานากา',natang)
chongkrok.setSelection(2,5) # กำหนดตำแหน่งที่ลากคลุม
chongkrok.setGeometry(10,10,150,30)
chongkrok.selectionChanged.connect(khian)
khian()
natang.show()
qAp.exec_()
ก็จะได้ออกมาเป็นแบบนี้ ลองเปลี่ยนตำแหน่งที่ลากคลุมเพื่อดูความเปลี่ยนแปลงได้
ช่องใส่ข้อความทีละหลายบรรทัด {QTextEdit}
QTextEdit จะคล้ายกับ QLineEdit แค่พิมพ์ข้อความได้หลายบรรทัด ไม่ใช่แค่บรรทัดเดียว
ข้อความที่ถูกพิมพ์ภายใน QTextEdit จะเอาได้จากเมธอด .toPlainText
ตัวอย่างเช่น ลองสร้างช่องพิมพ์ข้อความที่ให้พิมพ์ข้อความตามที่เขียนในช่องเมื่อกดปุ่ม
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,QTextEdit
qAp = QApplication(sys.argv)
natang = QWidget()
natang.setStyleSheet('font-family: Tahoma; font-size: 18px')
vbl = QVBoxLayout()
natang.setLayout(vbl)
chongkhian = QTextEdit()
vbl.addWidget(chongkhian)
chongkhian.setFixedSize(300,150)
pumbanthuek = QPushButton('พิมพ์ข้อความ')
vbl.addWidget(pumbanthuek)
pumbanthuek.clicked.connect(lambda: print(chongkhian.toPlainText()))
natang.show()
qAp.exec_()
ก็จะได้กล่องข้อความแบบนี้ ลองพิมพ์อะไรลงไปแล้วกดปุ่มดูได้
ที่จริงแล้ว QTextEdit นั้นมีรายละเอียดการใช้งานมากกว่านี้มาก เช่นใช้เขียน .rtf (rich text format) ได้ แต่ในที่นี้แค่จะแนะนำการใช้งานเบื้องต้น คือใช้ในฐานะแทน QLineEdit ในกรณีที่ต้องการข้อความหลายบรรทัด
สรุปท้ายบท
ในบทนี้ได้พูดถึงการสร้างและใช้งาน QLineEdit และ QTextEdit ซึ่งเป็นกล่องที่ใช้เพื่อใส่ข้อความตัวหนังสือเพื่อนำไปใช้ทำอะไรต่างๆได้
ในบทต่อๆไปก็จะแนะนำ widget ตัวอื่นๆที่ใช้ใน GUI ต่อไปอีก
อ่านบทถัดไป >>
บทที่ ๑๐