φυβλαςのβλογ
phyblas的博客



pyqt เบื้องต้น บทที่ ๙: การสร้างและใช้งานช่องกรอกข้อความ
เขียนเมื่อ 2021/08/11 11:00
แก้ไขล่าสุด 2021/09/28 16:42

ต่อจาก บทที่ ๘

หลังจากที่ในบทก่อนหน้านี้ได้แนะนำ 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 ต่อไปอีก



อ่านบทถัดไป >> บทที่ ๑๐





-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> pyqt

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