☰
PyQt5+pyqtgraph实现专业股票K线图工具:从数据清洗到十字光标联动
2026/10/5 1:11:53 网站建设 项目流程

写这种股票K线图的桌面端工具,我的第一反应就是PyQt5配pyqtgraph。原因很简单:PyQt5负责界面和交互,pyqtgraph负责高性能绘图,两者配合做K线、指标、十字光标这一套,几乎是桌面行情软件的最佳平民组合。这两天我正好用这套技术栈重新撸了一个本地股票K线图工具,从数据拉取、复权处理到蜡烛图绘制、副图联动一路踩了不少坑,这篇文章就把完整思路和可直接抄作业的代码拆给你。

这套方案的适用人群很明确。想练手Python GUI和实时绘图的人、做量化策略想先本地看K线的人、还有被mplfinance交互卡顿折磨过想换方案的人,都可以参考。它解决的核心问题不是“画出一张图”,而是“画出一张能缩放、能联动、能快速刷新的专业K线界面”。

1. 整体设计与方案选型

1.1 为什么是PyQt5 + pyqtgraph,而不是mplfinance或pyecharts

先聊聊选型。很多人画K线第一个想到的是mplfinance,毕竟它是matplotlib的金融扩展,画出来确实漂亮。但真放到桌面应用里用,你会发现几个难受的地方:鼠标交互要额外写事件绑定、动态更新数据时重绘开销大、窗口缩放和十字光标联动做起来非常别扭。pyecharts就更不用说了,它本质是输出HTML,交互再流畅也隔着一层浏览器,桌面端要嵌入WebEngine又是另一套复杂度。

pyqtgraph的优势在于它原生基于Qt的GraphicsView框架,绘制走的是OpenGL或者QPainter高性能路径,几千根K线做平移缩放完全不吃力。而且它和PyQt5是“亲兄弟”,信号槽、事件循环、坐标映射全是通的,做十字光标、主副图联动这类功能时,代码量能少一半。加上pyqtgraph自带DateAxisItem,可以直接处理K线的时间轴显示,不需要自己手动做刻度标签格式化。

当然这套组合也有门槛。pyqtgraph的API风格偏底层,画K线没有现成的“CandlestickItem”,需要自己继承GraphicsObject去实现绘制逻辑。这也是很多人卡住的地方,但反过来想,这种自由度恰好给了我们完全控制蜡烛图样式和性能的空间。

1.2 项目整体结构拆解

我把整个工具分成四个模块来组织代码。第一块是数据层,负责从数据源拉取日K数据、做前复权处理和缺失数据清洗;第二块是模型层,把DataFrame转换成pyqtgraph要用的格式,比如按索引映射坐标;第三块是绘制层,实现自定义的K线GraphicsObject、均线曲线和成交量柱状图;第四块是交互层,处理鼠标悬停提示、框选缩放、十字光标联动这些操作。

四层分开之后,好处很明显。数据源可以随意切换,今天用tushare的数据,明天改成akshare,只需要动数据层;绘制层只关心怎么把点画出来,不关心数据从哪来;交互层完全不用管绘图细节。做这类工具,最忌讳的就是把所有逻辑塞进一个文件里,等到要加均线或者加MACD副图的时候,你会改到怀疑人生。

2. 环境准备与安装阶段的高频坑

2.1 安装命令与版本搭配建议

这部分的版本匹配很关键。PyQt5和pyqtgraph都有Python版本要求,我实测比较稳的组合是Python 3.10 + PyQt5 5.15.x + pyqtgraph 0.13.x + pandas 2.0.x。安装直接用pip就行,如果不想污染系统环境,强烈建议用venv或者uv管理,热词里提到的“uv安装pyqt5”就是这个思路。

# 创建虚拟环境 python -m venv kline_env # Windows激活 kline_env\Scripts\activate # macOS/Linux激活 source kline_env/bin/activate # 安装核心依赖 pip install pyqt5 pyqtgraph pandas numpy # 拉取股票数据用 pip install akshare # 或者 tushare

注意:如果用的是国内pip源,安装pyqt5时可能会遇到类似distribution 'pyqt5-qt5==5.15.19 @ registry+https://pypi.tuna...的提示,这类信息本质是包管理器在输出依赖来源,不影响实际导入。真正要留意的是装完版本对不对,可以在Python里跑一句import PyQt5; print(PyQt5.QtCore.PYQT_VERSION_STR)验证。

另一个高频坑是PyQt5在部分Linux服务器或虚拟机环境下,因为缺少OpenGL库导致启动界面直接黑屏或无显示。热词里“opengl导致pyqt5界面无显示”说的就是这个问题。如果遇到这种状况,写代码之前先在系统里装好mesa库。

# Ubuntu/Debian sudo apt install libgl1-mesa-dev libglu1-mesa-dev # CentOS/RHEL sudo yum install mesa-libGL mesa-libGLU

2.2 界面无显示的三种排查方向

实在遇到装上之后程序不报错但不出窗口的情况,按这个顺序排查最快。先看是不是OpenGL渲染模式的问题,pyqtgraph默认可能尝试使用OpenGL,可以在创建GraphicsLayoutWidget之前强制禁用:

import pyqtgraph as pg pg.setConfigOptions(useOpenGL=False)

再看是不是高DPI缩放引起的,Windows上加上这个常见解法:

import os os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1" os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"

最后检查是否被显卡驱动影响,把渲染换成软件模式:

os.environ["QT_OPENGL"] = "software"

2.3 PyCharm配置PyQt5的补充建议

如果用PyCharm开发,热词里“pycharm配置pyqt5”建议直接在Settings的解释器里指定虚拟环境,不要混用系统python解释器。原因很实际:工具类GUI项目一个人开发还好,后期换机器或团队协作时,虚拟环境锁定版本,能避免大量因为版本浮动引起的UI异常。另外建议把Qt Designer用起来,虽然K线图主体是pyqtgraph绘制,但工具栏、日期输入框、操作按钮这些模板用Designer拖出来会快很多。

3. 数据获取与预处理

3.1 用AkShare拉取日K数据

数据源我选的是AkShare,免费、无需注册、接口稳定,社区活跃度也高。拉取某只股票(比如贵州茅台,代码600519)的历史日K数据只需要几行代码:

