看完這篇文章你會得到的成果圖
前言
我們接下來的討論,會基於讀者已經先讀過我 day5 文章 的架構下去進行程式設計
如果還不清楚我程式設計的邏輯 (UI.py、controller.py、start.py 分別在幹麻)
建議先閱讀 day5 文章後再來閱讀此文。
【PyQt5】Day 5 – 開始來設計我們的 controller.py,改以「程式角度」來說明如何建立 PyQt 的系統
此篇文章的範例程式碼 github
https://github.com/howarder3/ironman2021_PyQt5_photoshop/tree/main/day09_input_text_2
介紹 QLineEdit, QTextEdit, QPlainTextEdit
我們在 day8 中已經有介紹過 QLineEdit 的使用方法,
與 QLineEdit 類似的還有 QTextEdit, QPlainTextEdit,
今日我們一併介紹。
- QLineEdit:特色是單行的文字輸入,通常會使用於帳號、密碼或 email 等等,大概只需要一行文字輸入的地方。
- QTextEdit:特色是多行的文字輸入。
- QPlainTextEdit:特色也是多行的文字輸入,基本上與 QTextEdit 功能相同。
我們一般使用上會使用 QTextEdit 作為文字顯示
使用 QPlainTextEdit 來進行文字 input 處理
UI 設計部份 (UI.py)
Qt designer 部份
一樣先打開我們的 Qt designer,
這次我們建立三行input、按鈕、與顯示文字,
分別對應各自的結果。
我們在 Input widgets 中找到 LineEdit, TextEdit, PlainTextEdit,
拖曳至視窗自己喜歡的地方,
我們今天想實作一個小功能,是昨天 day 8 的延伸練習,
讓我們「輸入」的文字,可以藉由「點擊按鈕」,「顯示」在畫面的某處。
因此我們今天總共需要3*3個物件
- QLineEdit, QTextEdit, QPlainTextEdit:作為讓我們輸入文字的地方
- QPushButton*3:作為按鈕,可以點擊執行任務
- Qlabel*3:作為顯示結果用
讀者們可以開始自行設計自己的介面囉,以下為我的示範:
這邊我極度建議要修改物件的名稱 (上圖右上角紅框處) ,等等我們撰寫 controller.py 功能的時候,才不會要在那邊認說 label_1、label_2、label_3 誰是誰。
另外我們這邊直接在介面上修改了預設的文字,(點兩下即可直接編輯),
其實這與前幾天我們在 controller.py 的作法也是相同的,只是這次我們把 setText 的功能搬至 UI.py 中,讓 UI.py 直接完成介面 initialize 的工作。
轉換成 UI.py
一樣的編譯指令,我們加上 -x (也可不加),
我們就可以先檢視看看轉換後的視窗是不是跟我們想像的一樣。
轉換 day9.ui -> UI.py
pyuic5 -x day9.ui -o UI.py
執行看看 UI.py 畫面是否如同我們想像
一樣,這程式只有介面 (視覺上的呈現),沒有任何互動功能
- 看看我們製作出來的介面
python UI.py
我們稍微閱讀一下轉換出來的 UI.py 的程式碼,
我們就會發現與前幾天不同的地方,
也就是我們在 UI.py 完成的初始化部份。
物件名稱更改部份
稍微注意一下就會發現,
我們剛剛在 Qtdesigner 修改的內容,直接反應在 class 的成員名稱上,
另外 setObjectName 也同步被改動了,總共有這兩個變化。
初始化內容部份
這部份我們在 UI.py 中發現了多了 retranslateUi() 這個 function,
裡面有一連串的名稱變換,完成我們剛剛設定的文字初始化。
controller 設計部份 (controller.py)
接下來,我們必須先研究一下我們剛剛的程式,
把我們剛剛程式中的「物件名稱」找出來。
從 UI.py 中找出物件名稱
畢竟我們剛剛已經先改過了變數名稱,這邊就方便了!
我們這邊先把變數名稱列出來,方便我們之後設定。
- QLineEdit 部份
- 輸入:self.box_line
- 按鈕:self.button_line
- 顯示:self.label_line (上面的圖片我是我修改前的結果,修改後應該會是這個名稱)
- QTextEdit 部份
- 輸入:self.box_text
- 按鈕:self.button_text
- 顯示:self.label_text
- QPlainTextEdit 部份
- 輸入:self.box_plain
- 按鈕:self.button_plain
- 顯示:self.label_plain
(務必記得名稱,不然等等不知道要改誰XD)
取得名稱後,去修改 controller.py
還記得我們在 day5 中的模板嗎?這邊我們直接複製過來使用並修改。
from PyQt5 import QtWidgets, QtGui, QtCore
from UI import Ui_MainWindow
class MainWindow_controller(QtWidgets.QMainWindow):
def __init__(self):
super().__init__() # in python3, super(Class, self).xxx = super().xxx
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.setup_control()
def setup_control(self):
# TODO
self.ui.button_line.clicked.connect(self.buttonClicked_line)
self.ui.button_text.clicked.connect(self.buttonClicked_text)
self.ui.button_plain.clicked.connect(self.buttonClicked_plain)
def buttonClicked_line(self):
msg = self.ui.box_line.text()
self.ui.label_line.setText(msg)
def buttonClicked_text(self):
msg = self.ui.box_text.toPlainText()
self.ui.label_text.setText(msg)
def buttonClicked_plain(self):
msg = self.ui.box_plain.toPlainText()
self.ui.label_plain.setText(msg)
我們修改了 setup_control(),使按鈕能夠連接對應的 function,
並新增了buttonClicked_line(), buttonClicked_text(), buttonClicked_plain() 的部份,完成我們按鈕的功能。
【注意】 QLineEdit, QTextEdit, QPlainTextEdit 使用函數的不同
如果想要讀取 QLineEdit 內的文字,
我們使用的是 「.text()」 的方式呼叫。
而如果是想要讀取 QTextEdit, QPlainTextEdit 內的文字,
我們使用的是 「.toPlainText()」 的方式呼叫。
所以如果出現 「AttributeError: ‘QTextEdit’ object has no attribute ‘text’」
就是上述的這個問題囉!
於是我們就完成我們今天的功能囉!
執行結果
照我們 day5 的程式架構,我們執行
python start.py