視窗中開啟新視窗
這篇教學會介紹使用 PyQt5 建立基本的應用程式視窗,並在主視窗中點擊按鈕開啟新視窗,更會進一步實作點擊按鈕修改其他視窗文字的效果。
快速導覽:
- PyQt6 版本參考:PyQt6 教學 - 視窗中開啟新視窗
- 因為 Google Colab 不支援 PyQt5,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda )。
建立 PyQt5 視窗
參考「QPushButton 按鈕」文章範例,建立具有 QLabel 和 QPushButton 的視窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
label = QtWidgets.QLabel(Form)
label.setText('測試文字')
label.setStyleSheet('font-size:20px;')
label.setGeometry(50,30,100,30)
btn = QtWidgets.QPushButton(Form)
btn.setText('開啟新視窗')
btn.setStyleSheet('font-size:16px;')
btn.setGeometry(40,60,120,40)
Form.show()
sys.exit(app.exec_())
同樣的結果也可使用 class 的寫法:
from PyQt5 import QtWidgets
import sys
class mainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setText('測試文字')
self.label.setStyleSheet('font-size:20px;')
self.label.setGeometry(50,30,100,30)
self.btn = QtWidgets.QPushButton(self)
self.btn.setText('開啟新視窗')
self.btn.setStyleSheet('font-size:16px;')
self.btn.setGeometry(40,60,120,40)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = mainWindow()
Form.show()
sys.exit(app.exec_())
主視窗點擊按鈕,開啟新視窗
主視窗建立後,仿照主視窗建立方法建立新視窗,並將主視窗的按鈕綁定「點擊後開啟新視窗」的匿名函式,程式執行後,點擊主視窗的按鈕,就會開啟新視窗。
from PyQt5 import QtWidgets, QtGui, QtCore
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
label = QtWidgets.QLabel(Form)
label.setText('測試文字')
label.setStyleSheet('font-size:20px;')
label.setGeometry(50,30,100,30)
btn = QtWidgets.QPushButton(Form)
btn.setText('開啟新視窗')
btn.setStyleSheet('font-size:16px;')
btn.setGeometry(40,60,120,40)
btn.clicked.connect(lambda:Form2.show()) # 使用 lambda 函式,顯示新視窗
Form2 = QtWidgets.QWidget() # 建立新視窗
Form2.setWindowTitle('oxxo.studio.2')
Form2.resize(300, 200)
btn2 = QtWidgets.QPushButton(Form2)
btn2.setText('test')
btn2.setGeometry(110,60,50,30)
Form.show()
sys.exit(app.exec_())
由於多視窗可能會牽扯到互相呼叫與傳遞訊息的操作,建議使用 class 的做法。
from PyQt5 import QtWidgets
import sys
# 主視窗
class mainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setText('測試文字')
self.label.setStyleSheet('font-size:20px;')
self.label.setGeometry(50,30,100,30)
self.btn = QtWidgets.QPushButton(self)
self.btn.setText('開啟新視窗')
self.btn.setStyleSheet('font-size:16px;')
self.btn.setGeometry(40,60,120,40)
self.btn.clicked.connect(self.showNewWindow)
def showNewWindow(self):
self.nw = newWindow() # 連接新視窗
self.nw.show() # 顯示新視窗
x = self.nw.pos().x() # 取得新視窗目前 x 座標
y = self.nw.pos().y() # 取得新視窗目前 y 座標
self.nw.move(x+100, y+100) # 移動新視窗位置
# 新視窗
class newWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio.2')
self.resize(300, 200)
self.ui()
def ui(self):
self.btn = QtWidgets.QPushButton(self)
self.btn.setText('test')
self.btn.setStyleSheet('font-size:16px;')
self.btn.setGeometry(40,60,120,40)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = mainWindow()
Form.show()
sys.exit(app.exec_())
點擊按鈕修改其他視窗文字
在主視窗點擊按鈕所開啟的新視窗,是根據定義的 class 而產生的新視窗物件,因此只要將主視窗與新視窗的程式都寫在主視窗裡,就能讓彼此都能獲得點擊按鈕的訊息,執行下方的程式碼,點擊按鈕開啟新視窗後,點擊新視窗的按鈕時,主視窗的文字會發生變化,點擊主視窗的按鈕時,新視窗裡的文字也會發生變化。
from PyQt5 import QtWidgets
import sys
class mainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setText('測試文字')
self.label.setStyleSheet('font-size:20px;')
self.label.setGeometry(50,30,100,30)
self.btn = QtWidgets.QPushButton(self)
self.btn.setText('開啟新視窗')
self.btn.setStyleSheet('font-size:16px;')
self.btn.setGeometry(40,60,120,40)
self.btn.clicked.connect(self.showNewWindow) # 點擊按鈕,開啟新視窗
self.btn2 = QtWidgets.QPushButton(self)
self.btn2.setText('在新視窗裡顯示文字')
self.btn2.setStyleSheet('font-size:16px;')
self.btn2.setGeometry(40,100,200,40)
self.btn2.clicked.connect(self.changeNewWindowText) # 點擊按鈕,改變新視窗裡的文字
def showNewWindow(self):
self.nw = newWindow()
self.nw.show()
x = self.nw.pos().x()
y = self.nw.pos().y()
self.nw.move(x+50, y+50)
self.nw.btn.clicked.connect(self.changeText) # 點擊按鈕,改變主視窗裡的文字
def changeText(self):
self.label.setText('點擊按鈕囉')
def changeNewWindowText(self):
self.nw.label.setText('主視窗也點擊按鈕囉')
class newWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio.2')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setText('')
self.label.setStyleSheet('font-size:20px;')
self.label.setGeometry(50,30,200,30)
self.btn = QtWidgets.QPushButton(self)
self.btn.setText('test')
self.btn.setStyleSheet('font-size:16px;')
self.btn.setGeometry(40,60,120,40)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = mainWindow()
Form.show()
sys.exit(app.exec_())
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~