admin
10 天以前 ec060ce444cdd1c48a54686cadbc8950478eedcf
main.py
@@ -1,42 +1,75 @@
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)
@@ -53,29 +86,200 @@
        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):
@@ -104,18 +308,51 @@
        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}')")
@@ -125,12 +362,160 @@
        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):
@@ -142,13 +527,28 @@
    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):
@@ -162,6 +562,16 @@
            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:
@@ -188,57 +598,77 @@
            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__()
@@ -251,26 +681,58 @@
        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()
@@ -279,12 +741,27 @@
        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):
@@ -302,9 +779,16 @@
            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)