| | |
| | | import base64 |
| | | import ctypes |
| | | import hashlib |
| | | import json |
| | | import logging |
| | | import multiprocessing |
| | | import queue |
| | | import threading |
| | | import time |
| | | from multiprocessing import freeze_support |
| | | import sys |
| | | from functools import partial |
| | | from multiprocessing import Pipe, Process, freeze_support |
| | | |
| | | import torch |
| | | import win32api |
| | | import win32con |
| | | import win32gui |
| | | from PyQt5.QtGui import QFont, QPalette, QColor, QTextOption |
| | | |
| | | from PyQt5.QtWebChannel import QWebChannel |
| | | from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings |
| | | from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QMessageBox |
| | | from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings, QWebEnginePage |
| | | from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QMessageBox, QLabel |
| | | |
| | | from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal, QTimer, QUrl, QPoint |
| | | from PyQt5.QtCore import Qt, pyqtSlot, QObject, pyqtSignal, QTimer, QUrl, QPoint |
| | | |
| | | import constant |
| | | import gui_wx |
| | | import network_util |
| | | from utils import network_util, xgb_api, ths_util, ths_ocr_util |
| | | import setting |
| | | from utils import tool |
| | | import win32_util |
| | | from kpl.kpl_data_manager import KPLLimitUpDataManager |
| | | from utils.network_delegate_manager import LocalKanPanNetworkDelegate |
| | | |
| | | freeze_support() |
| | | URL_MSG_LIST = f"http://{constant.WEB_HOST}/kp/msg_list.html" |
| | | |
| | | window_msg_queue = queue.Queue() |
| | | |
| | | |
| | | class JSBridgeClass(QObject): |
| | | class BaseBridgeClass(QObject): |
| | | signal_request = pyqtSignal(str, str, str) |
| | | |
| | | def __request_result_callback(self, method, key, result): |
| | | self.webview.page().runJavaScript(f"{method}('{key}','{result}')") |
| | | base64_str = base64.b64encode(result.encode('utf-8')).decode('utf-8') |
| | | self.__webview.page().runJavaScript(f"{method}('{key}','{base64_str}')") |
| | | |
| | | def __init__(self, window, webview): |
| | | def __init__(self, webview): |
| | | super().__init__() |
| | | self.window = window |
| | | self.webview = webview |
| | | self.__webview = webview |
| | | self.signal_request.connect(self.__request_result_callback) |
| | | |
| | | def __http_request(self, url,callback_info): |
| | | def __http_request(self, url, callback_info): |
| | | try: |
| | | result = network_util.http_get(url) |
| | | print("请求结果:", result) |
| | | self.signal_request.emit(callback_info[0],callback_info[1],result) |
| | | # 代理请求结果 |
| | | result, need_delegate = LocalKanPanNetworkDelegate.http_delegate_request(url) |
| | | if not need_delegate: |
| | | result = network_util.http_get(url) |
| | | print(url, f"请求结果:{len(result.encode('utf-8'))}", result) |
| | | self.signal_request.emit(callback_info[0], callback_info[1], result) |
| | | return result |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | def __socket_request(self, text, callback_info, port=None): |
| | | try: |
| | | print("socket請求:", text) |
| | | if port: |
| | | result = network_util.socket_request(text, port=port) |
| | | else: |
| | | result = network_util.socket_request(text) |
| | | print(f"请求结果:{len(result.encode('utf-8'))}", result) |
| | | self.signal_request.emit(callback_info[0], callback_info[1], result) |
| | | return result |
| | | except Exception as e: |
| | | logging.exception(e) |
| | |
| | | t1.setDaemon(True) |
| | | t1.start() |
| | | |
| | | @pyqtSlot(str, result=str) |
| | | def socket_request(self, text): |
| | | @pyqtSlot(str, str) |
| | | def socket_request(self, text, callback_info): |
| | | print("socket_request", text) |
| | | return network_util.socket_request(json.loads(text)) |
| | | try: |
| | | text_json = json.loads(text) |
| | | params = [] |
| | | for k in text_json: |
| | | if k == "sign": |
| | | continue |
| | | if type(text_json[k]) == dict or type(text_json[k]) == list: |
| | | params.append(f"{k}={json.dumps(text_json[k], separators=(',', ':'))}") |
| | | else: |
| | | params.append(f"{k}={text_json[k]}") |
| | | params.sort() |
| | | params.append("%Yeshi2014@#.") |
| | | params_str = "&".join(params) |
| | | md5 = hashlib.md5() |
| | | md5.update(params_str.encode("utf-8")) |
| | | md5_hash = md5.hexdigest() |
| | | text_json["sign"] = md5_hash |
| | | text = json.dumps(text_json) |
| | | except: |
| | | pass |
| | | callback_info = json.loads(callback_info) |
| | | t1 = threading.Thread(target=lambda: self.__socket_request(text, callback_info)) |
| | | t1.setDaemon(True) |
| | | t1.start() |
| | | |
| | | @pyqtSlot(str, str) |
| | | def ls_socket_request(self, text, callback_info): |
| | | print("ls_socket_request", text) |
| | | try: |
| | | text_json = json.loads(text) |
| | | params = [] |
| | | for k in text_json: |
| | | if k == "sign": |
| | | continue |
| | | if type(text_json[k]) == dict or type(text_json[k]) == list: |
| | | params.append(f"{k}={json.dumps(text_json[k], separators=(',', ':'))}") |
| | | else: |
| | | params.append(f"{k}={text_json[k]}") |
| | | params.sort() |
| | | params.append("%Yeshi2014@#.") |
| | | params_str = "&".join(params) |
| | | md5 = hashlib.md5() |
| | | md5.update(params_str.encode("utf-8")) |
| | | md5_hash = md5.hexdigest() |
| | | text_json["sign"] = md5_hash |
| | | text = json.dumps(text_json) |
| | | except: |
| | | pass |
| | | callback_info = json.loads(callback_info) |
| | | t1 = threading.Thread(target=lambda: self.__socket_request(text, callback_info, port=14008)) |
| | | t1.setDaemon(True) |
| | | t1.start() |
| | | |
| | | # 获取客户端ID |
| | | @pyqtSlot(result=str) |
| | | def get_client(self): |
| | | return setting.get_client() |
| | | |
| | | @pyqtSlot(str) |
| | | def add_code_to_ths(self, code): |
| | | # 添加到同花顺 |
| | | threading.Thread(target=lambda: ths_util.add_code_to_zixuan(code), daemon=True).start() |
| | | |
| | | @pyqtSlot(str) |
| | | def open_webview_window(self, data): |
| | | """ |
| | | 打开独立网页窗口 |
| | | :param data: |
| | | :return: |
| | | """ |
| | | data = json.loads(data) |
| | | url = data.get("url") |
| | | title = data.get("title") |
| | | key = data.get("key") |
| | | size = data.get("size") |
| | | common_window = CommonWindow(title, key, size, parent=self.__webview.window()) |
| | | common_window.loadUrl(url) |
| | | common_window.show() |
| | | |
| | | @pyqtSlot(str) |
| | | def set_target_code(self, code): |
| | | # 设置目标代码 |
| | | window_msg_queue.put_nowait({"type": "set_target_code", "data": {"code": code}}) |
| | | |
| | | |
| | | class SecondWindowBridgeClass(BaseBridgeClass): |
| | | @pyqtSlot(str) |
| | | def set_target_code(self, code): |
| | | # 设置目标代码 |
| | | window_msg_queue.put_nowait({"type": "set_target_code", "data": {"code": code}}) |
| | | |
| | | |
| | | class JSBridgeClass(BaseBridgeClass): |
| | | |
| | | def __init__(self, window, webview): |
| | | super().__init__(webview) |
| | | self.window = window |
| | | self.webview = webview |
| | | |
| | | @pyqtSlot(str) |
| | | def show_info(self, msg): |
| | | QMessageBox.information(self.window, "提示", msg, QMessageBox.Yes) |
| | | |
| | | @pyqtSlot(str, str, str, str) |
| | | def set_trade_info(self, code, name, trade_data, trade_record): |
| | | self.window.set_trade_data(code, name, trade_data, trade_record) |
| | | |
| | | @pyqtSlot(str, str) |
| | | def show_want_codes(self, plate, codes): |
| | | WantBuyWindow(plate, json.loads(codes)).show() |
| | | @pyqtSlot(str, str, str, str, str, str) |
| | | def set_trade_info(self, code, name, trade_data, trade_record, initiative_buy_codes, passive_buy_codes): |
| | | self.window.set_trade_data(code, name, trade_data, trade_record, initiative_buy_codes, passive_buy_codes) |
| | | |
| | | |
| | | class WantBuyWindow(QMainWindow): |
| | | def __init__(self, plate, codes): |
| | | super(WantBuyWindow, self).__init__() |
| | | self.setWindowTitle(f'想买单({plate})') |
| | | self.resize(300, 200) |
| | | class MessageWindow(QMainWindow): |
| | | msgChange = pyqtSignal(str) |
| | | |
| | | def __setMsg(self, msg): |
| | | print("收到信息:", msg) |
| | | palette = QPalette() |
| | | if msg.find("撤单") > -1: |
| | | palette.setColor(QPalette.WindowText, QColor(0, 128, 0)) # 设置字体颜色为绿色 |
| | | elif msg.find("下单") > -1: |
| | | palette.setColor(QPalette.WindowText, QColor(34, 26, 178)) # 设置字体颜色为黄色 |
| | | elif msg.find("成交") > -1: |
| | | palette.setColor(QPalette.WindowText, QColor(255, 0, 0)) # 设置字体颜色为红色 |
| | | self.label.setPalette(palette) |
| | | self.label.setText(msg) |
| | | self.show() |
| | | self.timer.stop() |
| | | self.timer.start(5000) |
| | | |
| | | # 设置信息 |
| | | def setMsg(self, msg): |
| | | # TODO 测试 |
| | | self.msgChange.emit(msg) |
| | | |
| | | def __init__(self): |
| | | super().__init__() |
| | | window_height = 80 |
| | | padding = 10 |
| | | self.resize(300, 50) |
| | | # hwnds = win32_util.search_window("悬浮盯盘", is_one_result=True) |
| | | # if hwnds: |
| | | # rect = win32gui.GetWindowRect(hwnds[0]) |
| | | # self.move(rect[0] + padding - 3, rect[1] - window_height - 30) |
| | | # if rect[2] - rect[0] > 0: |
| | | # self.resize((rect[2] - rect[0]) - (padding - 2) * 2, window_height) |
| | | self.setWindowTitle("消息提示") |
| | | self.setWindowFlag(Qt.WindowStaysOnTopHint, True) |
| | | self.setWindowOpacity(0.9) |
| | | # 去掉标题栏 |
| | | # self.setWindowFlags(Qt.FramelessWindowHint) |
| | | # 删除最大最小化按钮 |
| | | # self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint & ~Qt.WindowMinimizeButtonHint) |
| | | |
| | | font = QFont('微软雅黑', 12) # 设置字体为微软雅黑,字号为12 |
| | | palette = QPalette() # 创建一个调色板 |
| | | palette.setColor(QPalette.WindowText, QColor(255, 0, 0)) # 设置字体颜色为红色 |
| | | |
| | | self.label = QLabel(self) |
| | | self.label.setStyleSheet(f"padding: {padding}px;") |
| | | self.label.setFont(font) |
| | | self.label.setPalette(palette) # 将该调色板应用到QLabel上 |
| | | self.label.setAlignment(Qt.AlignTop) |
| | | self.label.resize(self.width(), self.height()) |
| | | # 设置多行显示 |
| | | self.label.setWordWrap(True) # 设置Label的自动换行 |
| | | |
| | | self.timer = QTimer() |
| | | self.timer.timeout.connect(self.close) |
| | | # 只运行1次定时器 |
| | | self.timer.setSingleShot(True) |
| | | self.msgChange.connect(self.__setMsg) |
| | | |
| | | |
| | | class MsgListWindow(QMainWindow): |
| | | |
| | | def __init__(self): |
| | | super().__init__() |
| | | self.setWindowTitle('历史消息') |
| | | # 窗口置顶 |
| | | self.setWindowFlag(Qt.WindowStaysOnTopHint, True) |
| | | self.resize(500, 800) |
| | | self.webview = QWebEngineView() |
| | | self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True) |
| | | self.webview.page().setZoomFactor(1) |
| | | self.setCentralWidget(self.webview) |
| | | |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = BaseBridgeClass(self.webview) |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | def loadUrl(self, url): |
| | | self.webview.load(QUrl(url)) |
| | | |
| | | |
| | | class SecondWindow(QMainWindow): |
| | |
| | | self.webview.page().setZoomFactor(1) |
| | | self.setCentralWidget(self.webview) |
| | | |
| | | self.signal_update_kpl.connect(self.set_kpl_data) |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = SecondWindowBridgeClass(self.webview) |
| | | |
| | | t1 = threading.Thread(target=self.update_kpl_func) |
| | | t1.setDaemon(True) |
| | | t1.start() |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | # win32gui.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.handleCustomMessage) |
| | | |
| | | # self.signal_update_kpl.connect(self.set_kpl_data) |
| | | |
| | | # t1 = threading.Thread(target=self.update_kpl_func) |
| | | # t1.setDaemon(True) |
| | | # t1.start() |
| | | |
| | | # 自定义消息处理函数 |
| | | def handleCustomMessage(self, hwnd, msg, wparam, lparam): |
| | | if msg == win32con.WM_USER + 1024: |
| | | # 解析数据 |
| | | # try: |
| | | # code = ctypes.cast(lparam, ctypes.py_object).value |
| | | # print(code) |
| | | # except: |
| | | # pass |
| | | pass |
| | | |
| | | # 处理数据 |
| | | # self.dataReceived.emit(intValue, stringValue) |
| | | |
| | | return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) |
| | | |
| | | def loadUrl(self, url): |
| | | self.webview.load(QUrl(url)) |
| | | |
| | | # 设置交易数据 |
| | | def set_trade_data(self, code, code_name, trade_data, trade_record): |
| | | self.webview.page().runJavaScript(f"app.set_trade_info('{code}','{code_name}','{trade_data}','{trade_record}')") |
| | | def set_trade_data(self, code, code_name, trade_data, trade_record, initiative_buy_codes, passive_buy_codes): |
| | | script_str = "try{" |
| | | script_str += "var trade_data = " + trade_data + ";" |
| | | script_str += "var trade_record = " + trade_record + ";" |
| | | |
| | | script_str += "app.set_trade_info(\"{}\",\"{}\",trade_data,trade_record,'{}','{}');".format(code, code_name, |
| | | initiative_buy_codes, |
| | | passive_buy_codes) |
| | | script_str += "} catch(e){console.log(e)}" |
| | | self.webview.page().runJavaScript(script_str) |
| | | |
| | | def set_kpl_data(self, data): |
| | | self.webview.page().runJavaScript(f"fill_kpl_data('{data}')") |
| | |
| | | datas = network_util.http_get("/get_kpl_data") |
| | | self.signal_update_kpl.emit(datas) |
| | | |
| | | def set_target_code(self, code): |
| | | print("set_target_code", code) |
| | | # 测试 |
| | | self.webview.page().runJavaScript(f"app.set_target_code('{code}')") |
| | | |
| | | def closeEvent(self, event): |
| | | try: |
| | | setting.set_kp_second_window_info( |
| | | (self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) |
| | | except Exception as e: |
| | | print("") |
| | | |
| | | |
| | | class DelegatingWindow(QMainWindow): |
| | | """ |
| | | 加贝控制中心 |
| | | """ |
| | | signal_update_kpl = pyqtSignal(str) |
| | | |
| | | def update_kpl_func(self): |
| | | while True: |
| | | time.sleep(3) |
| | | try: |
| | | self.__update_kpl() |
| | | except: |
| | | pass |
| | | |
| | | def __init__(self, parent=None): |
| | | super(DelegatingWindow, self).__init__(parent) |
| | | self.setWindowTitle('加贝控制中心') |
| | | window_info = setting.get_delegating_window_info() |
| | | if window_info: |
| | | self.move(window_info[0], window_info[1]) |
| | | self.resize(window_info[2], window_info[3]) |
| | | else: |
| | | self.resize(600, 800) |
| | | |
| | | self.webview = QWebEngineView() |
| | | self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True) |
| | | self.webview.page().setZoomFactor(1) |
| | | self.setCentralWidget(self.webview) |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = BaseBridgeClass(self.webview) |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | # 自定义消息处理函数 |
| | | def handleCustomMessage(self, hwnd, msg, wparam, lparam): |
| | | if msg == win32con.WM_USER + 1024: |
| | | # 解析数据 |
| | | # try: |
| | | # code = ctypes.cast(lparam, ctypes.py_object).value |
| | | # print(code) |
| | | # except: |
| | | # pass |
| | | pass |
| | | |
| | | # 处理数据 |
| | | # self.dataReceived.emit(intValue, stringValue) |
| | | |
| | | return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) |
| | | |
| | | def loadUrl(self, url): |
| | | self.webview.load(QUrl(url)) |
| | | |
| | | def closeEvent(self, event): |
| | | try: |
| | | setting.set_delegating_window_info( |
| | | (self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) |
| | | except Exception as e: |
| | | print("") |
| | | |
| | | |
| | | class CommonWindow(QMainWindow): |
| | | """ |
| | | 加贝控制中心 |
| | | """ |
| | | signal_update_kpl = pyqtSignal(str) |
| | | |
| | | def update_kpl_func(self): |
| | | while True: |
| | | time.sleep(3) |
| | | try: |
| | | self.__update_kpl() |
| | | except: |
| | | pass |
| | | |
| | | def __init__(self, title, key, default_size, parent=None): |
| | | """ |
| | | :param title: 标题 |
| | | :param key: 标识 |
| | | :param default_size:(宽, 高) |
| | | :param parent: |
| | | """ |
| | | super(CommonWindow, self).__init__(parent) |
| | | self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint) |
| | | |
| | | self.setWindowTitle(title) |
| | | window_info = setting.get_window_info(f"{key}_window_info") |
| | | if window_info: |
| | | self.move(window_info[0], window_info[1]) |
| | | self.resize(window_info[2], window_info[3]) |
| | | else: |
| | | self.resize(default_size[0], default_size[1]) |
| | | self.key = key |
| | | |
| | | self.webview = QWebEngineView() |
| | | self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True) |
| | | self.webview.page().setZoomFactor(1) |
| | | self.setCentralWidget(self.webview) |
| | | |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = BaseBridgeClass(self.webview) |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | # 自定义消息处理函数 |
| | | def handleCustomMessage(self, hwnd, msg, wparam, lparam): |
| | | if msg == win32con.WM_USER + 1024: |
| | | # 解析数据 |
| | | # try: |
| | | # code = ctypes.cast(lparam, ctypes.py_object).value |
| | | # print(code) |
| | | # except: |
| | | # pass |
| | | pass |
| | | |
| | | # 处理数据 |
| | | # self.dataReceived.emit(intValue, stringValue) |
| | | |
| | | return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) |
| | | |
| | | def loadUrl(self, url): |
| | | self.webview.load(QUrl(url)) |
| | | |
| | | def closeEvent(self, event): |
| | | try: |
| | | setting.set_window_info(f"{self.key}_window_info", |
| | | (self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) |
| | | except Exception as e: |
| | | print("") |
| | | # self.webview.close() |
| | | |
| | | |
| | | class WebEnginePage(QWebEnginePage): |
| | | def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID): |
| | | """处理 JavaScript 控制台消息""" |
| | | print(f"JavaScript Console Error: {message} at line {lineNumber} of {sourceID}") |
| | | |
| | | def onLoadFailed(self, errorCode, failingUrl, errorDescription): |
| | | """处理加载失败的情况""" |
| | | print(f"Failed to load URL: {failingUrl}, Error: {errorDescription}, Code: {errorCode}") |
| | | |
| | | |
| | | class MainWindow(QMainWindow): |
| | |
| | | def show_warning(self, msg): |
| | | QMessageBox.warning(self, "提示", msg, QMessageBox.Yes) |
| | | |
| | | def set_trade_data(self, code, code_name, trade_data, trade_record): |
| | | self.secondWindow.set_trade_data(code, code_name, trade_data, trade_record) |
| | | def set_trade_data(self, code, code_name, trade_data, trade_record, initiative_buy_codes, passive_buy_codes): |
| | | self.secondWindow.set_trade_data(code, code_name, trade_data, trade_record, initiative_buy_codes, |
| | | passive_buy_codes) |
| | | |
| | | # 设置目标代码 |
| | | def set_target_code(self, code): |
| | | print("set_target_code") |
| | | self.wx_pipe.send(json.dumps({"type": "set_code", "code": code})) |
| | | self.webview.page().runJavaScript(f"app.set_target_code('{code}')") |
| | | self.secondWindow.set_target_code(code) |
| | | |
| | | def read_window_msg(self): |
| | | while True: |
| | | try: |
| | | data = window_msg_queue.get() |
| | | if data["type"] == "set_target_code": |
| | | code = data["data"]["code"] |
| | | self.signal_update_code.emit(code) |
| | | except: |
| | | pass |
| | | finally: |
| | | pass |
| | | |
| | | # 菜单及菜单点击事件 |
| | | def __menu(self): |
| | |
| | | ps = (self.x(), self.y()) |
| | | size = (self.width(), self.height()) |
| | | self.wx_pipe.send(json.dumps({"type": "juejin_setting", "pos": (ps[0] + size[0] / 2, ps[1] + size[1] / 2)})) |
| | | |
| | | def __juejin_tick_download(): |
| | | self.wx_pipe.send(json.dumps({"type": "juejin_tick_download"})) |
| | | |
| | | def __ths_ocr_code(): |
| | | try: |
| | | code = ths_ocr_util.ocr_ths_code(always_save=True) |
| | | self.show_info(f"识别到的代码:{code}") |
| | | except Exception as e: |
| | | self.show_warning(f"识别出错:{str(e)}") |
| | | |
| | | def __download_codes(): |
| | | try: |
| | |
| | | size = (self.width(), self.height()) |
| | | self.wx_pipe.send(json.dumps({"type": "codes_setting", "pos": (ps[0] + size[0] / 2, ps[1] + size[1] / 2)})) |
| | | |
| | | def __show_dead_hwnds(): |
| | | self.wx_pipe.send(json.dumps({"type": "show_dead_hwnds"})) |
| | | |
| | | def __manage_ths_pos(): |
| | | ps = (self.x(), self.y()) |
| | | size = (self.width(), self.height()) |
| | | self.wx_pipe.send(json.dumps({"type": "manage_ths_pos", "pos": (ps[0] + size[0] / 2, ps[1] + size[1] / 2)})) |
| | | |
| | | def __show_float_callback(): |
| | | self.wx_pipe.send(json.dumps({"type": "show_float_callback"})) |
| | | |
| | | def __show_main_callback(): |
| | | self.wx_pipe.send(json.dumps({"type": "show_main_callback"})) |
| | | |
| | | def __show_second_window(): |
| | | self.secondWindow.show() |
| | | |
| | | def __show_delegating_window(): |
| | | self.delegatingWindow.show() |
| | | |
| | | def __show_want_buy_codes_window(): |
| | | self.wantBuyCodesWindow.show() |
| | | |
| | | def __show_his_msg_window(): |
| | | self.msgListWindow.loadUrl(URL_MSG_LIST) |
| | | self.msgListWindow.show() |
| | | |
| | | # 清除浏览器缓存 |
| | | def __clear_webview_cache(): |
| | | self.webview.page().profile().clearHttpCache() |
| | | |
| | | def __show_ths_flash_trade(): |
| | | hwnds = ths_util.get_flash_trade_hwnds() |
| | | for hwnd in hwnds: |
| | | if not win32gui.IsWindowVisible(hwnd): |
| | | win32gui.BringWindowToTop(hwnd) |
| | | win32_util.move_window(hwnd, 0, 0) |
| | | |
| | | menubar = self.menuBar() |
| | | |
| | | setting_ = menubar.addMenu('&设置') |
| | | |
| | | juejin_action = QAction("&掘金参数配置", self) |
| | | juejin_action.triggered.connect(__set_juejin_params) |
| | | setting_.addAction(juejin_action) |
| | | |
| | | action = QAction("&代码管理", self) |
| | | action.triggered.connect(__manage_code) |
| | | setting_.addAction(action) |
| | | |
| | | action = QAction("&下载涨停代码", self) |
| | | action.triggered.connect(__download_codes) |
| | | setting_.addAction(action) |
| | | |
| | | action = QAction("&GPU检测", self) |
| | | action.triggered.connect(__gpu_is_avaiable) |
| | | setting_.addAction(action) |
| | | |
| | | auto_ = menubar.addMenu('&自动化') |
| | | action = QAction("&同花顺设置", self) |
| | | action.triggered.connect(__manage_ths_pos) |
| | | auto_.addAction(action) |
| | | action = QAction("&清除浏览器缓存", self) |
| | | action.triggered.connect(__clear_webview_cache) |
| | | setting_.addAction(action) |
| | | |
| | | action = QAction("&同花顺代码识别", self) |
| | | action.triggered.connect(__ths_ocr_code) |
| | | setting_.addAction(action) |
| | | |
| | | action = QAction("&死句柄管理", self) |
| | | action.triggered.connect(__show_dead_hwnds) |
| | | setting_.addAction(action) |
| | | |
| | | view_ = menubar.addMenu('&视图') |
| | | action = QAction("&打开副屏", self) |
| | | action.triggered.connect(__show_second_window) |
| | | view_.addAction(action) |
| | | |
| | | action = QAction("&打开悬浮盯盘", self) |
| | | action.triggered.connect(__show_float_callback) |
| | | action = QAction("&打开加贝控制中心", self) |
| | | action.triggered.connect(__show_delegating_window) |
| | | view_.addAction(action) |
| | | |
| | | action = QAction("&打开分时看盘", self) |
| | | action.triggered.connect(__show_main_callback) |
| | | action = QAction("&打开想买单", self) |
| | | action.triggered.connect(__show_want_buy_codes_window) |
| | | view_.addAction(action) |
| | | |
| | | action = QAction("&打开历史消息", self) |
| | | action.triggered.connect(__show_his_msg_window) |
| | | view_.addAction(action) |
| | | |
| | | view_ = menubar.addMenu('&显示一键卖出') |
| | | view_.aboutToShow.connect(__show_ths_flash_trade) |
| | | |
| | | def __init__(self, wx_pipe): |
| | | super().__init__() |
| | |
| | | else: |
| | | self.resize(1100, 1000) |
| | | self.center() |
| | | self.setWindowFlag(Qt.WindowStaysOnTopHint, True) |
| | | self.webview = QWebEngineView() |
| | | self.webview.setPage(WebEnginePage()) |
| | | self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True) |
| | | self.__menu() |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = JSBridgeClass(self,self.webview) |
| | | self.python_bridge = JSBridgeClass(self, self.webview) |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | # 设置副屏 |
| | | self.secondWindow = SecondWindow(self) |
| | | self.delegatingWindow = DelegatingWindow(self) |
| | | self.wantBuyCodesWindow = CommonWindow("想买单", "want_buy_codes", (500, 1000), parent=self) |
| | | |
| | | self.setCentralWidget(self.webview) |
| | | self.show() |
| | | self.webview.load(QUrl("http://192.168.3.122:8848/kp/index23-05-04.html")) |
| | | if not constant.IS_TEST: |
| | | self.webview.load(QUrl(f"http://{constant.WEB_HOST}/kp/index23-05-04.html")) |
| | | else: |
| | | self.webview.load(QUrl("http://127.0.0.1:8848/kp/index23-05-04.html")) |
| | | |
| | | self.secondWindow.show() |
| | | self.secondWindow.loadUrl("http://192.168.3.122:8848/kp/banshuping.html") |
| | | if not setting.is_only_convertible_bonds(): |
| | | self.secondWindow.show() |
| | | if not constant.IS_TEST: |
| | | self.secondWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/codes_list.html") |
| | | else: |
| | | self.secondWindow.loadUrl("http://127.0.0.1:8848/kp/codes_list.html") |
| | | |
| | | self.delegatingWindow.show() |
| | | if not constant.IS_TEST: |
| | | self.delegatingWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/delegating_list.html") |
| | | else: |
| | | self.delegatingWindow.loadUrl("http://127.0.0.1:8848/kp/delegating_list.html") |
| | | |
| | | if not constant.IS_TEST: |
| | | self.wantBuyCodesWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/want_buy_codes_list.html") |
| | | else: |
| | | self.wantBuyCodesWindow.loadUrl("http://127.0.0.1:8848/kp/want_buy_codes_list.html") |
| | | |
| | | self.wantBuyCodesWindow.show() |
| | | |
| | | # 绑定槽函数 |
| | | self.signal_update_code.connect(self.set_target_code) |
| | | # self.statusBar().showMessage("这是条测试数据额", 10000) |
| | | |
| | | self.messageWindow = MessageWindow() |
| | | self.msgListWindow = MsgListWindow() |
| | | |
| | | threading.Thread(target=KPLLimitUpDataManager().run, daemon=True).start() |
| | | threading.Thread(target=xgb_api.run, daemon=True).start() |
| | | threading.Thread(target=self.read_window_msg, daemon=True).start() |
| | | |
| | | def closeEvent(self, event): |
| | | event.accept() |
| | |
| | | except Exception as e: |
| | | print("") |
| | | self.wx_pipe.send(json.dumps({"type": "exit"})) |
| | | wxGuiProcess.terminate() |
| | | wxGuiProcess.join() |
| | | sys.exit(0) |
| | | |
| | | |
| | | # 打包命令 |
| | | # cd D:\workspace\GP\trade_desk |
| | | # D:\workspace\GP\trade_desk\dist\env\pk_env\Scripts\pyinstaller.exe main.spec |
| | | # 读取消息 |
| | | def read_msg(self): |
| | | client = setting.get_client() |
| | | if not client: |
| | | client = 'hxh' |
| | | while True: |
| | | if tool.is_trade_time(): |
| | | try: |
| | | res = network_util.http_get(f"/pull_kp_client_msg?client=" + client.strip()) |
| | | if res: |
| | | res = json.loads(res) |
| | | if res["code"] == 0: |
| | | print("拉取到消息", res) |
| | | self.messageWindow.setMsg(res["data"]) |
| | | except: |
| | | pass |
| | | time.sleep(0.5) |
| | | |
| | | |
| | | def recieve_code(pipe, mainWindow): |
| | |
| | | logging.exception(e) |
| | | |
| | | |
| | | # 打包命令 |
| | | # cd D:\workspace\GP\trade_desk |
| | | # D:\workspace\GP\trade_desk\dist\env\pk_env\Scripts\pyinstaller.exe main.spec |
| | | # 为了不出现意外的bug,运行时请将目录放在英文路径 |
| | | |
| | | if __name__ == "__main__": |
| | | freeze_support() |
| | | p1, p2 = multiprocessing.Pipe() |
| | | wxGuiProcess = multiprocessing.Process(target=gui_wx.run, args=(p1,)) |
| | | global wxGuiProcess |
| | | wxGuiProcess = Process(target=gui_wx.run, args=(p1,)) |
| | | wxGuiProcess.start() |
| | | |
| | | app = QApplication(sys.argv) |