--使用PyQt套件
#原文出處
#摘要紀錄與說明
--PyQt5 是基於Qt5而來
--請直接下載檔案執行。如果是複製網頁上的程式,貼上後請注意縮排問題。
#一步一步建立「py小計算機」
- 先把視窗架起來 pycalc01.py
- #01-建立外殼 pycalc01.py
- import sys
- from PyQt5.QtWidgets import QApplication #qt應用程式
- from PyQt5.QtWidgets import QMainWindow #qt主視窗
- from PyQt5.QtWidgets import QWidget #qt總部件
- #from PyQt5 import QtGui #為了加一個window icon,這裡可以省略。
- #這是原作者,感謝。
- __version__ = '0.1'
- __author__ = 'Leodanis Pozo Ramos'
- #定義主視窗,繼承自QMainWindow
- class PyCalcUi(QMainWindow):
- #初始化,訂定視窗外觀
- def __init__(self):
- super().__init__()
- self.setWindowTitle('py小計算機')
- self.setFixedSize(235, 235) #固定大小,免得計算機變形。
- # 建立中央部件
- self._centralWidget = QWidget(self) #先建立總部件實體(self相當於parent=self,top level的物件沒有parent了,所以不能省略。)
- self.setCentralWidget(self._centralWidget) #再設定成中央部件
- #self.setWindowIcon(QtGui.QIcon('icon.png')) #這行將icon放上去。這行可以省略。
- # 主程式
- def main():
- pycalc = QApplication(sys.argv) #建立app
- view = PyCalcUi() #建立主視窗實體
- view.show()
- sys.exit(pycalc.exec())
- if __name__ == '__main__':
- main()
- 建立外觀 pycalc02.py
- #02-建立外觀 pycalc02.py
- import sys
- from PyQt5.QtWidgets import QApplication #qt應用程式
- from PyQt5.QtWidgets import QMainWindow #qt主視窗
- from PyQt5.QtWidgets import QWidget #qt總部件
- from PyQt5 import QtGui #為了加一個window icon,這裡可以省略。
- from PyQt5.QtCore import Qt #一般性質的設定
- from PyQt5.QtWidgets import QGridLayout #格狀排列
- from PyQt5.QtWidgets import QLineEdit #單行文字
- from PyQt5.QtWidgets import QPushButton #按鈕
- from PyQt5.QtWidgets import QVBoxLayout #垂直排列
- #這是原作者,感謝。
- __version__ = '0.1'
- __author__ = 'Leodanis Pozo Ramos'
- #定義主視窗,繼承自QMainWindow
- class PyCalcUi(QMainWindow):
- #初始化,訂定視窗外觀
- def __init__(self):
- super().__init__()
- self.setWindowTitle('py小計算機')
- self.setFixedSize(235, 235) #固定大小,免得計算機變形。
- self.generalLayout = QVBoxLayout() #整體的部件是垂直排列
- # 建立中央部件
- self._centralWidget = QWidget(self) #先建立總部件實體(self相當於parent=self,top level的物件沒有parent了,所以不能省略。)
- self.setCentralWidget(self._centralWidget) #再設定成中央部件
- self._centralWidget.setLayout(self.generalLayout) #中央部件就設定為整體垂直排列
- self._createDisplay() #計算機顯示數字的部件
- self._createButtons() #計算機顯示按鈕的部件
- #self.setWindowIcon(QtGui.QIcon('icon.png')) #這行將icon放上去。這行可以省略。
- #計算機顯示數字的部件
- def _createDisplay(self):
- self.display = QLineEdit() #顯示只要一行
- self.display.setFixedHeight(35) #顯示幕的高度
- self.display.setAlignment(Qt.AlignRight) #靠右顯示
- self.display.setReadOnly(True) #設定唯讀
- self.generalLayout.addWidget(self.display) #將以上設定加入整體垂直設定中
- def _createButtons(self):
- self.buttons = {}
- buttonsLayout = QGridLayout()
- #在字典中,設定按鈕顯示的數字和在格狀排列中的座標
- buttons = {'7': (0, 0),
- '8': (0, 1),
- '9': (0, 2),
- '/': (0, 3),
- 'C': (0, 4),
- '4': (1, 0),
- '5': (1, 1),
- '6': (1, 2),
- '*': (1, 3),
- '(': (1, 4),
- '1': (2, 0),
- '2': (2, 1),
- '3': (2, 2),
- '-': (2, 3),
- ')': (2, 4),
- '0': (3, 0),
- '00': (3, 1),
- '.': (3, 2),
- '+': (3, 3),
- '=': (3, 4),
- }
- #取出字典中的文字和座標,一一擺進格狀排列中
- for btnText, pos in buttons.items():
- self.buttons[btnText] = QPushButton(btnText) #設定按鈕實體,以及顯示的文字
- self.buttons[btnText].setFixedSize(40, 40) #設定按鈕大小
- buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1]) #擺進格狀排列
- self.generalLayout.addLayout(buttonsLayout)#將以上設定加入整體垂直設定中
- # 主程式
- def main():
- pycalc = QApplication(sys.argv) #建立app
- view = PyCalcUi() #建立主視窗實體
- view.show()
- sys.exit(pycalc.exec())
- if __name__ == '__main__':
- main()
- 處理view的部份--也就是計算機面板上的訊號-- pycalc03.py
- 面板顯示
- 計算式
- 按鍵狀態
- #03-建立Controller,處理view訊號,只剩=還沒處理。 pycalc03.py
- import sys
- from PyQt5.QtWidgets import QApplication #qt應用程式
- from PyQt5.QtWidgets import QMainWindow #qt主視窗
- from PyQt5.QtWidgets import QWidget #qt總部件
- from PyQt5 import QtGui #為了加一個window icon,這裡可以省略。
- from PyQt5.QtCore import Qt #一般性質的設定
- from PyQt5.QtWidgets import QGridLayout #格狀排列
- from PyQt5.QtWidgets import QLineEdit #單行文字
- from PyQt5.QtWidgets import QPushButton #按鈕
- from PyQt5.QtWidgets import QVBoxLayout #垂直排列
- from functools import partial #有關function的工作
- #這是原作者,感謝。
- __version__ = '0.1'
- __author__ = 'Leodanis Pozo Ramos'
- #定義主視窗,繼承自QMainWindow
- class PyCalcUi(QMainWindow):
- #初始化,訂定視窗外觀
- def __init__(self):
- super().__init__()
- self.setWindowTitle('py小計算機')
- self.setFixedSize(235, 235) #固定大小,免得計算機變形。
- self.generalLayout = QVBoxLayout() #整體的部件是垂直排列
- # 建立中央部件
- self._centralWidget = QWidget(self) #先建立總部件實體(self相當於parent=self,top level的物件沒有parent了,所以不能省略。)
- self.setCentralWidget(self._centralWidget) #再設定成中央部件
- self._centralWidget.setLayout(self.generalLayout) #中央部件就設定為整體垂直排列
- self._createDisplay() #計算機顯示數字的部件
- self._createButtons() #計算機顯示按鈕的部件
- #self.setWindowIcon(QtGui.QIcon('icon.png')) #這行將icon放上去。這行可以省略。
- #計算機顯示數字的部件
- def _createDisplay(self):
- self.display = QLineEdit() #設定display,顯示只要一行
- self.display.setFixedHeight(35) #顯示幕的高度
- self.display.setAlignment(Qt.AlignRight) #靠右顯示
- self.display.setReadOnly(True) #設定唯讀
- self.generalLayout.addWidget(self.display) #將以上設定加入整體垂直設定中
- def _createButtons(self):
- self.buttons = {}
- buttonsLayout = QGridLayout()
- #在字典中,設定按鈕顯示的數字和在格狀排列中的座標
- buttons = {'7': (0, 0),
- '8': (0, 1),
- '9': (0, 2),
- '/': (0, 3),
- 'C': (0, 4),
- '4': (1, 0),
- '5': (1, 1),
- '6': (1, 2),
- '*': (1, 3),
- '(': (1, 4),
- '1': (2, 0),
- '2': (2, 1),
- '3': (2, 2),
- '-': (2, 3),
- ')': (2, 4),
- '0': (3, 0),
- '00': (3, 1),
- '.': (3, 2),
- '+': (3, 3),
- '=': (3, 4),
- }
- #取出字典中的文字和座標,一一擺進格狀排列中
- for btnText, pos in buttons.items():
- self.buttons[btnText] = QPushButton(btnText) #設定按鈕實體,以及顯示的文字
- self.buttons[btnText].setFixedSize(40, 40) #設定按鈕大小
- buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1]) #擺進格狀排列
- self.generalLayout.addLayout(buttonsLayout)#將以上設定加入整體垂直設定中
- #補PyCalcUi的3個methods,在PyCalcCtrl中被呼叫。
- def setDisplayText(self, text):
- """Set display's text."""
- self.display.setText(text)
- self.display.setFocus()
- def displayText(self):
- """Get display's text."""
- return self.display.text()
- def clearDisplay(self):
- """Clear the display."""
- self.setDisplayText("")
- #建立Controller
- class PyCalcCtrl:
- def __init__(self, view):
- self._view = view #初始化參數view(PyCalcUi實體)
- self._connectSignals() #呼叫方法
- #顯示幕上的文字處理
- def _buildExpression(self, sub_exp):
- expression = self._view.displayText() + sub_exp
- self._view.setDisplayText(expression)
- #連結事件和處理程式
- def _connectSignals(self):
- #掃描所有按鍵,有click,就呼叫_buildExpression。
- for btnText, btn in self._view.buttons.items():
- if btnText not in {'=', 'C'}:
- btn.clicked.connect(partial(self._buildExpression, btnText)) #有click,才會呼叫_buildExpression
- self._view.buttons['C'].clicked.connect(self._view.clearDisplay)
- # 主程式
- def main():
- pycalc = QApplication(sys.argv) #建立app
- view = PyCalcUi() #建立主視窗實體
- view.show() #顯示
- #處理按鍵和顯示幕的文字
- PyCalcCtrl(view=view)
- sys.exit(pycalc.exec())
- if __name__ == '__main__':
- main()
- 最後的計算及按錯時的處理。 pycalc04.py
- #04-完整程式。
- #處理「=」「enter」事件及計算答案。 pycalc04.py
- import sys
- from PyQt5.QtWidgets import QApplication #qt應用程式
- from PyQt5.QtWidgets import QMainWindow #qt主視窗
- from PyQt5.QtWidgets import QWidget #qt總部件
- from PyQt5 import QtGui #為了加一個window icon,這裡可以省略。
- from PyQt5.QtCore import Qt #一般性質的設定
- from PyQt5.QtWidgets import QGridLayout #格狀排列
- from PyQt5.QtWidgets import QLineEdit #單行文字
- from PyQt5.QtWidgets import QPushButton #按鈕
- from PyQt5.QtWidgets import QVBoxLayout #垂直排列
- from functools import partial #有關function的工作
- #這是原作者,感謝。
- __version__ = '0.1'
- __author__ = 'Leodanis Pozo Ramos'
- ERROR_MSG = '算式錯誤'
- #定義主視窗,繼承自QMainWindow
- class PyCalcUi(QMainWindow):
- #初始化,訂定視窗外觀
- def __init__(self):
- super().__init__()
- self.setWindowTitle('py小計算機')
- self.setFixedSize(235, 235) #固定大小,免得計算機變形。
- self.generalLayout = QVBoxLayout() #整體的部件是垂直排列
- # 建立中央部件
- self._centralWidget = QWidget(self) #先建立總部件實體(self相當於parent=self,top level的物件沒有parent了,所以不能省略。)
- self.setCentralWidget(self._centralWidget) #再設定成中央部件
- self._centralWidget.setLayout(self.generalLayout) #中央部件就設定為整體垂直排列
- self._createDisplay() #計算機顯示數字的部件
- self._createButtons() #計算機顯示按鈕的部件
- #self.setWindowIcon(QtGui.QIcon('icon.png')) #這行將icon放上去。這行可以省略。
- #計算機顯示數字的部件
- def _createDisplay(self):
- self.display = QLineEdit() #設定display,顯示只要一行
- self.display.setFixedHeight(35) #顯示幕的高度
- self.display.setAlignment(Qt.AlignRight) #靠右顯示
- self.display.setReadOnly(True) #設定唯讀
- self.generalLayout.addWidget(self.display) #將以上設定加入整體垂直設定中
- def _createButtons(self):
- self.buttons = {}
- buttonsLayout = QGridLayout()
- #在字典中,設定按鈕顯示的數字和在格狀排列中的座標
- buttons = {'7': (0, 0),
- '8': (0, 1),
- '9': (0, 2),
- '/': (0, 3),
- 'C': (0, 4),
- '4': (1, 0),
- '5': (1, 1),
- '6': (1, 2),
- '*': (1, 3),
- '(': (1, 4),
- '1': (2, 0),
- '2': (2, 1),
- '3': (2, 2),
- '-': (2, 3),
- ')': (2, 4),
- '0': (3, 0),
- '00': (3, 1),
- '.': (3, 2),
- '+': (3, 3),
- '=': (3, 4),
- }
- #取出字典中的文字和座標,一一擺進格狀排列中
- for btnText, pos in buttons.items():
- self.buttons[btnText] = QPushButton(btnText) #設定按鈕實體,以及顯示的文字
- self.buttons[btnText].setFixedSize(40, 40) #設定按鈕大小
- buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1]) #擺進格狀排列
- self.generalLayout.addLayout(buttonsLayout)#將以上設定加入整體垂直設定中
- def setDisplayText(self, text):
- """Set display's text."""
- self.display.setText(text)
- self.display.setFocus()
- def displayText(self):
- """Get display's text."""
- return self.display.text()
- def clearDisplay(self):
- """Clear the display."""
- self.setDisplayText("")
- #這是一個獨立的functions,就是model部份
- def evaluateExpression(expression):
- try:
- result = str(eval(expression, {}, {})) #eval(expression, globals=None, locals=None)全域變數和區域變數
- except Exception:
- result = ERROR_MSG
- return result
- #建立Controller
- class PyCalcCtrl:
- #Control溝通model和view:view處理所有的顯示,model處理所有的後端計算,Control就是二者的交會處。
- def __init__(self,model, view):
- self._evaluate = model #model就是evaluateExpression
- self._view = view #初始化參數view(PyCalcUi實體)
- self._connectSignals() #呼叫方法
- #計算答案,間接承接自model的function,來算答案。
- def _calculateResult(self):
- result = self._evaluate(expression=self._view.displayText())
- self._view.setDisplayText(result)
- #顯示幕上的文字處理
- def _buildExpression(self, sub_exp):
- #先檢查,如果之前是錯誤的訊息,就先清除
- if self._view.displayText() == ERROR_MSG:
- self._view.clearDisplay()
- expression = self._view.displayText() + sub_exp
- self._view.setDisplayText(expression)
- #連結事件和處理程式
- def _connectSignals(self):
- #掃描所有按鍵,有click,就呼叫_buildExpression。
- for btnText, btn in self._view.buttons.items():
- if btnText not in {'=', 'C'}:
- btn.clicked.connect(partial(self._buildExpression, btnText)) #有click,才會呼叫_buildExpression
- self._view.buttons['='].clicked.connect(self._calculateResult) #按=就算答案
- self._view.display.returnPressed.connect(self._calculateResult) #按enter就算答案
- self._view.buttons['C'].clicked.connect(self._view.clearDisplay)
- # 主程式
- def main():
- pycalc = QApplication(sys.argv) #建立app
- view = PyCalcUi() #建立主視窗實體
- view.show() #顯示
- #處理按鍵和顯示幕的文字,model算出答案
- model = evaluateExpression
- PyCalcCtrl(model=model, view=view)
- sys.exit(pycalc.exec())
- if __name__ == '__main__':
- main()
沒有留言:
張貼留言