python_PyQt5运行股票研究python方法工具V1.0

写在前面:

1 在写研究方法过程中(例如:股票研究),很多方法根据数据的更新需要重复运行获取新的结果,本工具就是固化这些需要重复运行的代码,可以直接在工具中运行得到更新的结果。

2 本文是V1.0版本,提供运行python方法的框架,结果显示的控件后续根据研究过程的需要会陆续补充

界面展示:

 代码:

日志窗体

class LogShowWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.init_data()
        self.init_ui()
        pass
    def init_data(self):
        self.whole_data:List = []
        self.current_log: str = None
        pass
    def init_ui(self):
        self.setWindowTitle('执行日志')
        self.setMinimumWidth(600)
        self.setMinimumHeight(600)

        pre_btn = QtWidgets.QPushButton('上一个')
        pre_btn.clicked.connect(self.pre_btn_clicked)
        next_btn = QtWidgets.QPushButton('下一个')
        next_btn.clicked.connect(self.next_btn_clicked)

        layout_one = QtWidgets.QHBoxLayout()
        layout_one.addStretch(1)
        layout_one.addWidget(pre_btn)
        layout_one.addWidget(next_btn)
        layout_one.addStretch(1)

        self.log_textedit = QtWidgets.QTextEdit()

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(layout_one)
        layout.addWidget(self.log_textedit)
        self.setLayout(layout)
        pass
    def set_data(self,data:List):
        self.whole_data.clear()
        self.whole_data = data

        self.current_log = self.whole_data[-1]
        self.fill_log()
        pass
    def pre_btn_clicked(self):
        cur_i = self.whole_data.index(self.current_log)
        if cur_i<=0:
            cur_i = len(self.whole_data)-1
        else:
            cur_i = cur_i -1
        self.current_log = self.whole_data[cur_i]
        self.fill_log()
        pass
    def next_btn_clicked(self):
        cur_i = self.whole_data.index(self.current_log)
        if cur_i >= len(self.whole_data) - 1:
            cur_i = 0
        else:
            cur_i = cur_i + 1
        self.current_log = self.whole_data[cur_i]
        self.fill_log()
        pass
    def fill_log(self):
        self.log_textedit.clear()
        self.log_textedit.setPlainText(self.current_log)
        pass
    pass

 代码执行控件(界面中蓝色框部分)

