跟第一版的区别:
1. 主窗口从QMainWindow
继承过来,而不是从QWidget
. 所有的控件加载在QWidget
上,然后QWidget
加载到QMainWindow
上
-
模块化一些产生控件的code. 比如
create_menu
,create_status_bar
,create_main_frame
,create_action
等等 -
可以再添加
QHBoxLayout
或者QVBoxLayout
来安排更多的widget
'''
20160531 in v4: try to re-arrange the widgets with QMainWindow
20160516: in v3, try to read in the csv file through menu rather than do this in the code, but v3 does not work
20160516: in v2, try to use dropdown menu to select data
20160515 in this v1, we can input the rating and year_quarter in the first and second cell of the table and then plot the result.
'''
from PyQt4 import QtGui, QtCore
import os, sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import style
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
style.use('ggplot')
class PrettyWidget(QtGui.QMainWindow):
def __init__(self, parent = None):
super(PrettyWidget, self).__init__(parent)
self.setWindowTitle('Revision on Plots, Tables and File Browser')
self.create_menu()
self.create_main_frame()
self.create_status_bar()
def create_main_frame(self):
self.main_frame = QtGui.QWidget()
#Grid Layout
grid = QtGui.QGridLayout()
self.setLayout(grid)
#Canvas and Toolbar
self.figure = plt.figure(figsize=(15,5))
self.canvas = FigureCanvas(self.figure)
grid.addWidget(self.canvas, 2,0,1,2)
#Import CSV Button
btn1 = QtGui.QPushButton('Import CSV', self)
btn1.resize(btn1.sizeHint())
btn1.clicked.connect(self.getCSV)
grid.addWidget(btn1, 1, 0)
#DropDown mean / comboBox
self.df = pd.DataFrame()
self.rating_list = []
self.yq_list = []
self.comboBox = QtGui.QComboBox(self)
self.comboBox.addItems(self.rating_list)
grid.addWidget(self.comboBox, 0, 0)
self.comboBox2 = QtGui.QComboBox(self)
self.comboBox2.addItems(self.yq_list)
grid.addWidget(self.comboBox2, 0, 1)
#Plot Button
btn2 = QtGui.QPushButton('Plot', self)
btn2.resize(btn2.sizeHint())
btn2.clicked.connect(self.plot)
grid.addWidget(btn2, 1, 1)
self.main_frame.setLayout(grid)
self.setCentralWidget(self.main_frame)
self.show()
def create_status_bar(self):
self.status_text = QtGui.QLabel("Please load the csv file: ca_cni_camacro_20160531.csv!!")
self.statusBar().addWidget(self.status_text, 1)
def create_menu(self):
self.file_menu = self.menuBar().addMenu("&File")
open_action = self.create_action("&Open File", slot = lambda: self.on_about("Open CSV", "Please click Import CSV button"))
quit_action = self.create_action("&Quit", slot = self.close, shortcut = "Ctrl+Q", tip = "Close the App")
self.add_actions(self.file_menu, (open_action, None, quit_action))
self.help_menu = self.menuBar().addMenu("&Help")
about_action = self.create_action("&About", shortcut = 'F1', slot = lambda: self.on_about("About the App", "Demo of IFRS9 PD Plot"))
self.add_actions(self.help_menu, (about_action, ))
def on_about(self, msg_title, msg):
QtGui.QMessageBox.about(self, msg_title, msg.strip())
def add_actions(self, target, actions):
for action in actions:
if action is None:
target.addSeparator()
else:
target.addAction(action)
def create_action(self, text, slot = None, shortcut = None, icon = None, tip = None, checkable = False, signal = "triggered()"):
action = QtGui.QAction(text, self)
if icon is not None:
action.setIcon(text, self)
if shortcut is not None:
action.setShortcut(shortcut)
if tip is not None:
action.setToolTip(tip)
action.setStatusTip(tip)
if slot is not None:
self.connect(action, QtCore.SIGNAL(signal), slot)
if checkable is not None:
action.setCheckable(True)
return action
def getCSV(self):
filePath = QtGui.QFileDialog.getOpenFileName(self,
'Single File',
'~/Desktop/PyRevolution/PyQt4',
'*.csv')
print filePath
self.df = pd.read_csv(str(filePath))
self.rating_list = self.df.rating.unique().tolist()
self.yq_list = [str(x) for x in self.df.yq.unique().tolist()]
self.comboBox.addItems(self.rating_list)
self.comboBox2.addItems(self.yq_list)
print self.rating_list
self.status_text.setText("Loaded " + str(filePath))
def plot(self):
y = []
for n in range(3):
try:
y.append(self.table.item(0, n).text())
except:
y.append(np.nan)
p1 = self.df.ix[(self.df.rating == str(self.comboBox.currentText())) & (self.df.yq == int(str(self.comboBox2.currentText()))), :]
print p1
plt.cla()
ax = self.figure.add_subplot(111)
ax.plot(p1.ix[:, 0], 'g', label = "Pred on data with Model")
ax.plot(p1.ix[:, 1], label = "adj Pred to non-decreasing")
ax.plot(p1.ix[:, 3], label = "Fitting value in Model")
ax.plot(p1.ix[:, 2], 'r', label = "Actual PD")
ax.plot(p1.ix[:, 4], 'y', label = "Long Run Avg")
ax.set_title('Canada C&I PD Plot')
ax.legend(loc = 0)
self.canvas.draw()
def center(self):
qr = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
app = QtGui.QApplication(sys.argv)
w = PrettyWidget()
app.exec_()
if __name__ == '__main__':
main()
Figure 1. ready to read in csv