本文共 10189 字,大约阅读时间需要 33 分钟。
在上一篇教程中,我们已经分析了“货币转换程序”的具体编程思路,本教程我们来详细的探讨一下,程序的具体细节,先看源程序。
源程序:
import sysfrom PyQt5.QtWidgets import QWidget, \ QPushButton, \ QToolTip, \ QMessageBox, \ QApplication, \ QDesktopWidget, \ QMainWindow, \ QAction, \ qApp, \ QVBoxLayout, \ QHBoxLayout, \ QTextBrowser, \ QLineEdit, \ QLabel, \ QComboBox, \ QGridLayoutfrom PyQt5.QtCore import Qtfrom PyQt5.QtGui import QFont, \ QIconimport urllib.request# QMainWindow是QWidget的派生类class CMainWindow(QMainWindow): def __init__(self): super().__init__() # ToolTip设置 QToolTip.setFont(QFont('华文楷体', 10)) # statusBar设置 self.statusBar().showMessage('准备就绪') # 退出Action设置 exitAction = QAction(QIcon('1.png'), '&退出', self) exitAction.setShortcut('ctrl+Q') exitAction.setStatusTip('退出应用程序') exitAction.triggered.connect(qApp.quit) # qApp就相当于QCoreApplication.instance() # menuBar设置 menubar = self.menuBar() fileMenu = menubar.addMenu('&文件') fileMenu.addAction(exitAction) # toolBar设置 self.toolbar = self.addToolBar('文件') self.toolbar.addAction(exitAction) # 确认PushButton设置 btnExchange = QPushButton("转换") btnExchange.setToolTip("将人民币转换为对应货币!") btnExchange.setStatusTip("将人民币转换为对应货币!") btnExchange.clicked.connect(self.funExchange) btnExchange.resize(btnExchange.sizeHint()) # 退出PushButton设置 btnQuit = QPushButton('退出') btnQuit.setToolTip("点击此按钮将退出应用程序!") btnQuit.setStatusTip("点击此按钮将退出应用程序!") btnQuit.clicked.connect(qApp.quit) btnQuit.resize(btnQuit.sizeHint()) # PushButton布局 hBox1 = QHBoxLayout() hBox1.addStretch(1) hBox1.addWidget(btnExchange) hBox1.addWidget(btnQuit) # 标签 self.labDate = QLabel("日期:") # 汇率日期 self.labCurrency = QLabel("货币:") # 欲转换的货币 self.labExchange = QLabel("加元汇率:") # 加元对该货币的汇率 self.labCanadaToChina = QLabel("加元对人民币汇率:") # 加元对人民比的汇率 self.labChina = QLabel("人民币对该货币汇率:") # 人民币对该货币的汇率 self.labChinaQuality = QLabel("人民币:") # 转换金额 self.labCurrencyQuality = QLabel("转换货币:") # 转换后的货币金额 self.labData = QLabel("原始数据:") # 计算的原数数据和中间过程数据输出 # 复合框和单行文本框 self.lineDate = QLineEdit("") self.lineDate.setReadOnly(True) self.comCurrency = QComboBox() self.comCurrency.currentIndexChanged.connect(self.funReadExchange) self.lineExchange = QLineEdit("") self.lineExchange.setReadOnly(True) self.lineCanadaToChina = QLineEdit("") self.lineCanadaToChina.setReadOnly(True) self.lineChina = QLineEdit("") self.lineChina.setReadOnly(True) self.lineChinaQuality = QLineEdit("1000.00") self.lineCurrencyQuality = QLineEdit("0.00") self.lineCurrencyQuality.setReadOnly(True) # 多行文本框 self.textData = QTextBrowser() # 定义字典和列表 self.dicCurrency = {} # 存储货币信息 self.dicDescription = {} # 存储货币的描述信息 self.dicExchange = {} # 存储汇率信息 self.listRow = [] # 指定每种货币所在的列 # 读取数据 try: self.data = urllib.request.urlopen("http://www.bankofcanada.ca/valet/observations/" "FXCADAUD,FXCADBRL,FXCADCNY,FXCADEUR,FXCADHKD,FXCADINR,FXCADIDR," "FXCADJPY,FXCADMYR,FXCADMXN,FXCADNZD,FXCADNOK,FXCADPEN,FXCADRUB," "FXCADSAR,FXCADSGD,FXCADZAR,FXCADKRW,FXCADSEK,FXCADCHF,FXCADTWD," "FXCADTHB,FXCADTRY,FXCADGBP,FXCADUSD,FXCADVND/csv").read() for line in self.data.decode("utf-8", "replace").split('\n'): # 调用decode方法直接将数据转换为utf-8,否则应使用str将其转换为字符串 line = line.rstrip() # 除去字符串尾指定字符,默认为空格 # 取得货币缩写代码 if line.startswith("FXC"): temp = line.split(",") self.dicCurrency.setdefault(temp[0], temp[1].strip("\"")[4:7]) description = temp[2].strip("\"") description = description.split(" ") if description[5] == 'daily': description = "加元对 " + description[3] + " " + description[4] + " 汇率:" else: description = "加元对 " + description[3] + " " + description[4] + " " + description[5] + " 汇率:" self.dicDescription.setdefault(temp[0], description) # 取得货币所在的列号 elif line.startswith("date"): self.listRow = line.split(",") # 当读出错误时,退出 elif line.startswith("ERRORS"): break else: temp = line.split(",") if temp[0][4:5] == '-' and temp[1] != '': self.dicExchange = {} for index in range(len(temp)): self.dicExchange.setdefault(self.listRow[index], temp[index]) # 将货币加入复合框 for key in self.dicCurrency: self.comCurrency.addItem(self.dicCurrency[key]) # 输出汇率信息 for key in self.dicExchange: self.textData.append(self.dicExchange[key]) # 输出日期 self.lineDate.setText(self.dicExchange['date']) # 输出加拿大元对人民币汇率 self.lineCanadaToChina.setText(self.dicExchange['FXCADCNY']) except Exception as e: self.textData.setText("加载数据失败,请检查网络连接,错误:\n{}".format(e)) # GridLayout布局 grid = QGridLayout() grid.setSpacing(10) grid.addWidget(self.labDate, 1, 0) grid.addWidget(self.lineDate, 1, 1) grid.addWidget( self.labCurrency, 2, 0) grid.addWidget(self.comCurrency, 2, 1) grid.addWidget(self.labExchange, 3, 0) grid.addWidget(self.lineExchange, 3, 1) grid.addWidget(self.labCanadaToChina, 4, 0) grid.addWidget(self.lineCanadaToChina, 4, 1) grid.addWidget(self.labChina, 5, 0) grid.addWidget(self.lineChina, 5, 1) grid.addWidget(self.labChinaQuality, 6, 0) grid.addWidget(self.lineChinaQuality, 6, 1) grid.addWidget(self.labCurrencyQuality, 7, 0) grid.addWidget(self.lineCurrencyQuality, 7, 1) grid.addWidget(self.labData, 8, 0) grid.addWidget(self.textData, 8, 1, 15, 1) # 布局 vBox = QVBoxLayout() vBox.addLayout(grid) vBox.addLayout(hBox1) widget = QWidget() self.setCentralWidget(widget) # 建立的widget在窗体的中间位置 widget.setLayout(vBox) # Window设置 self.resize(500, 300) self.center() self.setFont(QFont('华文楷体', 10)) self.setWindowTitle('PyQt5应用教程(snmplink编著)') self.setWindowIcon(QIcon('10.png')) self.show() def center(self): # 得到主窗体的框架信息 qr = self.frameGeometry() # 得到桌面的中心 cp = QDesktopWidget().availableGeometry().center() # 框架的中心与桌面中心对齐 qr.moveCenter(cp) # 自身窗体的左上角与框架的左上角对齐 self.move(qr.topLeft()) def funExchange(self): try: self.lineCurrencyQuality.setText("{0:.2f}".format(float(self.lineChinaQuality.text()) * float(self.lineChina.text()))) except Exception as e: self.textData.setText("加载数据失败,请检查网络连接,错误:\n{}".format(e)) def funReadExchange(self): # 显示描述信息 try: for key in self.dicCurrency: if self.dicCurrency[key] == self.comCurrency.currentText(): self.labExchange.setText(self.dicDescription[key]) self.lineExchange.setText(self.dicExchange[key]) self.lineChina.setText("{0:.2f}".format(float(self.dicExchange[key]) / float(self.dicExchange['FXCADCNY']))) break self.funExchange() except Exception as e: self.textData.setText("加载数据失败,请检查网络连接,错误:\n{}".format(e)) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() def closeEvent(self, QCloseEvent): reply = QMessageBox.question(self, 'PyQt5应用教程(snmplink编著)', "是否要退出应用程序?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: QCloseEvent.accept() else: QCloseEvent.ignore()if __name__ == '__main__': app = QApplication(sys.argv) MainWindow = CMainWindow() sys.exit(app.exec_())1、第21行:输入urlib.request模块,我们使用该模块可以通过http协议,访问网上信息。
2、第52-56行:设置转换PushButton的相关内容。
3、第72-79行:设置标签信息,具体的用途可以参考一下注解信息。
4、第81-95行:设置复合框、单行文本框和多行文本框的内容,其排列顺序与标签信息相同,大家对照着看一下。
5、第98行:定义字典dicCurrency,用于存储货币的缩写信息。
6、第99行:定义字典dicDescription,用于存储货币的描述信息。
7、第100行:定义字典dicExchange,用于存储货币的汇率信息(这里是加元对该货币的汇率)。
8、第101行:定义列表listRow,用于存储查找CSV第2部分内容的列信息。
9、第105-109行:从网上读取CSV文件。
10、第110行:按行遍历读取到的数据,这里首先将数据转换为utf-8,然后通过'\n'进行行的分割。
11、第111行:除去字符串尾部的空格。
12、第113行:判断行的首字符是否为“FXC”,从而判断是否为CSV的第1部分内容。
13、第114行:将行信息按照“,”进行分割,存入列表。temp[0]从存储的是索引,temp[1]中存储的是货币缩写,temp[2]中存储的是货币描述。
14、第115行:按照索引信息将内容加入dicCurrency,至于[4:7]的理解,大家要看一下原始文件。
15、第116-122行:处理描述信息,将其加入字典dicDescription。
16、第124-125行:如果首字符是"date",则是CSV文件中,第2部分的第1行,我们将其信息存入listRow列表。
17、第130-134行:对汇率信息进行处理,如果当前行有内容,则覆盖上1行的内容,将数据加入dicExchange字典。
18、第136-137行:读取到的货币缩写字典dicCurrency内容,加入复合文本框。
19、第139-140行:在textData中输出汇率信息,这仅是为了调试,你可以输入其它调试内容。
20、第142行:输出最新的汇率日期。
21、第144行:输出加元对人民币汇率。
22、第149-166行:通过GridLayout进行布局。
23、第195-198行:进行货币计算。
23、第200-221行:处理复合框索引变化,如果变换则更改其它行的相应信息,并调用funExchange进行货币计算。
其它的信息,如果有看不明白的,翻看先前的教程即可。
原创性文章,转载请注明出处 。
CSDN: