先上最初的源码:
===================================================================
import sys
import urllib2
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
date = self.getdata()
rates = sorted(self.rates.keys())
dateLabel = QLabel(date)
self.fromComboBox = QComboBox()
self.fromComboBox.addItems(rates)
self.fromSpinBox = QDoubleSpinBox()
self.fromSpinBox.setRange(0.01, 10000000.00)
self.fromSpinBox.setValue(1.00)
self.toComboBox = QComboBox()
self.toComboBox.addItems(rates)
self.toLabel = QLabel("1.00")
grid = QGridLayout()
grid.addWidget(dateLabel, 0, 0)
grid.addWidget(self.fromComboBox, 1, 0)
grid.addWidget(self.fromSpinBox, 1, 1)
grid.addWidget(self.toComboBox, 2, 0)
grid.addWidget(self.toLabel, 2, 1)
self.setLayout(grid)
self.connect(self.fromComboBox,
SIGNAL("currentIndexChanged(int)"), self.updateUi)
self.connect(self.toComboBox,
SIGNAL("currentIndexChanged(int)"), self.updateUi)
self.connect(self.fromSpinBox,
SIGNAL("valueChanged(double)"), self.updateUi)
self.setWindowTitle("Currency")
def updateUi(self):
to = unicode(self.toComboBox.currentText())
from_ = unicode(self.fromComboBox.currentText())
amount = (self.rates[from_] / self.rates[to]) * \
self.fromSpinBox.value()
self.toLabel.setText("%0.2f" % amount)
def getdata(self): # Idea taken from the Python Cookbook
self.rates = {}
try:
date = "Unknown"
fh = urllib2.urlopen("http://www.bankofcanada.ca"
"/en/markets/csv/exchange_eng.csv")
for line in fh:
line = line.rstrip()
if not line or line.startswith(("#", "Closing ")):
continue
fields = line.split(",")
if line.startswith("Date "):
date = fields[-1]
else:
try:
value = float(fields[-1])
self.rates[unicode(fields[0])] = value
except ValueError:
pass
return "Exchange Rates Date: " + date
except Exception, e:
return "Failed to download:\n%s" % e
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
===============================================================
在最初的源码中,界面用是PyQt4,抓取数据用的是urllib2。在PyQT5中,connect方法已经改变了。在Python3.x中,urllib2已变成了urllib,使用方法也大不相同。首先,把原来的模块引入修改成:
import sys
import re #引入了正则表达式模块
import urllib.request #把urllib2改成urllib
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import * #QApplication 已经定位到PyQt5.QtWidgets这个模块
引入正则表达式模块,是因为要对原来的代码中的getdata方法进行修改。另外,在这几行中:
self.connect(self.fromComboBox,
SIGNAL("currentIndexChanged(int)"), self.updateUi)
self.connect(self.toComboBox,
SIGNAL("currentIndexChanged(int)"), self.updateUi)
self.connect(self.fromSpinBox,
SIGNAL("valueChanged(double)"), self.updateUi)
我前面说了,connect方法已经变了。要变成:
self.fromComboBox.currentIndexChanged.connect(self.updateUi)
self.toComboBox.currentIndexChanged.connect(self.updateUi)
self.fromSpinBox.valueChanged.connect(self.updateUi)
另外,还要把带有unicode的函数去掉,因为python3.x默认就是unicode编码。最后,修改后的完整代码就是这样:
=======================================================================================
import sys
import re #引入了正则表达式模块
import urllib.request#把urllib2改成urllib
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import * #QApplication 已经定位到PyQt5.QtWidgets这个模块
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
date = self.getdata()
rates = sorted(self.rates.keys())
dateLabel = QLabel(date)
self.fromComboBox = QComboBox()
self.fromComboBox.addItems(rates)
self.fromSpinBox = QDoubleSpinBox()
self.fromSpinBox.setRange(0.01, 10000000.00)
self.fromSpinBox.setValue(1.00)
self.toComboBox = QComboBox()
self.toComboBox.addItems(rates)
self.toLabel = QLabel("1.00")
grid = QGridLayout()
grid.addWidget(dateLabel, 0, 0)
grid.addWidget(self.fromComboBox, 1, 0)
grid.addWidget(self.fromSpinBox, 1, 1)
grid.addWidget(self.toComboBox, 2, 0)
grid.addWidget(self.toLabel, 2, 1)
self.setLayout(grid)
self.fromComboBox.currentIndexChanged.connect(self.updateUi)
self.toComboBox.currentIndexChanged.connect(self.updateUi)
self.fromSpinBox.valueChanged.connect(self.updateUi)
self.setWindowTitle("Currency")
def updateUi(self):
to = self.toComboBox.currentText()#把unicode去掉
from_ = self.fromComboBox.currentText()#把unicode去掉
amount = (self.rates[from_] / self.rates[to]) * \
self.fromSpinBox.value()
self.toLabel.setText("%0.2f" % amount)
def getdata(self):
self.rates = {}
try:
date = "Unknown"
fh = urllib.request.urlopen("http://www.bankofcanada.ca/en/markets/csv/exchange_eng.csv")
csv_data = str(fh.read())
pattern = re.compile('Date[\s\S]*')#以"Date"关键词,匹配"Date"之后的数据
csv_data = pattern.search(csv_data)
csv_data = csv_data.group(0)
csv_data = csv_data.split("\\n")#以换行符为标志生成数据列表
for line in csv_data:
if "Date" in line:#如果数据行包含“Date”项,就将最后的日期作为date的值
date = line.split(',')[-1]#以逗号进行分割,获得最后的日期
else:
temp = line.split(',')#以逗号进行分割,获得每一行的数据,生成一个临时列表
if temp[0] is not "\'":
key = temp[0]#将临时列表的第1项作为汇率名
value = temp[-1]#将这个列表的最后一项作为汇率值
self.rates[key] = float(value)#生成汇率字典
return "Exchange Rates Date: " + date
except Exception as e: #在python3.x中,要将逗号改成as
return "Failed to download:\n%s" % e
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
==================================================================================
上述代码中,getdata方法改动最大,但也比较容易理解。关键是,能配合urllib对数据进行获取。