使用PyQt绘制精美的股票行情分时线图

本文介绍如何利用Python的PyQt库,结合股票数据CSV文件(600519.csv),绘制出详细且美观的股票分时行情图表,帮助投资者直观了解股票走势。
摘要由CSDN通过智能技术生成

分时图

# -*- coding: utf-8 -*-
# !/usr/bin/python

import sys
import tushare as ts
import pandas as pd
import os
from PyQt4 import QtGui, QtCore, Qt

reload(sys)
sys.setdefaultencoding('utf8')

class report_painter:
    '''绘制行情类'''

    def __init__(self, parent):

        # 初始化
        self.parent = parent
        self.paint = QtGui.QPainter()
        self.paint.begin(self.parent)
        self.total_amount_data = 4890.00

        # 设置抗锯齿
        # self.paint.setRenderHint(QtGui.QPainter.Antialiasing)
        # 度量尺对象
        self.metrics = self.paint.fontMetrics()

        # 设置字体库
        self.fonts = dict()
        self.fonts['default'] = QtGui.QFont('', 8, QtGui.QFont.Light)
        self.fonts['yahei_14'] = QtGui.QFont('', 8, QtGui.QFont.Bold)
        self.fonts['yahei_14'] = QtGui.QFont('', 8, QtGui.QFont.Light)
        self.setFont('default')

        # 设置笔刷样式库
        self.pens = dict()

        # 红色 1px粗  1px点 2px距 线条
        self.pens['red_1px_dashline'] = QtGui.QPen(QtCore.Qt.red, 1, QtCore.Qt.DashLine)
        self.pens['red_1px_dashline'].setDashPattern([1, 2])

        # 红色 1px粗 实线条
        self.pens['red'] = QtGui.QPen(QtCore.Qt.red, 1, QtCore.Qt.SolidLine)
        # 红色 3px粗 实线条
        self.pens['red_2px'] = QtGui.QPen(QtCore.Qt.red, 2, QtCore.Qt.SolidLine)
        # 红色 2px粗 实线条
        self.pens['red_3px'] = QtGui.QPen(QtCore.Qt.red, 3, QtCore.Qt.SolidLine)
        # 黄色 1px粗 实线条
        self.pens['yellow'] = QtGui.QPen(QtCore.Qt.yellow, 1, QtCore.Qt.SolidLine)
        # 白色 1px粗 实线条
        self.pens['white'] = QtGui.QPen(QtCore.Qt.white, 1, QtCore.Qt.SolidLine)
        # 灰色 1px粗 实线条
        self.pens['gray'] = QtGui.QPen(QtCore.Qt.gray, 1, QtCore.Qt.SolidLine)
        # 绿色 1px粗 实线条
        self.pens['green'] = QtGui.QPen(QtCore.Qt.cyan, 1, QtCore.Qt.SolidLine)
        # 绿色 3px粗 实线条
        self.pens['green_2px'] = QtGui.QPen(QtCore.Qt.green, 2, QtCore.Qt.SolidLine)
        # 亮蓝 1px粗  1px点 2px距 线条
        self.pens['cyan_1px_dashline'] = QtGui.QPen(QtCore.Qt.cyan, 1, QtCore.Qt.DashLine)
        self.pens['cyan_1px_dashline'].setDashPattern([1, 2])
        # 获得窗口的长和宽
        size = self.parent.size()
        self.w = size.width()
        self.h = size.height()

        # 设置grid的上下左右补丁边距
        self.grid_padding_left = 55  # 左侧补丁边距
        self.grid_padding_right = 55  # 右侧补丁边距 如果设置为245,则显示五档盘口等信息
        self.grid_padding_top = 20  # 顶部补丁边距
        self.grid_padding_bottom = 17  # 底部补丁边距

        # 开始绘制
        self.start_paint()

        self.paint.end()  # 结束

    '''绘制流程步骤'''

    def start_paint(self):
        self.PriceGridPaint()
        self.rightGridPaint()
        self.timelinePaint()
        self.topInfoPaint()
        self.rulerPaint()
        self.VolumeGridPaint()
        self.pricePaint()
        self.volumePaint()
        self.xyPaint()

    '''设置使用的字体'''

    def setFont(self, code='default'):
        self.paint.setFont(self.fonts[code])

    '''设置使用的笔刷'''

    def setPen(self, code='default'):
        self.paint.setPen(self.pens[code])

    '''绘制股价走势表格'''

    def PriceGridPaint(self):
        self.setPen('red')
        self.paint.setBrush(QtCore.Qt.NoBrush)

        sum_width = self.grid_padding_left + self.grid_padding_right
        sum_height = self.grid_padding_top + self.grid_padding_bottom

        grid_height = self.h - sum_height

        # 画边框
        self.paint.drawRect(self.grid_padding_left, self.grid_padding_top,
                            self.w - sum_width, self.h - sum_height)
        # 成交量和走势的分界线
        self.paint.drawLine(self.grid_padding_left, grid_height * 0.7 + self.grid_padding_top,
                            self.w - self.grid_padding_right, grid_height * 0.7 + self.grid_padding_top)

        # 股票昨收中间线
        self.paint.drawLine(self.grid_padding_left + 1, grid_height * 0.35 + self.grid_padding_top,
                            self.w - self.grid_padding_right, grid_height * 0.35 + self.grid_padding_top)

        # 其他线条
        self.paint.drawLine(0, self.h - self.grid_padding_bottom, self.w - self.grid_padding_right + 55, self.h - self.grid_padding_bottom)
        self.paint.drawLine(0, self.h - self.grid_padding_bottom + 16, self.w, self.h - self.grid_padding_bottom + 16) # 底框线条

        # self.paint.drawLine(self.w - self.grid_padding_right, 0, self.w - self.grid_padding_right, self.h - self.grid_padding_bottom + 16)
        self.paint.drawLine(self.w - self.grid_padding_right + 55, 0, self.w - self.grid_padding_right + 55, self.h - self.grid_padding_bottom + 16)
        self.setPen('yellow')
        # self.paint.drawText(self.w - self.grid_padding_right + 5, self.h - self.grid_padding_bottom - 4, QtCore.QString(u'成交量'))
        self.setPen('white')
        # 右下角文字
        # self.paint.drawText(self.w - self.grid_padding_right + 12, self.h - self.grid_padding_bottom + 12, QtCore.QString(u'实时'))

    '''绘制成交量走势表格'''

    def VolumeGridPaint(self):
        sum_width = self.grid_padding_left + self.grid_padding_right
        sum_height = self.grid_padding_top + self.grid_padding_bottom

        grid_height = self.h - sum_height
        max_volume = self.parent.stk_data['max_vol']

        px_h_radio = max_volume / (grid_height * 0.3)

        self.setPen('red_1px_dashline')

        grid_num = 6
        x = grid_num
        cnt = grid_height * 0.3 / grid_num
        for i in range(0, grid_num):
            self.setPen('red_1px_dashline')
            # 计算坐标
            y1 = self.grid_padding_top + (grid_height * 0.7) + i * cnt
            x1 = self.grid_padding_left
            x2 = self.grid_padding_left + self.w - sum_width

            self.paint.drawLine(x1, y1, x2, y1)  # 画价位虚线

            vol_int = int(cnt * x * px_h_radio)
            vol_str = str(vol_int)
            fw = self.metrics.width(vol_str)  # 获得文字宽度
            fh = self.metrics.height() / 2  # 获得文字高度
            self.setPen('yellow')
            self.paint.drawText(x2 + 55 - fw, y1 + fh, vol_str)  # 写入右侧成交量柱状图文字
            self.setPen('white')
            # self.paint.drawText(x1 - 2 - self.metrics.width(str(x)), y1 + fh, str(x))  # 写入左侧成交量柱状图文字
            x -= 1

    '''绘制左侧信息栏和盘口等内容'''

    def rightGridPaint(self):
        self.setPen('red')
        # 绘制信息内容之间的分割线
        _h = 0
        _x = self.w - self.grid_padding_right + 55
        self.paint.drawLine(self.w - 1, 0, self.w - 1, self.h - self.grid_padding_bottom + 16)
        self.paint.drawLine(0, 0, 0, self.h - self.grid_padding_bottom + 16)
        self.paint.drawLine(0, _h, self.w, _h)
        _h += 23
        self.paint.drawLine(_x, _h, self.w, _h)
        _h += 24
        self.paint.drawLine(_x, _h, self.w, _h)

        _h += 93
        self.paint.drawLine(_x, _h, self.w, _h)
        _h += 20
        self.paint.drawLine(_x, _h, self.w, _h)
        _h += 93
        self.paint.drawLine(_x, _h, self.w, _h)
        _h += 123
        self.paint.drawLine(_x, _h, self.w, _h)
        _h += 23
        self.paint.drawLine(_x, _h, self.w, _h)
        # 股票名称和代码
        self.setFont('yahei_14')
        self.setPen('yellow')
        name_str = QtCore.QString(u'%s %s' % (self.parent.stk_info['code'], self.parent.stk_info['name']))
        self.paint.drawText(_x + 35, 18, name_str)
        # 委比和委差
        self.setFont('yahei_14')
        zx_str = QtCore.QString(u'最新')
        self.paint.drawText(_x + 3, 156, zx_str)
        self.setPen('gray')
        wb_str = QtCore.QString(u'委比')
        wc_str = QtCore.QString(u'委差')
        xs_str = QtCore.QString(u'现手')
        self.paint.drawText(_x + 3, 39, wb_str)
        self.paint.drawText(_x + 100, 39, wc_str)
        self.paint.drawText(_x + 100, 156, xs_str)
        fh = self.metrics.height()

        left_field_list = [u'涨跌', u'涨幅', u'振幅', u'总手', u'总额', u'换手', u'分笔']
        i = 1
        for field in left_field_list:
            field_str = QtCore.QString(field)
            self.paint.drawText(_x + 3, 253 + (i * 17), field_str)
            i += 1

        right_field_list = [u'均价', u'前收', u'今开', u'最高', u'最低', u'量比', u'均量']

        i = 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值