φυβλαςのβλογ
บล็อกของ 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
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



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

  ค้นหาบทความ

  บทความแนะนำ

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

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文