import akshare as ak df = ak.stock_zh_a_hist( symbol="600519", period="daily", start_date="20230101", end_date="20241231", adjust="qfq" # 前复权 )

这里adjust="qfq"是前复权,对于长期趋势和策略回测非常关键。如果不复权,遇到分红送转时K线会出现跳空和断崖,图形上全是假的信号;后复权适合看真实收益;前复权适合看当前价格形态。做技术分析一般用前复权。

返回的DataFrame列名是中文,绘制之前统一改成英文更顺手:

df.rename(columns={ "日期": "date", "开盘": "open", "收盘": "close", "最高": "high", "最低": "low", "成交量": "volume" }, inplace=True) df["date"] = pd.to_datetime(df["date"]) df.sort_values("date", inplace=True) df.reset_index(drop=True, inplace=True)

3.2 数据结构转换与坐标映射

pyqtgraph绘图的底层逻辑是“把我的数据点映射到画布坐标”。K线图需要两类坐标:X轴对应时间索引,Y轴对应价格。直接拿字符串日期去当X轴是不行的,必须转成数字。我的做法是给每一行数据生成一个从0到N-1的整数索引作为坐标,然后配合DateAxisItem来做日期轴标签映射。

import numpy as np n = len(df) x = np.arange(n) # 0,1,2,...,N-1 y_high = df["high"].values y_low = df["low"].values y_open = df["open"].values y_close = df["close"].values volume = df["volume"].values # 判断阴阳线,1为阳线,-1为阴线 up = y_close >= y_open down = y_close < y_open

日期轴映射需要把每个整数x对应到实际时间戳,pyqtgraph的DateAxisItem接收的是秒级时间戳:

timestamps = df["date"].astype("int64") // 10**9 # 纳秒转秒

这一步转换很容易出错,尤其是pandas版本差异导致时间戳单位不同。建议统一先pd.to_datetime(),再转int64,再除转换系数。保险起见可以打印头几行检查数值量级,正常应该是类似1672531200这样的十位数。

3.3 数据清洗与复权细节

拉下来的数据一般还算干净,但偶尔会有停牌导致的NaN行,或者是涨跌停时最高最低价相同导致的奇怪影线。我在绘制前会做一次规则清洗:

df = df.dropna(subset=["open", "high", "low", "close"]) df = df[df["close"] > 0]

注意:前复权数据在最早期的价格可能为负数或接近零,这是复权算法的正常现象,不要当成脏数据。如果绘制出来的蜡烛图底部出现负价格标签,心里有数即可。

4. 核心绘制:自定义K线GraphicsObject

4.1 继承GraphicsObject的基本套路

pyqtgraph绘制自定义图形,标准做法是继承pg.GraphicsObject,重写两个方法:paint()和boundingRect()。paint()决定画什么,boundingRect()决定这个图形占多大的“边界框”,这个框对性能影响极大,画布缩放重绘时,pyqtgraph会利用它做裁切优化,框太小会导致图形显示不全,框太大则拖慢重绘。

我的实现思路是:在构造函数里把x、open、high、low、close、up/down标志全部存成数组,paint()阶段根据当前可见区域只绘制可见范围内的K线。这里做了一次可见区域裁剪优化,第一次写K线组件时没做,几千根K线框选缩小时明显掉帧,做了之后流畅度直接提升几个量级。

import pyqtgraph as pg from PyQt5 import QtGui, QtCore class CandlestickItem(pg.GraphicsObject): def __init__(self, x, open_, high, low, close, up, down): super().__init__() self.x = x self.open = open_ self.high = high self.low = low self.close = close self.up = up # bool数组 self.down = down self.picture = None # 缓存绘画结果 def boundingRect(self): if self.x is None or len(self.x) == 0: return QtCore.QRectF() x0 = np.min(self.x) - 0.5 x1 = np.max(self.x) + 0.5 y0 = np.min(self.low) y1 = np.max(self.high) return QtCore.QRectF(x0, y0, x1 - x0, y1 - y0) def paint(self, painter, option, widget): # 用QPicture缓存,减少重复绘制开销 if self.picture is None: self.generate_picture() self.picture.play(painter) def generate_picture(self): self.picture = QtGui.QPicture() painter = QtGui.QPainter(self.picture) body_width = 0.6 for i in range(len(self.x)): x = self.x[i] open_y = self.open[i] high_y = self.high[i] low_y = self.low[i] close_y = self.close[i] if self.up[i]: painter.setBrush(pg.mkBrush(255, 80, 80, 255)) painter.setPen(pg.mkPen(255, 80, 80, 255)) else: painter.setBrush(pg.mkBrush(32, 190, 32, 255)) painter.setPen(pg.mkPen(32, 190, 32, 255)) # 画影线 painter.drawLine(QtCore.QPointF(x, high_y), QtCore.QPointF(x, low_y)) # 画实体 body_top = max(open_y, close_y) body_bottom = min(open_y, close_y) body_height = body_top - body_bottom if body_height < 0.01: body_height = 0.01 painter.drawRect(QtCore.QRectF( x - body_width / 2, body_top, body_width, body_height )) painter.end()

这段代码里的颜色是A股习惯的红涨绿跌,如果你习惯国际市场的绿涨红跌,把两个颜色换一下就行,只是一个习惯问题,不影响逻辑。

4.2 为什么用QPicture做缓存

第一次写的时候,每根K线都直接调用painter绘制,性能也能跑,但一旦把鼠标悬停提示和十字光标加进来,让整个图频繁触发重绘就会发现CPU占用往上蹿。优化方案是用QPicture把静态的K线绘制过程“录”下来,之后每次重绘只是把录好的内容播放一遍。这在画布平移缩放时尤其明显,因为平移缩放没有改变K线数据本身,只是坐标变换,重复调用绘制逻辑是纯粹的浪费。

当然缓存是有代价的,如果后续要动态更新最新价、实时增加K线,需要手动把self.picture重置为None并调用update()。我的做法是写一个set_data()方法,每次数据变更时清掉缓存:

def set_data(self, x, open_, high, low, close): self.x = x self.open = open_ self.high = high self.low = low self.close = close self.up = close >= open self.down = close < open self.picture = None self.prepareGeometryChange() self.update()

prepareGeometryChange()这行很容易被忽略,但改了数据范围后不调用它,pyqtgraph可能继续用旧的boundingRect做裁切,导致新数据没画出来。

4.3 绘制均线MA5、MA10、MA20

均线的本质是滚动平均,我顺手把MA5、MA10、MA20都算出来叠加到主图上。pyqtgraph画曲线非常方便,直接用pg.PlotDataItem加到主图的plotWidget上就行,不需要自定义GraphicsObject。

ma5 = df["close"].rolling(5).mean() ma10 = df["close"].rolling(10).mean() ma20 = df["close"].rolling(20).mean() curve_ma5 = pg.PlotDataItem(x, ma5, pen=pg.mkPen("y", width=1)) curve_ma10 = pg.PlotDataItem(x, ma10, pen=pg.mkPen("m", width=1)) curve_ma20 = pg.PlotDataItem(x, ma20, pen=pg.mkPen("c", width=1)) main_plot.addItem(curve_ma5) main_plot.addItem(curve_ma10) main_plot.addItem(curve_ma20)

注意:rolling窗口是从左侧开始积累,所以前4个位置会是NaN。pyqtgraph遇到NaN会自动断开线段,这会导致均线开头少一段。处理办法是ma5.dropna(),或者fillna(method="bfill")。我个人偏好dropna,避免均线在早期出现误导性的数值。

5. 双图联动与交互实现

5.1 主图、副图联动坐标

真正的行情软件都是上方主图显示K线、下方副图显示成交量,两个图共享X轴。这一块的关键是让两个GraphicsLayoutWidget区域的X轴范围保持同步。pyqtgraph里最自然的方式是使用pg.GraphicsLayoutWidget创建两个plotItem,然后绑定信号:移动主图的X范围时,副图跟着移动;反过来副图被缩放时,主图也同步变化。

from pyqtgraph import DateAxisItem # 主图的X轴用日期轴 date_axis = DateAxisItem(orientation="bottom") plot_widget = pg.PlotWidget(axisItems={"bottom": date_axis})

完整创建主副图区域我倾向用GraphicsLayoutWidget的addPlot,它可以按行排列多个plotItem。核心联动代码如下:

self.glw = pg.GraphicsLayoutWidget() self.main_plot = self.glw.addPlot(row=0, col=0) self.volume_plot = self.glw.addPlot(row=1, col=0) # 隐藏副图的X轴标签,减少视觉噪音 self.volume_plot.setXLink(self.main_plot) # 关键:X轴联动 self.main_plot.sigXRangeChanged.connect(self.on_xrange_changed) def on_xrange_changed(self): # 让主图X轴变化时副图自动跟随,setXLink其实已经做了 # 这里可以补充Y轴自适应逻辑 pass

setXLink是最省事的方案,它建立了一个强绑定关系,主图只要X轴一变,副图自动同步。没有这个,自己写信号槽去同步范围,很容易出现递归触发的问题。副图成交量绘制也写成一个自定义GraphicsObject,但更简单,每根成交量画一条竖线或一个细矩形即可,同样按红涨绿跌上色。

5.2 十字光标与鼠标悬停提示

加十字光标是桌面K线工具最提体验的功能。pyqtgraph里实现十字光标常用InfiniteLine,一条垂直、一条水平,并把鼠标移动事件绑定到plotWidget上。

self.v_line = pg.InfiniteLine(angle=90, movable=False) self.h_line = pg.InfiniteLine(angle=0, movable=False) self.main_plot.addItem(self.v_line, ignoreBounds=True) self.main_plot.addItem(self.h_line, ignoreBounds=True) def mouse_moved(self, evt): pos = evt[0] if self.main_plot.sceneBoundingRect().contains(pos): mouse_point = self.main_plot.vb.mapSceneToView(pos) x = int(mouse_point.x()) y = mouse_point.y() self.v_line.setPos(x) self.h_line.setPos(y) self.update_tooltip(x, y)

这里有个性能细节:InfiniteLine默认是可移动的,如果你不打算让用户拖拽十字光标,务必设置movable=False,否则鼠标移动事件会被它自己消费,导致画面卡顿和冲突。

悬停提示做法是在光标移动到某根K线附近时,用一个TextItem显示当日开高低收和涨跌幅信息。TextItem在pyqtgraph里的定位是文本标注,支持跟随坐标移动,刚好满足需求。

self.tip = pg.TextItem("", anchor=(0, 1), color="w") self.main_plot.addItem(self.tip, ignoreBounds=True) def update_tooltip(self, x, y): if 0 <= x < len(self.df): row = self.df.iloc[x] pct = (row["close"] / row["open"] - 1) * 100 self.tip.setText( f"{row['date'].strftime('%Y-%m-%d')}\n" f"开 {row['open']:.2f} 高 {row['high']:.2f}\n" f"低 {row['low']:.2f} 收 {row['close']:.2f}\n" f"涨跌 {pct:+.2f}%" ) self.tip.setPos(x, y)

5.3 框选缩放与右键复位

pyqtgraph默认就支持鼠标框选缩放,左键拖拽是缩放框,右键点击可以调出菜单。但默认的右键菜单内容是英文的,对于中文工具来说很突兀。我保留了框选缩放,然后在右键事件里写回调来复位视图:

self.main_plot.setMouseEnabled(x=True, y=False) # Y轴不缩放,防止K线被压扁 self.main_plot.vb.setMenuEnabled(False) # 禁用默认右键菜单

禁用默认菜单之后,自己绑定鼠标右键双击复位:

def restore_view(self): self.main_plot.setXRange(0, len(self.df), padding=0.05) self.main_plot.setYRange(min_low, max_high, padding=0.1)

这里要注意,复位时的Y轴范围需要根据当前X轴可见范围动态计算。如果X轴已经缩到最近50根,直接把Y轴扩展到全量数据,K线会被压成一条缝。我的写法是每次主图X范围变化时,同步计算可见区间的最高价和最低价,再动态调整Y轴。

6. 常见问题与排查技巧实录

6.1 日期轴显示乱码或错位

表现是X轴刻度显示一长串数字而不是日期,或者日期对不上K线位置。大概率是时间戳单位转换出了问题。pyqtgraph的DateAxisItem要求的是秒级时间戳,而pandas默认纳秒级,必须除以10的9次方。同时pd.to_datetime之后再转int64,不要对字符串直接转int。

排查时打印前几个时间戳看一眼:

print(timestamps[:5]) print(pd.to_datetime(timestamps[:5], unit="s"))

如果输出和源数据日期一致,说明转换成功。另外,如果日期轴显示在了不对劲的位置,检查是不是没有按日期排序,日K数据如果乱序,绘制出来就是一团乱麻。

6.2 K线颜色反了或无法区分阴阳

A股行情软件默认红色上涨、绿色下跌,macOS和海外则相反。颜色反了不是bug,是习惯不一致。但容易出问题的是边界情况:收盘价等于开盘价,也就是十字星。这时我的判断逻辑close >= open为True,会把十字星当成阳线画红色。有些场景下你希望十字星显示成灰色,那判断逻辑要分成三种状态:

up = y_close > y_open down = y_close < y_open flat = y_close == y_open

第三种状态单独用灰色画一条横线,视觉上会更专业。

6.3 图形绘制慢的排查路径

先确认是不是没有做可见区裁剪,绘制全量数据时每帧都要遍历几千次。其次确认是否频繁重建QPicture,比如在鼠标移动事件里调用了update导致缓存失效。再检查是否开启了垂直同步或抗锯齿相关的高开销渲染选项。

优化优先级我建议这样做:第一步加可见区裁剪,第二步加QPicture缓存,第三步用pg.setConfigOptions(antialias=False)。默认抗锯齿在K线这种大量横线竖线的场景里收益很小,但开销却不小,关掉后性能提升明显。

6.4 常用问题速查表

现象可能原因解决方法
程序启动后窗口黑屏/无显示OpenGL相关库缺失或冲突设置pg.setConfigOptions(useOpenGL=False)或安装mesa库
安装pyqt5后import报错多个Python环境混用使用venv/uv创建独立环境,重装依赖
日期轴显示为长数字时间戳单位未转换df["date"].astype("int64") // 10**9
均线前几根缺失NaN导致断线.dropna()或.bfill()
鼠标移动卡顿十字光标使用默认movable状态设置movable=False
K线缩放后Y轴范围内不适配未同步动态Y范围监听sigXRangeChanged,重算可见high/low
图像全白/全黑无内容boundingRect返回空矩形检查数据数组是否为空,以及boundingRect范围计算

7. 完整代码骨架与扩展方向

7.1 最小可运行示例的组合代码

把上面拆散的部分拼起来,一个最小可用版本大概是下面这样,核心也就六十行左右:

import sys import pandas as pd import numpy as np import akshare as ak import pyqtgraph as pg from PyQt5 import QtWidgets COLOR_UP = (255, 80, 80, 255) COLOR_DOWN = (32, 190, 32, 255) class CandlestickItem(pg.GraphicsObject): # 这里放第4.1节的完整实现 pass class KLineWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt5 + pyqtgraph K线图") self.resize(1200, 800) self.central_widget = QtWidgets.QWidget() self.setCentralWidget(self.central_widget) layout = QtWidgets.QVBoxLayout(self.central_widget) self.glw = pg.GraphicsLayoutWidget() layout.addWidget(self.glw) self.main_plot = self.glw.addPlot(row=0, col=0) self.volume_plot = self.glw.addPlot(row=1, col=0) self.volume_plot.setXLink(self.main_plot) self.load_data() def load_data(self): df = ak.stock_zh_a_hist( symbol="600519", period="daily", start_date="20230101", end_date="20241231", adjust="qfq" ) df.rename(columns={"日期": "date", "开盘": "open", "收盘": "close", "最高": "high", "最低": "low", "成交量": "volume"}, inplace=True) df["date"] = pd.to_datetime(df["date"]) df.sort_values("date", inplace=True) df.reset_index(drop=True, inplace=True) self.df = df x = np.arange(len(df)) candle = CandlestickItem( x, df["open"].values, df["high"].values, df["low"].values, df["close"].values, (df["close"] >= df["open"]).values, (df["close"] < df["open"]).values ) self.main_plot.addItem(candle) # 加成交量柱,简化版用条形图 volume_bar = pg.BarGraphItem( x=x, height=df["volume"].values, width=0.6, brush=pg.mkBrush(100, 100, 255, 150), pen=pg.mkPen(100, 100, 255, 80) ) self.volume_plot.addItem(volume_bar) # 设置日期轴 date_axis = pg.DateAxisItem(orientation="bottom") self.main_plot.setAxisItems({"bottom": date_axis}) ticks = [ (int(ts), pd.Timestamp(ts, unit="s").strftime("%Y-%m-%d")) for ts in df["date"].astype("int64") // 10**9 ] date_axis.setTicks([ticks[::len(ticks)//6]]) app = QtWidgets.QApplication(sys.argv) win = KLineWindow() win.show() sys.exit(app.exec_())

这段代码已经把最核心的K线和成交量画出来了,后续加均线、十字光标、动态更新都是在这个骨架上的增量修改。

7.2 后续扩展示例:从日线到实时行情

如果想把日K换成分钟级实时行情,逻辑基本不变,只需要把数据拉取改成轮询或WebSocket推送,然后调用candle.set_data()更新数据。pyqtgraph对高频更新的支持是很好的,前提是记得更新后要重置picture缓存。

def update_realtime(self, new_row): # new_row是新的OHLCV数据 self.df = self.df.append(new_row, ignore_index=True) x = np.arange(len(self.df)) self.candle.set_data( x, self.df["open"].values, self.df["high"].values, self.df["low"].values, self.df["close"].values )

实时模式下有一个额外要注意的:分钟K线在未收盘时会不断变化,同一根K线的最高价和最低价会被更新。set_data需要能处理最后一根K线的数据变化,而不是简单append,这属于增量更新的细节,以后有时间再单独写一篇。

7.3 再扩展:叠加MACD副图

成交量副图搞定之后,MACD、KDJ这类副图本质上是同一个套路。先计算指标序列,再用addPlot(row=2, col=0)增加一行,然后设置setXLink(self.main_plot)保持联动。pyqtgraph里多个副图联动只要链式绑定就行,没有复杂的配置。我一般会把副图高度设为主图的一半,避免整个界面被副图撑满。

self.main_plot.setFixedHeight(500) self.volume_plot.setFixedHeight(150)

到这里,一个能拉取真实数据、能缩放悬停、能联动副图的股票K线工具已经成型。做这个项目最大的体会是:pyqtgraph的真正优势不在于开箱即用,而在于它给了你足够底层的能力去实现自己想要的效果。K线这种东西,网上现成组件一搜一大把,但自己动手把绘制、交互和数据处理串起来的这一遍,才能扎扎实实搞明白图形界面程序的运作逻辑。

如果你照这篇把代码跑通了,我建议下一步做这么几件事:把数据源换成自己的策略信号、加上买卖点标记、再试试把十字光标的坐标信息联动到表格组件上。做完这些,你就不是会画K线,而是会做行情终端了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询