class ExcuteShowWidget(QtWidgets.QWidget):
    signal_excute = QtCore.pyqtSignal(object)
    def __init__(self):
        super().__init__()

        self.thread_caculate: Thread = None

        self.init_data()
        self.init_ui()
        self.register_event()
        self.progress_init()
        pass
    def init_data(self):
        self.please_select_str: str = '-- 请选择 --'
        self.dir_path: str = ''
        self.log_list: List[str] = []
        self.log_widget: QtWidgets.QWidget = None
        pass
    def init_ui(self):
        self.caculate_progress = QtWidgets.QProgressBar()
        self.caculate_status_label = QtWidgets.QLabel()

        layout_progress = QtWidgets.QHBoxLayout()
        layout_progress.addWidget(self.caculate_progress)
        layout_progress.addWidget(self.caculate_status_label)

        log_btn = QtWidgets.QPushButton('日志')
        log_btn.clicked.connect(self.log_btn_clicked)

        self.code_combox = QtWidgets.QComboBox()
        self.code_combox.addItem(self.please_select_str)

        excute_code_btn = QtWidgets.QPushButton('执行')
        excute_code_btn.clicked.connect(self.excute_code_btn_clicked)
        self.excute_info_label = QtWidgets.QLabel()
        self.excute_info_label.setStyleSheet('QLabel{font-size:18px;color:red;font-weight:bold;}')

        layout_one = QtWidgets.QHBoxLayout()
        layout_one.addWidget(log_btn)
        layout_one.addWidget(self.code_combox)
        layout_one.addWidget(excute_code_btn)
        layout_one.addWidget(self.excute_info_label)

        self.scroll_layout = QtWidgets.QVBoxLayout()
        self.scroll_area = QtWidgets.QScrollArea()
        self.scroll_area.setWidgetResizable(True)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(layout_progress)
        layout.addLayout(layout_one)
        layout.addWidget(self.scroll_area)
        self.setLayout(layout)
        pass
    def register_event(self):
        self.signal_excute.connect(self.process_excute_event)
        pass
    def process_excute_event(self,data:Dict):
        mark_str = data['mark_str']
        status = data['status']
        if status == 'success':
            self.excute_info_label.setText(f'{mark_str} 执行成功')

            ret = data['ret']
            target_style = ret['target_style']
            if target_style == 'table':
                # 表格类型结果
                pre_map = {
                    'header':ret['target_header'],
                    'data':ret['target_data']
                }
                node_widget = TableNodeWidget()
                node_widget.set_data(pre_map)
                self.fill_scroll_area([node_widget])
                pass
            elif target_style == 'graph':
                # 图类型
                pre_map = {
                    'data':ret['target_data']
                }
                node_widget = GraphNodeWidget()
                node_widget.set_data(pre_map)
                self.fill_scroll_area([node_widget])
                pass

            self.thread_caculate = None
            self.progress_finished()
            pass
        else:
            self.excute_info_label.setText(f'{mark_str} 失败!失败!')
            now_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            log_str = f'{now_str}::{mark_str}::{data["msg"]}'
            self.log_list.append(log_str)

            self.thread_caculate = None
            self.progress_finished()
            pass
        pass

    def excute_code_btn_clicked(self):
        cur_txt = self.code_combox.currentText()
        if not cur_txt or cur_txt == self.please_select_str:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '请选择要执行的代码',
                QtWidgets.QMessageBox.Yes
            )
            return
        py_file_path = self.dir_path+ os.path.sep + cur_txt + '.py'
        json_file_path = self.dir_path + os.path.sep + cur_txt + '.json'
        if not os.path.exists(py_file_path):
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '不存在该py文件',
                QtWidgets.QMessageBox.Yes
            )
            return
        if not os.path.exists(json_file_path):
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '不存在该json文件',
                QtWidgets.QMessageBox.Yes
            )
            return
        with open(py_file_path,'r',encoding='utf-8') as fr:
            py_code_str = fr.read()
        try:
            with open(json_file_path,'r',encoding='utf-8') as fr:
                json_obj = json.load(fr)
        except Exception as e:
            QtWidgets.QMessageBox.information(
                self,
                '报错',
                e.__str__(),
                QtWidgets.QMessageBox.Yes
            )
            return
        self.start_caculate_thread(cur_txt,{'py_code':py_code_str,'json_obj':json_obj})
        pass
    def set_target_combox_data(self,data:List,dir_path:str):
        self.dir_path = dir_path
        self.code_combox.clear()
        self.code_combox.addItem(self.please_select_str)
        self.code_combox.addItems(data)
        pass
    def log_btn_clicked(self):
        if not self.log_widget:
            self.log_widget = LogShowWidget()
        self.log_widget.set_data(self.log_list)
        self.log_widget.show()
        pass
    def fill_scroll_area(self,widget_list:List):
        while self.scroll_layout.count():
            item = self.scroll_layout.takeAt(0)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            pass
        sc_child_widget = self.scroll_area.takeWidget()
        if sc_child_widget is not None:
            sc_child_widget.deleteLater()
        for item in widget_list:
            self.scroll_layout.addWidget(item)
        one_sc_child_widget = QtWidgets.QWidget()
        one_sc_child_widget.setLayout(self.scroll_layout)
        self.scroll_area.setWidget(one_sc_child_widget)
        pass

    def start_caculate_thread(self,mark_str:str,data:Dict[str,Any]):
        if self.thread_caculate:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '线程正在执行任务,请稍后。。。',
                QtWidgets.QMessageBox.Yes
            )
            return
        self.thread_caculate = Thread(
            target=self.running_caculate_thread,
            args=(
                mark_str, data,
            )
        )
        self.thread_caculate.start()
        self.progress_busy()
        pass
    def running_caculate_thread(self,mark_str:str,data:Dict[str,Any]):
        py_code = data['py_code']
        json_obj = data['json_obj']
        try:
            namespace = {}
            fun_code = compile(py_code,'<string>','exec')
            exec(fun_code,namespace)
            ret = namespace['excute_code'](json_obj)

            res_map = {
                'mark_str':mark_str,
                'status':'success',
                'ret':ret
            }
            self.signal_excute.emit(res_map)
        except Exception as e:
            res_map = {
                'mark_str':mark_str,
                'status':'error',
                'msg':e.__str__()
            }
            self.signal_excute.emit(res_map)
        pass
    def progress_init(self) -> None:
        self.caculate_progress.setValue(0)
        self.caculate_status_label.setText('无任务')
    def progress_busy(self) -> None:
        self.caculate_progress.setRange(0, 0)
        self.caculate_status_label.setText('正在执行')
    def progress_finished(self) -> None:
        self.caculate_progress.setRange(0, 100)
        self.caculate_progress.setValue(100)
        self.caculate_status_label.setText('执行完毕')
        pass
    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
        if self.log_widget:
            self.log_widget.close()
        self.close()
        pass

主界面

class StockAnalysisMainWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.init_data()
        self.init_ui()
        pass
    def init_data(self):
        self.code_py_list:List = []
        pass
    def init_ui(self):
        self.setWindowTitle('PyQt5运行股票研究python方法工具V1.0')

        code_py_dir_btn = QtWidgets.QPushButton('代码py文件目录')
        code_py_dir_btn.clicked.connect(self.code_py_dir_btn_clicked)
        self.code_py_dir_lineedit = QtWidgets.QLineEdit()
        tip_label = QtWidgets.QLabel('提示:json文件为参数文件,同一业务json和py文件同名')

        layout_one = QtWidgets.QFormLayout()
        layout_one.addRow(code_py_dir_btn,self.code_py_dir_lineedit)
        layout_one.addWidget(tip_label)

        copy_one_widget_btn = QtWidgets.QPushButton('复制窗体')
        copy_one_widget_btn.clicked.connect(self.copy_one_widget_btn_clicked)

        layout_two = QtWidgets.QHBoxLayout()
        layout_two.addWidget(copy_one_widget_btn)
        layout_two.addStretch(1)

        layout_three = QtWidgets.QVBoxLayout()
        layout_three.addLayout(layout_one)
        layout_three.addLayout(layout_two)

        # 分界线 s
        h_line = QtWidgets.QFrame()
        h_line.setFrameShape(QtWidgets.QFrame.HLine)
        h_line.setFrameShadow(QtWidgets.QFrame.Sunken)
        # 分界线 e

        self.excute_show_widget = ExcuteShowWidget()

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(layout_three)
        layout.addWidget(h_line)
        layout.addWidget(self.excute_show_widget)
        self.setLayout(layout)
        pass
    def code_py_dir_btn_clicked(self):
        path = QtWidgets.QFileDialog.getExistingDirectory(
            self,
            '打开py和json文件所在目录',
            '.'
        )
        if not path:
            return
        self.code_py_list.clear()
        py_file_list = os.listdir(path)
        for item in py_file_list:
            if item.endswith('.py'):
                self.code_py_list.append(item[0:-3])
        self.code_py_dir_lineedit.setText(path)
        self.excute_show_widget.set_target_combox_data(self.code_py_list,path)
        pass
    def copy_one_widget_btn_clicked(self):
        pass
    pass

执行代码:

if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    app = QtWidgets.QApplication(sys.argv)
    main_window = StockAnalysisMainWidget()
    main_window.showMaximized()
    app.exec()
    pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/73463.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sharding-JDBC概述

前言 ​ 随着业务数据量的增加&#xff0c;原来所有的数据都是在一个数据库上的&#xff0c;网络IO及文件IO都集中在一个数据库上的&#xff0c;因此CPU、内存、文件IO、网络IO都可能会成为系统瓶颈。当业务系统的数据容量接近或超过单台服务器的容量、QPS/TPS接近或超过单个数…

自动方向识别式 LSF型电平转换芯片

大家好&#xff0c;这里是大话硬件。 今天这篇文章想分享一下电平转换芯片相关的内容。 其实在之前的文章分享过一篇关于电平转换芯片的相关内容&#xff0c;具体可以看链接《高速电路逻辑电平转换设计》。当时这篇文章也是分析的电平转换芯片&#xff0c;不过那时候更多的是…

打造企业或者个人IP引流法

打造企业或者个人IP引流法. 大家好&#xff0c;我是百收网SEO编辑&#xff1a;狂潮老师&#xff0c;今天给大家分享企业IP打造的方法 首先我们想让人知道你的企业叫什么&#xff0c;怎么找到你的企业 这个时候我们就需要去各大平台发布信息&#xff0c;客户想了解直接去搜索…

Unity2D RPG开发笔记 P1 - Unity界面基础操作和知识

文章目录 工具选择简单快捷键Game 窗口分辨率检视器Transform 组件Sprite Renderer综合检视器 工具选择 按下 QWERTY 可以选择不同的工具进行 旋转、定位、缩放 简单快捷键 按下 Ctrl D 可以复制物体 Game 窗口分辨率 16:9 为最常见的分辨率 检视器 Transform 组件 物体在…

Vue3 引用第三方Swiper内容触摸滑动简单应用

去官网查看更多教程→&#xff1a;Swiper官网 → 点击教程在vue中使用Swiper→ 在Vue中使用Swiper cd 到项目 安装Swiper&#xff1a; cnpm install --save swiper 安装指定版本 cnpm install --save swiper8.1.6 9.4.1 10.1.0…

了解 Langchain️是个啥?:第 1 部分

一、说明 在日常生活中&#xff0c;我们主要致力于构建端到端的应用程序。我们可以使用许多自动 ML 平台和 CI/CD 管道来自动化 ml 管道。我们还有像Roboflow和Andrew N.G.的登陆AI这样的工具来自动化或创建端到端的计算机视觉应用程序。 如果我们想在OpenAI或拥抱脸的帮助下创…

[C++] 模板template

讲模板之前呢&#xff0c;我们先来谈谈泛型编程&#xff1a; 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础。 模板分为两类&#xff1a;函数模板与类模板 1、函数模板 1.1 函数模板概念 函数模板代表了一个函数家…

在pycharm中对使用脚本文件运行的程序进行调试

在github中下载的许多项目都可以使用给出的脚本文件运行&#xff0c;本文介绍如果在pycharm中对使用脚本文件运行的程序进行调试的方法。 1.点击 edit configurations 2.选择要debug的py文件&#xff0c;并且填写参数 3.点击运行旁边的debug按钮

尚硅谷大数据项目《在线教育之离线数仓》笔记001

视频地址&#xff1a;尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P003 P004【数仓概念讲的颇为详细】 P018 P019 P020 P021 P022 P023 P024 P003 时间切片&#xff1a;时间回溯&#xff0c;找回以前的数据。 P004【数仓概念讲的颇为详细】 核心架…

前端开发实习总结参考范文(合集)

▼前端开发实习总结篇一 今天就简单聊聊上面的StrutsSpringHibernate吧。 Struts 代表&#xff1a;表示层;Spring代表&#xff1a;业务逻辑层;Hibernate则代表持久层。他们是目前在Java Web编程开发中用得最多的框架&#xff0c;其实这样区分是为了适应软件开发过程中各个分工…

Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载

上拉、下拉的效果图如下&#xff1a; 使用步骤 1、在清单文件中添加依赖 implementation ‘com.android.support:recyclerview-v7:27.1.1’ implementation “androidx.swiperefreshlayout:swiperefreshlayout:1.0.0” 2、main布局 <LinearLayout xmlns:android"http…

HTML详解连载(4)

HTML详解连载&#xff08;4&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽CSS定义书写位置示例注意 CSS引入方式内部样式表&#xff1a;学习使用 外部演示表&#xff1a;开发使用代码示例行内样式代码示例 选择器作用基础选择器标签选择器举例特…

日常BUG——SpringBoot关于父子工程依赖问题

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 在父子工程A和B中。A依赖于B&#xff0c;但是A中却无法引入B中的依赖&#xff0c;具体出现的…

MySQL 45讲笔记(1-10讲)

1. SQL语句如何开始执行&#xff1f; MySQL分为Server和存储引擎两部分&#xff1a; Server层包含连接器、存储缓存、分析器、执行器等&#xff0c;以及所有的内置函数&#xff08;事件、日期&#xff09;等等&#xff0c;还有视图、触发器。 存储引擎是负责数据的存储和提取&a…

风丘科技将亮相 EVM ASIA 2023

风丘科技将首次亮相 EVM ASIA 2023 WINDHILL will debut EVM ASIA 2023 ——可持续移动的未来 —The Future of SUSTAINABLE Mobility EVM ASIA 2023是亚太地区电气化的国际性展会&#xff0c;专注于新能源汽车、充电技术及汽车零件制造等。展会致力于促进包括充电站、交通…

DAY19

题目一 空间尝试模型 一个样本做行一个样本做列 范围尝试模型 以....做分隔 dp[i][j] 为以i为左界限 以j为右界限 求这个范围内的计算值(不对 是方法数) 这& | ^ 都是双目运算符 观察一下规律 整体字符数量一定为奇数(包括运算符和数字) 对应到数组中 数组的位一定是偶数…

openGauss学习笔记-39 openGauss 高级数据管理-分区表

文章目录 openGauss学习笔记-39 openGauss 高级数据管理-分区表39.1 范围分区表的分类39.2 创建范围分区39.2.1 创建VALUES LESS THAN范围分区表语法格式39.2.2 创建VALUES LESS THAN范围分区表参数说明39.2.3 创建VALUES LESS THAN范围分区表示例 39.3 询分区表39.3.1 查询分区…

​​C++多态​​

目录 1. 多态的概念 2. 多态的定义及实现 多态的构成条件 虚函数 虚函数的重写 特例 override 和 final 1. final&#xff1a;修饰虚函数&#xff0c;表示该虚函数不能再被重写 2.override: 检查派生类虚函数是否重写了基类某个虚函数&#xff0c;如果没有重写编译报错…

档案库房智能管理系统的功能有哪些呢?

档案库房智能管理系统是一个基于人工智能技术的综合性档案管理解决方案&#xff0c;通过自动化、智能化的方式&#xff0c;优化了档案管理流程&#xff0c;提高了工作效率和信息安全性。 1.档案入库管理&#xff1a; 档案信息录入&#xff1a;系统可以通过扫描、识别和自动填写…

Qt应用开发(基础篇)——框架类 QFrame

一、前言 QFrame继承于QWidget&#xff0c;被QLCDNumber、QToolBox、QLabel、QListView等部件继承&#xff0c;是一个拥有矩形框架的基类。 QFrame可以直接创建成一个没有内容的的矩形框架&#xff0c;框架的样式由边框厚度(lineWidth)、框架形状(QFrame::Shape)和阴影样式(QFr…