大盘行情界面
实现方法:http://qt.gtimg.cn网站和tushare作为数据来源,pyqt5和echart作为软件界面展示
数据线程
#大盘页面数据类》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
class DaPanDataClass(QThread):
sig = pyqtSignal(tuple)
sig_tag = pyqtSignal(list)
isRun = True
def __init__(self):
super(DaPanDataClass, self).__init__()
def get_san_data(self,url_code):
urlt = "http://qt.gtimg.cn/q=s_{}".format(','.join(url_code))
response = requests.get(urlt)
if response.text != "":
# print(response.text)
ss = response.text.split(';')
for i in ss:
if i.split("=")[-1] != "":
strings = i.split("=")[-1][1:-1]
tem_list = strings.split('~')
# print(tem_list)
if len(tem_list) > 1:
res = (tem_list[1],float(tem_list[3]),float(tem_list[4]),tem_list[5],tem_list[2])
self.sig.emit(res)
def get_tag_data(self,url_code):
data = []
url = "http://qt.gtimg.cn/q=s_{}".format(','.join(url_code))
response = requests.get(url)
if response.text != "":
# print(response.text)
ss = response.text.split(';')
for i in ss:
if i.split("=")[-1] != "":
strings = i.split("=")[-1][1:-1]
tem_list = strings.split('~')
# print(tem_list)
if len(tem_list) > 1:
res = (tem_list[1],tem_list[2],float(tem_list[5]),float(tem_list[3]),float(tem_list[4]))
data.append(res)
self.sig_tag.emit(data)
def run(self):
while True:
if self.isRun == False:
break
self.get_san_data(['sh000001','s_sz399001','s_sz399006','s_sh000002'])
self.get_tag_data(['sz399300','s_sz399333','s_sz399335','s_sz399337','s_sz399339','s_sz399352','s_sz399361','s_sz399363',
's_sz399367','s_sz399368','s_sz399386','s_sz399387','s_sz399388','s_sz399389','s_sz399394','s_sz399395',
's_sz399431', 's_sz399432', 's_sz399433', 's_sz399434', 's_sz399435', 's_sz399436','s_sz399437','s_sz399438',
's_sz399439', 's_sz399440', 's_sz399441','s_sz399396','s_sz399397','s_sz399414','s_sz399300','s_sz399330',
's_sh000002','s_sh000066','s_sh000004','s_sh000005','s_sh000006','s_sh000007','s_sh000008','s_sh000009',
's_sh000010','s_sh000011','s_sh000012','s_sh000016','s_sh000017','s_sh000018','s_sh000025','s_sh000027',
's_sh000032','s_sh000033','s_sh000034','s_sh000036','s_sh000037','s_sh000039','s_sh000001','s_sz399001',
's_sz399006','s_sh000002'])
time.sleep(1)
#K线数据类》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
class KData(QThread):
def __init__(self):
super(KData,self).__init__()
self.code = None
self.name = None
def getcode(self):
with open('temcode','r',encoding='utf8')as f:
tem = f.read().strip().split(',')
self.code = tem[1]
self.name = tem[0]
def get_data(self,ky='D'):
self.getcode()
df = ts.get_hist_data(self.code,ktype=ky)
if df is not None:
a = [x for x in df.index]
df.insert(0, 'date', a)
df = df.reset_index(level=None, drop=True, col_level=0, col_fill='')
ac = [df['date'].values, df['open'].values, df['close'].values, df['low'].values, df['high'].values,
df['volume'].values]
data = list(map(list, zip(*ac)))
data.reverse()
return data
else:
print('数据刷新失败,请检查网络')
return
model
headerData控制表头,data函数实现数据设置。
Qt.TextColorRole实现控制数据内容的字体颜色,Qt.TextAlignmentRole实现数据字体的显示格式update_model实现数据刷新,self.layoutAboutToBeChanged.emit() self.dataChanged.emit(self.createIndex(0, 0), self.createIndex(self.rowCount(0), self.columnCount(0)))self.layoutChanged.emit()实现数据刷新不影响选中行
from PyQt5.QtCore import QAbstractTableModel,Qt,QVariant,QTimer
from PyQt5.QtGui import QFont,QColor,QBrush
class ModelDapan(QAbstractTableModel):
def __init__(self):
super(ModelDapan, self).__init__()
self.data_list = []
def columnCount(self, parent) -> int:
return 5
def rowCount(self, parent) -> int:
return len(self.data_list)
def headerData(self, section, orientation, role):
if role==Qt.DisplayRole and orientation==Qt.Horizontal:
headers = ["名称","代码","涨跌%","当前价格","涨跌"]
for n in range(5):
if section==n:
return headers[n]
else:
return QVariant()
def data(self, index, role):
col = index.column()
row = index.row()
if not index.isValid():
return QVariant()
if role==Qt.TextAlignmentRole:
return Qt.AlignCenter
if role==Qt.TextColorRole:
if col==2:
if self.data_list[row][2]<0:
return QBrush(QColor(Qt.green))
if self.data_list[row][2]>0:
return QBrush(QColor(Qt.red))
if col==4:
if self.data_list[row][4]<0:
return QBrush(QColor(Qt.green))
if self.data_list[row][4]>0:
return QBrush(QColor(Qt.red))
if role==Qt.DisplayRole:
for i in range(5):
if col==i:
return self.data_list[row][i]
else:
return QVariant()
def update_model(self,data):
self.data_list = data
self.layoutAboutToBeChanged.emit()
self.dataChanged.emit(self.createIndex(0, 0), self.createIndex(self.rowCount(0), self.columnCount(0)))
self.layoutChanged.emit()
view
通过QSortFilterProxyModel实现表格排序,dapan数据线程类绑定model的update_model函数,实现tableview的数据实时刷新
#tableview显示功能实现+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def model_fun(self):
self.model = ModelDapan()
self.proxymodel = QSortFilterProxyModel(self)
self.proxymodel.setSourceModel(self.model)
self.tableView.setModel(self.proxymodel) #表格按列排序
self.tableView.setSortingEnabled(True) #开启表头按列排序
self.tableView.verticalHeader().setHidden(True) #隐藏序号列
self.tableView.setSelectionMode(QAbstractItemView.SingleSelection) #设置选中行
self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tableView.clicked.connect(self.selectRow) #绑定单击选中行响应函数
self.dapadataThread.sig_tag.connect(self.model.update_model) #数据绑定model实时刷新数据
大盘widget类
from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QPushButton,QAbstractItemView
from PyQt5.QtCore import Qt,QSortFilterProxyModel,QEvent,QUrl,pyqtSignal
from PyQt5.QtWebEngineWidgets import QWebEngineView,QWebEngineSettings
from gui.dapan_gui import Ui_Form
from data.data_class import DaPanDataClass,KData
from model.model_dapan import ModelDapan
from echartsdir.Kline_widget import MainWindow
class DaPanWidget(QWidget,Ui_Form):
sig_code = pyqtSignal(str)
def __init__(self):
super(DaPanWidget,self).__init__()
self.setupUi(self)
self.dapadataThread = DaPanDataClass()
self.dapadataThread.start()
self.dapadataThread.sig.connect(self.push_update)
self.model_fun()
self.widget = MainWindow()
self.gridLayout_3.addWidget(self.widget)
self.pushButton_zh.clicked.connect(self.solt_zh)
self.pushButton_sz.clicked.connect(self.solt_sz)
self.pushButton_cy.clicked.connect(self.solt_cy)
#上证指数按钮+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def solt_zh(self):
on = self.pushButton_zh.text().split('\n')
s = on[0]+','+'sh'+on[1]
with open('temcode','w',encoding='utf8')as f:
f.write(s)
self.widget.update_data_day()
#深圳指数按钮+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def solt_sz(self):
on = self.pushButton_sz.text().split('\n')
s = on[0] + ',' + 'sz'+on[1]
with open('temcode', 'w', encoding='utf8')as f:
f.write(s)
self.widget.update_data_day()
#创业板指数按钮+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def solt_cy(self):
on = self.pushButton_cy.text().split('\n')
s = on[0] + ',' + on[1]
with open('temcode', 'w', encoding='utf8')as f:
f.write(s)
self.widget.update_data_day()
#三个指标数据实时刷新槽函数+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def push_update(self,one):
if one[0]=='上证指数':
self.pushButton_zh.setText("{}\n{}\n{}\n{} {}%".format(one[0],one[4],one[1],one[2],one[3]))
self.btn_three(self.pushButton_zh,one)
if one[0]=='深证成指':
self.pushButton_sz.setText("{}\n{}\n{}\n{} {}%".format(one[0],one[4],one[1],one[2],one[3]))
self.btn_three(self.pushButton_sz, one)
if one[0]=='创业板指':
self.pushButton_cy.setText("{}\n{}\n{}\n{} {}%".format(one[0],one[4],one[1],one[2],one[3]))
self.btn_three(self.pushButton_cy, one)
#三个大按钮判断大小改变颜色+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def btn_three(self,btn,one):
if one[2]<0:
btn.setStyleSheet("QPushButton { background-color: rgb(69, 83, 100);border-radius: 3px; color: rgb(1, 247, 2);}"
"QPushButton:hover { background-color: rgb(96, 121, 139)}")
# "QPushButton:checked { background-color: rgb(208, 227, 253);}")
if one[2]>0:
btn.setStyleSheet("QPushButton { background-color: rgb(69, 83, 100);border-radius: 3px; color: red;}"
"QPushButton:hover { background-color: rgb(96, 121, 139)}")
# "QPushButton:checked { background-color: rgb(208, 227, 253);}")
#tableview显示功能实现+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def model_fun(self):
self.model = ModelDapan()
self.proxymodel = QSortFilterProxyModel(self)
self.proxymodel.setSourceModel(self.model)
self.tableView.setModel(self.proxymodel) #表格按列排序
self.tableView.setSortingEnabled(True) #开启表头按列排序
self.tableView.verticalHeader().setHidden(True) #隐藏序号列
self.tableView.setSelectionMode(QAbstractItemView.SingleSelection) #设置选中行
self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tableView.clicked.connect(self.selectRow) #绑定单击选中行响应函数
self.dapadataThread.sig_tag.connect(self.model.update_model) #数据绑定model实时刷新数据
#单击响应行函数++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def selectRow(self, index):
#输出第一个字段
model = self.tableView.model()
j = model.index(index.row(),0)
i = model.index(index.row(),1)
code = model.data(i)
if code.startswith('6'):
code = 'sh'+code
else:
code = 'sz'+code
s = model.data(j) +','+ code
print(s)
with open('temcode','w',encoding='utf8')as f:
f.write(s)
#5分钟按钮响应
if self.widget.pushButton_2.isChecked():
self.widget.update_data_5_min()
#15分钟按钮响应
if self.widget.pushButton_3.isChecked():
self.widget.update_data_15_min()
#60分钟按钮响应
if self.widget.pushButton_4.isChecked():
self.widget.update_data_60_min()
#日线按钮响应
if self.widget.pushButton_5.isChecked():
self.widget.update_data_day()
#周线按钮响应
if self.widget.pushButton_6.isChecked():
self.widget.update_data_wend()
#月线按钮响应
if self.widget.pushButton_7.isChecked():
self.widget.update_data_mon()
自选股界面
实现输入联想提示
def line_edit_show(self):
with open('codelist','r',encoding='utf-8')as f:
temlist = f.readlines()
temlist = QCompleter(temlist)
temlist.setCaseSensitivity(Qt.CaseInsensitive)
temlist.setFilterMode(Qt.MatchContains)
self.lineEdit.setCompleter((temlist))
实现加自选股
def solt_add_stock(self):
input = self.lineEdit.text()
if input != "":
temdata = input.split('\t')
if temdata[0].startswith('6'):
code = 'sh' + temdata[0]
else:
code = 'sz' + temdata[0]
name = temdata[1]
mydb = MyDataDB()
mydb.input_data(code,name)
mydb.close()
实现减自选股
def solt_sub_stock(self):
self.model.removeRow(self.select_row)
with open('temcode', 'r', encoding='utf8')as f:
tem = f.readline()
if tem != "":
code = tem.split(',')[1]
if code.startswith("6"):
code='sh'+code
else:
code='sz'+code
mydb = MyDataDB()
mydb.delete_data(code)
mydb.close()