From ec060ce444cdd1c48a54686cadbc8950478eedcf Mon Sep 17 00:00:00 2001 From: admin <weikou2014> Date: 星期五, 22 八月 2025 16:27:34 +0800 Subject: [PATCH] 网页内容修改 --- main.py | 1965 +++++++++++++++++++++++------------------------------------ 1 files changed, 759 insertions(+), 1,206 deletions(-) diff --git a/main.py b/main.py index 00c292f..ddc3348 100644 --- a/main.py +++ b/main.py @@ -1,1247 +1,800 @@ +import base64 +import ctypes +import hashlib import json -import socket -import sys -import time -from multiprocessing import freeze_support - -import win32con -import win32gui - -import ocr_util -import opencv_util -import setting -import ths_util -import win32_util - -freeze_support() import logging import multiprocessing +import queue import threading +import time +import sys +from functools import partial +from multiprocessing import Pipe, Process, freeze_support -import matplotlib.pyplot as plt -from matplotlib.widgets import Button +import torch +import win32api +import win32con +import win32gui +from PyQt5.QtGui import QFont, QPalette, QColor, QTextOption -import wx -from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas -from matplotlib.figure import Figure +from PyQt5.QtWebChannel import QWebChannel +from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings, QWebEnginePage +from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QMessageBox, QLabel -import code_data_manager -import juejin_core -import tool -import dateutil +from PyQt5.QtCore import Qt, pyqtSlot, QObject, pyqtSignal, QTimer, QUrl, QPoint -APP_TITLE = "鍗栫エ鐪嬫澘" -APP_ICON = "" +import constant +import gui_wx +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 + +URL_MSG_LIST = f"http://{constant.WEB_HOST}/kp/msg_list.html" + +window_msg_queue = queue.Queue() -def show_warning(content, click): - toastone = wx.MessageDialog(None, content, "鎻愮ず", wx.YES_DEFAULT | wx.ICON_WARNING) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - if click is not None: - click() - toastone.Destroy() +class BaseBridgeClass(QObject): + signal_request = pyqtSignal(str, str, str) + def __request_result_callback(self, method, key, result): + base64_str = base64.b64encode(result.encode('utf-8')).decode('utf-8') + self.__webview.page().runJavaScript(f"{method}('{key}','{base64_str}')") -def show_info(content, click): - toastone = wx.MessageDialog(None, content, "鎻愮ず", wx.YES_DEFAULT | wx.ICON_INFORMATION) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - click() - toastone.Destroy() + def __init__(self, webview): + super().__init__() + self.__webview = webview + self.signal_request.connect(self.__request_result_callback) - -class JueJinSettingFrame(wx.Frame): - def __init__(self, position): - wx.Frame.__init__(self, None, -1, "鎺橀噾鍙傛暟璁剧疆", style=wx.SYSTEM_MENU ^ wx.CLOSE_BOX ^ wx.CAPTION ^ wx.STAY_ON_TOP, - size=(450, 200)) - - self.SetBackgroundColour(wx.Colour(224, 224, 224)) - self.SetPosition(wx.Point(position[0] - self.GetSize()[0] / 2, position[1] - self.GetSize()[1] / 2)) - boxsier = wx.BoxSizer() - flex = wx.FlexGridSizer(rows=3, cols=2, vgap=10, hgap=10) - # 绛栫暐 - label = wx.StaticText(self, label="绛栫暐ID锛�") - flex.Add(label, flag=wx.ALIGN_RIGHT) - self.edit_celue = wx.TextCtrl(self, size=(300, -1)) - flex.Add(self.edit_celue, flag=wx.EXPAND) - - # token - label = wx.StaticText(self, label="Token锛�") - flex.Add(label) - self.edit_token = wx.TextCtrl(self, size=(300, -1), style=wx.TE_MULTILINE) - flex.Add(self.edit_token) - - # 鍗犱綅 - flex.Add(wx.StaticText(self, label="")) - # 纭畾鎸夐挳 - ID_SURE = wx.NewId() - self.btn_sure = wx.Button(self, label='纭畾', id=ID_SURE) - self.btn_sure.Bind(wx.EVT_BUTTON, self.__sure_btn) - flex.Add(self.btn_sure, 1, wx.TOP | wx.LEFT, 20) - - boxsier.Add(flex, 1, wx.TOP | wx.LEFT, 20) - self.SetSizer(boxsier) - - # 鍒濆鍖栨暟鎹� - self.__init_data() - - def __init_data(self): - strategy_id, token = setting.get_juejin_params() - self.edit_celue.SetLabelText(strategy_id) - self.edit_token.SetLabelText(token) - pass - - def __sure_btn(self, event): - strategy_id = self.edit_celue.GetValue() - token = self.edit_token.GetValue() - setting.set_juejin_params(strategy_id, token) - toastone = wx.MessageDialog(None, "鏇存敼鎴愬姛", "鎻愮ず", wx.YES_DEFAULT | wx.ICON_INFORMATION) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - self.Close() - toastone.Destroy() - - -class CodesSettingFrame(wx.Frame): - def __init__(self, position, callback): - wx.Frame.__init__(self, None, -1, "浠g爜璁剧疆", style=wx.SYSTEM_MENU ^ wx.CLOSE_BOX ^ wx.CAPTION ^ wx.STAY_ON_TOP, - size=(170, 300)) - self.SetBackgroundColour(wx.Colour(224, 224, 224)) - self.SetPosition(wx.Point(position[0] - self.GetSize()[0] / 2, position[1] - self.GetSize()[1] / 2)) - boxsier = wx.BoxSizer(wx.VERTICAL) - # 浠g爜 - label = wx.StaticText(self, label="鐩爣浠g爜锛�") - boxsier.Add(label) - self.edit_codes = wx.TextCtrl(self, size=(150, 200), style=wx.TE_MULTILINE) - boxsier.Add(self.edit_codes) - - # 纭畾鎸夐挳 - ID_SURE = wx.NewId() - self.btn_sure = wx.Button(self, label='纭畾', id=ID_SURE) - self.btn_sure.Bind(wx.EVT_BUTTON, self.__sure_btn) - boxsier.Add(self.btn_sure) - root_boxsier = wx.BoxSizer(wx.HORIZONTAL) - root_boxsier.Add(boxsier, 1, wx.TOP | wx.TOP, 10) - self.SetSizer(root_boxsier) - - # 鍒濆鍖栨暟鎹� - self.__init_data() - self.callback = callback - - def __init_data(self): - codes = juejin_core.GPCodeManager().get_codes() - self.edit_codes.SetValue("\n".join(codes)) - pass - - def __sure_btn(self, event): - codes_str = self.edit_codes.GetValue() - codes = codes_str.split("\n") - codes_result = [] - for code in codes: - if code.strip(): - codes_result.append(code.strip()) - juejin_core.GPCodeManager().set_codes(codes_result) - # 閲嶆柊璁㈤槄 - self.callback() - toastone = wx.MessageDialog(None, "鏇存敼鎴愬姛", "鎻愮ず", wx.YES_DEFAULT | wx.ICON_INFORMATION) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - self.Close() - toastone.Destroy() - - -class FobiddenCodesFrame(wx.Frame): - def __init__(self, position): - wx.Frame.__init__(self, None, -1, "娣诲姞绂佹浜ゆ槗浠g爜", style=wx.SYSTEM_MENU ^ wx.CLOSE_BOX ^ wx.CAPTION ^ wx.STAY_ON_TOP, - size=(170, 200)) - self.SetBackgroundColour(wx.Colour(224, 224, 224)) - self.SetPosition(wx.Point(position[0] - self.GetSize()[0] / 2, position[1] - self.GetSize()[1] / 2)) - boxsier = wx.BoxSizer(wx.VERTICAL) - # 浠g爜 - label = wx.StaticText(self, label="浠g爜锛�") - boxsier.Add(label, flag=wx.ALIGN_LEFT, border=10) - self.edit_codes = wx.TextCtrl(self, size=(150, 100), style=wx.TE_MULTILINE) - boxsier.Add(self.edit_codes) - - # 纭畾鎸夐挳 - ID_SURE = wx.NewId() - self.btn_sure = wx.Button(self, label='纭畾', id=ID_SURE) - self.btn_sure.Bind(wx.EVT_BUTTON, self.__sure_btn) - boxsier.Add(self.btn_sure) - root_boxsier = wx.BoxSizer(wx.HORIZONTAL) - root_boxsier.Add(boxsier, 1, wx.TOP | wx.TOP, 10) - self.SetSizer(root_boxsier) - - def __request(self, codes): - client = socket.socket() # 鐢熸垚socket锛岃繛鎺erver - ip_port = ("192.168.3.252", 9001) # server鍦板潃鍜岀鍙e彿锛堟渶濂芥槸10000浠ュ悗锛� - client.connect(ip_port) - data = {"type": 201, "data": {"codes": codes}} - client.send(json.dumps(data).encode("utf-8")) - client.close() - - def __sure_btn(self, event): - codes_str = self.edit_codes.GetValue() - if codes_str: - codes_str = codes_str.strip() - - codes = codes_str.split("\n") - codes_result = [] - for code in codes: - if code.strip() and len(code.strip()) == 6: - codes_result.append(code.strip()) - if len(codes_result) == 0: - show_warning("璇峰~鍐欐纭殑浠g爜锛�", self.Close) - return + def __http_request(self, url, callback_info): try: - self.__request(codes_result) + # 浠g悊璇锋眰缁撴灉 + 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: - show_warning("娣诲姞鍑洪敊锛�" + str(e), None) - return + logging.exception(e) - toastone = wx.MessageDialog(None, "娣诲姞鎴愬姛", "鎻愮ず", wx.YES_DEFAULT | wx.ICON_INFORMATION) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - self.Close() - toastone.Destroy() - - -class THSPositionSettingFrame(wx.Frame): - def __init__(self, position): - wx.Frame.__init__(self, None, -1, "鍚岃姳椤哄潗鏍囪缃�", style=wx.SYSTEM_MENU ^ wx.CLOSE_BOX ^ wx.CAPTION ^ wx.STAY_ON_TOP, - size=(170, 400)) - self.SetBackgroundColour(wx.Colour(224, 224, 224)) - self.SetPosition(wx.Point(position[0] - self.GetSize()[0] / 2, position[1] - self.GetSize()[1] / 2)) - boxsier = wx.BoxSizer(wx.VERTICAL) - - label = wx.StaticText(self, label="浜ゆ槗鍒锋柊浜嬩欢闂撮殧(ms)锛�") - boxsier.Add(label) - self.edit_refresh_time_space = wx.TextCtrl(self, size=(150, -1)) - boxsier.Add(self.edit_refresh_time_space) - - label = wx.StaticText(self, label="鐐瑰嚮鏃堕棿闂撮殧(ms)锛�") - boxsier.Add(label) - self.edit_time_space = wx.TextCtrl(self, size=(150, -1)) - boxsier.Add(self.edit_time_space) - - # 浠g爜 - label = wx.StaticText(self, label="鍧愭爣锛�") - boxsier.Add(label) - self.edit_codes = wx.TextCtrl(self, size=(150, 200), style=wx.TE_MULTILINE) - boxsier.Add(self.edit_codes) - - # 纭畾鎸夐挳 - ID_SURE = wx.NewId() - self.btn_sure = wx.Button(self, label='纭畾', id=ID_SURE) - self.btn_sure.Bind(wx.EVT_BUTTON, self.__sure_btn) - boxsier.Add(self.btn_sure) - root_boxsier = wx.BoxSizer(wx.HORIZONTAL) - root_boxsier.Add(boxsier, 1, wx.TOP | wx.TOP, 10) - self.SetSizer(root_boxsier) - - # 鍒濆鍖栨暟鎹� - self.__init_data() - - def __init_data(self): - pos = setting.get_ths_auto_click_positions() - self.edit_codes.SetValue("\n".join(pos)) - space = setting.get_ths_auto_click_time_space() - if space is None: - space = 500 - self.edit_time_space.SetValue(f"{space}") - - space = setting.get_ths_auto_refresh_time_space() - if space is None: - space = 500 - self.edit_refresh_time_space.SetValue(f"{space}") - - def __sure_btn(self, event): - codes_str = self.edit_codes.GetValue() - ps = codes_str.split("\n") - result = [] - for p in ps: - if p.strip(): - result.append(p.strip()) - setting.set_ths_auto_click_positions(result) - - time_space = self.edit_time_space.GetValue() - if len(time_space) == 0: - show_warning("鐐瑰嚮鏃堕棿闂撮殧涓嶆纭�", None) - return - - refresh_time_space = self.edit_refresh_time_space.GetValue() - if len(refresh_time_space) == 0: - show_warning("鍒锋柊鏃堕棿闂撮殧涓嶆纭�", None) - return - - setting.set_ths_auto_click_time_space(time_space) - setting.set_ths_auto_refresh_time_space(refresh_time_space) - - toastone = wx.MessageDialog(None, "鏇存敼鎴愬姛", "鎻愮ず", wx.YES_DEFAULT | wx.ICON_INFORMATION) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - self.Close() - toastone.Destroy() - - -def ocr_ths_code(): - hwnd = ths_util.get_ths_main_content_hwnd() - if not hwnd: - raise Exception("鐪嬬洏椤甸潰鍙ユ焺鏈幏鍙栧埌") - # 鍙ユ焺鎴浘 - rect = win32gui.GetWindowRect(hwnd) - # hwnd_width = (rect[2] - rect[0]) * 15 // 10 - rect_ = setting.get_ths_auto_code_rect() - img = win32_util.window_capture(hwnd, (0, rect_[0], rect_[1], rect_[0] + rect_[2])) - code = ocr_util.recognize_code(opencv_util.clip_ths_code_area(img)) - return code - - -# 鎮诞妗� -class FloatFrame(wx.Frame): - def __init__(self, position): - wx.Frame.__init__(self, None, -1, "鎮诞鐩洏", style=wx.CAPTION ^ wx.STAY_ON_TOP, - size=(320, 195)) - self.SetBackgroundColour(wx.Colour(224, 224, 224)) - self.SetTransparent(230) - if position: - self.SetPosition(wx.Point(position[0], position[1])) - boxsier = wx.FlexGridSizer(5, 2, 2, 20) - - self.btn_remove_black = wx.Button(self, label="绉婚櫎榛戝悕鍗�", size=(70, 30)) - boxsier.Add(self.btn_remove_black, 0, wx.TOP, 5) - - bs1 = wx.BoxSizer(wx.HORIZONTAL) - - self.btn_remove_white = wx.Button(self, label="绉婚櫎鐧藉悕鍗�", size=(70, 30)) - bs1.Add(self.btn_remove_white, 0, wx.TOP, 5) - boxsier.Add(bs1, 0, wx.LEFT, 80) - - label = wx.StaticText(self, label="浜ゆ槗鍒锋柊锛�") - bs1 = wx.BoxSizer(wx.HORIZONTAL) - bs1.Add(label) - self.check_auto_refresh = wx.CheckBox(self, size=(-1, -1)) - bs1.Add(self.check_auto_refresh, 0, wx.LEFT, 10) - boxsier.Add(bs1, 0, wx.TOP, 5) - - bs1 = wx.BoxSizer(wx.HORIZONTAL) - self.want_list = wx.Button(self, label="鎯充拱鍗�", size=(45, 20)) - bs1.Add(self.want_list, 0, wx.TOP, 2) - self.btn_want_buy = wx.Button(self, label="鍔犲叆鎯充拱鍗�", size=(70, 25)) - bs1.Add(self.btn_want_buy) - - boxsier.Add(bs1, 0, wx.LEFT, 35) - - label = wx.StaticText(self, label="鍒嗙粍鍒锋柊锛�") - bs1 = wx.BoxSizer(wx.HORIZONTAL) - bs1.Add(label) - self.check_auto_click = wx.CheckBox(self, size=(-1, -1)) - bs1.Add(self.check_auto_click, 0, wx.LEFT, 10) - boxsier.Add(bs1) - - self.btn_want_buy_remove = wx.Button(self, label="绉婚櫎鎯充拱鍗�", size=(70, 25)) - boxsier.Add(self.btn_want_buy_remove, 0, wx.LEFT, 80) - - self.edit_code = wx.TextCtrl(self, size=(80, -1)) - boxsier.Add(self.edit_code) - - self.notify_text = wx.StaticText(self, label="", size=(80, -1)) - boxsier.Add(self.notify_text) - - # 浠g爜 - bs1 = wx.BoxSizer(wx.HORIZONTAL) - self.btn_black = wx.Button(self, label="鍔犲叆榛戝悕鍗�", size=(70, 30)) - bs1.Add(self.btn_black) - self.black_list = wx.Button(self, label="榛戝悕鍗�", size=(45, 20)) - self.black_list.SetForegroundColour("#00e600") - bs1.Add(self.black_list, 0, wx.CENTER | wx.ALL, 0) - boxsier.Add(bs1, 0, wx.LEFT, 0) - - bs1 = wx.BoxSizer(wx.HORIZONTAL) - self.btn_white = wx.Button(self, label="鍔犲叆鐧藉悕鍗�", size=(70, 30)) - self.white_list = wx.Button(self, label="鐧藉悕鍗�", size=(45, 20)) - self.white_list.SetForegroundColour("#FF3232") - bs1.Add(self.white_list, 0, wx.CENTER | wx.ALL, 0) - bs1.Add(self.btn_white, 0, wx.LEFT, 2) - - boxsier.Add(bs1, 0, wx.LEFT, 32) - - # 缁戝畾 - self.btn_black.Bind(wx.EVT_BUTTON, self.add_black) - self.btn_white.Bind(wx.EVT_BUTTON, self.add_white) - self.btn_remove_black.Bind(wx.EVT_BUTTON, self.remove_from_black) - self.btn_remove_white.Bind(wx.EVT_BUTTON, self.remove_from_white) - - self.btn_want_buy.Bind(wx.EVT_BUTTON, self.add_want) - self.btn_want_buy_remove.Bind(wx.EVT_BUTTON, self.remove_from_want) - - self.check_auto_click.Bind(wx.EVT_CHECKBOX, self.__auto_click_check) - self.check_auto_refresh.Bind(wx.EVT_CHECKBOX, self.__auto_refresh_check) - self.white_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "鐧藉悕鍗曞垪琛�", 302)) - self.black_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "榛戝悕鍗曞垪琛�", 301)) - self.want_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "鎯宠涔板垪琛�", 403)) - - root_boxsier = wx.BoxSizer(wx.HORIZONTAL) - root_boxsier.Add(boxsier, 1, wx.LEFT, 10) - self.SetSizer(root_boxsier) - - self.__bind_hot_keys() - # 鍒濆鍖栨暟鎹� - self.__init_data() - - self.timer = wx.Timer(self) # 鍒涘缓瀹氭椂鍣� - self.Bind(wx.EVT_TIMER, self.clear_msg, self.timer) - - def clear_msg(self, event): - self.notify_text.SetLabelText("") - - def __ocr_code(self): - code = self.edit_code.GetValue() - if code is not None and len(code.strip()) == 0: - code = None - if code is not None: - if len(code) != 6: - self.show_warning("璇峰~鍐欐纭殑浠g爜") - return + def __socket_request(self, text, callback_info, port=None): + try: + print("socket璜嬫眰锛�", text) + if port: + result = network_util.socket_request(text, port=port) else: - return - - code = ocr_ths_code() - if code is None: - raise Exception("浠g爜璇嗗埆鍑洪敊") - self.edit_code.SetValue(code) - - def show_warning(self, content): - self.notify_text.SetLabel(content) - self.notify_text.SetForegroundColour("#FF7F27") - self.timer.Stop() - self.timer.StartOnce(20000) - - def show_info(self, content): - self.notify_text.SetLabel(content) - self.notify_text.SetForegroundColour("#008000") - self.timer.Stop() - self.timer.StartOnce(20000) - - def __get_code(self): - self.__ocr_code() - code = self.edit_code.GetValue() - if code is None or len(code) != 6: - raise Exception("璇峰~鍐欐纭殑浠g爜") - return code - - def add_black(self, event): - try: - code = self.__get_code() - print("鍔犲叆榛戝悕鍗�", code) - self.__request([code], 201) - self.show_info(f"{code}鍔犲叆榛戝悕鍗曟垚鍔�") - self.edit_code.SetValue("") + 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: - self.show_warning(str(e)) - return + logging.exception(e) - def add_white(self, event): - try: - code = self.__get_code() - print("鍔犲叆鐧藉悕鍗�", code) - self.__request([code], 202) - self.show_info(f"{code}鍔犲叆鐧藉悕鍗曟垚鍔�") - self.edit_code.SetValue("") - except Exception as e: - self.show_warning(str(e)) - return - - def add_want(self, event): - try: - code = self.__get_code() - print("鍔犲叆鎯宠涔�", code) - self.__request([code], 401) - self.show_info(f"{code}鍔犲叆鎯宠涔板悕鍗曟垚鍔�") - self.edit_code.SetValue("") - except Exception as e: - self.show_warning(str(e)) - return - - def remove_from_black(self, event): - try: - code = self.__get_code() - print("绉婚櫎榛戝悕鍗�", code) - self.__request([code], 203) - self.show_info(f"{code}绉婚櫎榛戝悕鍗曟垚鍔�") - self.edit_code.SetValue("") - except Exception as e: - self.show_warning(str(e)) - return - - def remove_from_white(self, event): - try: - code = self.__get_code() - print("绉婚櫎鐧藉悕鍗�", code) - self.__request([code], 204) - self.show_info(f"{code}绉婚櫎鐧藉悕鍗曟垚鍔�") - self.edit_code.SetValue("") - except Exception as e: - self.show_warning(str(e)) - return - - def remove_from_want(self, event): - try: - code = self.__get_code() - print("绉婚櫎鎯宠涔板悕鍗�", code) - self.__request([code], 402) - self.show_info(f"{code}绉婚櫎鎯宠涔板悕鍗曟垚鍔�") - self.edit_code.SetValue("") - except Exception as e: - self.show_warning(str(e)) - return - - def show_list(self, event, title, type): - try: - result = self.__request_list(type) - result = json.loads(result) - self.__show_list(title, result["data"]) - except Exception as e: - show_warning(str(e), None) - - def __show_list(self, title, datas): - st = "" - for i in range(0, len(datas)): - st += datas[i] - if i % 2 == 1 and i != len(datas) - 1: - st += "\n" - elif i != len(datas) - 1: - st += " , " - - toastone = wx.MessageDialog(None, st, title) - if toastone.ShowModal() == wx.ID_YES: # 濡傛灉鐐瑰嚮浜嗘彁绀烘鐨勭‘瀹氭寜閽� - toastone.Destroy() - - def __bind_hot_keys(self): - # 蹇嵎閿� - setting_ = wx.Menu() - m_black = wx.MenuItem(setting_, id=101, text='&E', kind=wx.ITEM_NORMAL) - m_white = wx.MenuItem(setting_, id=102, text='&E', kind=wx.ITEM_NORMAL) - self.Bind(wx.EVT_MENU, self.add_black, m_black) - self.Bind(wx.EVT_MENU, self.add_white, m_white) - entries = [wx.AcceleratorEntry() for i in range(2)] - entries[0].Set(wx.ACCEL_CTRL, wx.WXK_F4, 101) - entries[1].Set(wx.ACCEL_CTRL, wx.WXK_F5, 102) - accel = wx.AcceleratorTable(entries) - self.SetAcceleratorTable(accel) - - def __init_data(self): - auto_click = setting.is_ths_auto_click() - if auto_click: - self.check_auto_click.SetValue(True) - else: - self.check_auto_click.SetValue(False) - - auto_refresh = setting.is_ths_trade_auto_refresh() - if auto_refresh: - self.check_auto_refresh.SetValue(True) - else: - self.check_auto_refresh.SetValue(False) - - def __auto_click_check(self, event): - if event.Selection: - setting.set_ths_auto_click(True) - else: - setting.set_ths_auto_click(False) - - def __auto_refresh_check(self, event): - if event.Selection: - setting.set_ths_trade_auto_refresh(True) - else: - setting.set_ths_trade_auto_refresh(False) - - def __request(self, codes, type): - client = socket.socket() # 鐢熸垚socket锛岃繛鎺erver - ip_port = ("192.168.3.252", 9001) # server鍦板潃鍜岀鍙e彿锛堟渶濂芥槸10000浠ュ悗锛� - client.connect(ip_port) - data = {"type": type, "data": {"codes": codes}} - client.send(json.dumps(data).encode("utf-8")) - client.close() - - def __request_list(self, type): - client = socket.socket() # 鐢熸垚socket锛岃繛鎺erver - ip_port = ("192.168.3.252", 9001) # server鍦板潃鍜岀鍙e彿锛堟渶濂芥槸10000浠ュ悗锛� - client.connect(ip_port) - data = {"type": type, "data": {}} - client.send(json.dumps(data).encode("utf-8")) - # 璇诲彇鍐呭 - result = client.recv(10240) - client.close() - return result.decode("gbk") - - -class mainFrame(wx.Frame): - def __init__(self): - '''鏋勯�犲嚱鏁�''' - wx.Frame.__init__(self, None, -1, APP_TITLE, style=wx.DEFAULT_FRAME_STYLE, - size=(800, 500)) - # ^ wx.RESIZE_BORDER ^ wx.STAY_ON_TOP - # 榛樿style鏄笅鍒楅」鐨勭粍鍚堬細wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN - self.SetBackgroundColour(wx.Colour(0, 0, 0)) - self.Center() - self.__menu() - # 浠ヤ笅浠g爜澶勭悊鍥炬爣 - # if hasattr(sys, "frozen") and getattr(sys, "frozen") == "windows_exe": - # exeName = win32api.GetModuleFileName(win32api.GetModuleHandle(None)) - # icon = wx.Icon(exeName, wx.BITMAP_TYPE_ICO) - # else: - # icon = wx.Icon(APP_ICON, wx.BITMAP_TYPE_ICO) - # self.SetIcon(icon) - # 瀹氫箟绐楀彛鍏抽棴 - self.Bind(wx.EVT_CLOSE, self.OnExit) - self.Bind(wx.EVT_SIZE, self.OnResize) - self.panels = [] - self.scroll = None - self.mark_lines = {} - self.col = 1 - self.__re_draw() - - self.timer = wx.Timer(self) # 鍒涘缓瀹氭椂鍣� - self.Bind(wx.EVT_TIMER, self.post_redraw, self.timer) # 缁戝畾涓�涓畾鏃跺櫒浜嬩欢 - self.last_size = (self.Size[0], self.Size[1]) - - # self.scroll.Layout() - # self.boxsier.Fit(self.scroll) - - # boxsier.Add(mainBoxsier, 1, wx.EXPAND | wx.ALL, 5) - # self.SetSizer(boxsier) - # mainBoxsier.Fit(self) - - window_info = setting.get_window_info() - float_pos = None - if window_info: - float_pos = window_info[1] - self.SetPosition(wx.Point(window_info[0][0], window_info[0][1])) - self.Size = wx.Size(window_info[0][2], window_info[0][3]) - self.floatFrame = FloatFrame(float_pos) - self.floatFrame.Show() - if setting.is_stay_on_top(): - self.WindowStyle = wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN | wx.STAY_ON_TOP - - def scrollTo(self, pos): - self.scroll.Scroll(0, pos) - - def __re_draw(self): - codes_name = juejin_core.GPCodeManager().get_codes_with_names() - rows = len(codes_name) - if rows % self.col == 0: - rows = rows / self.col - else: - rows = rows / self.col + 1 - space = 0 - if self.scroll is None: - self.scroll = wx.ScrolledWindow(self, -1, size=(800, 1000)) - self.boxsier = wx.FlexGridSizer(rows, self.col, space, space) - self.scroll.SetSizer(self.boxsier) - self.scroll.EnableScrolling(False, True) - if self.panels: - for p in self.panels: - p.Destroy() - self.boxsier.Clear() - pannel_height = round((self.Size[0] - (self.col - 1) * space) / self.col * (450 / 800)) - - self.scroll.SetScrollbars(1, 1, 0, pannel_height * rows) - self.scroll.SetScrollRate(0, pannel_height) - global drawManager - axes_list = [] - self.panels = [] - for i in range(0, len(codes_name)): - # pos=(0, i * pannel_height) - pannel = wx.Panel(self.scroll, size=(-1, pannel_height)) - pannel.BackgroundColour = wx.Colour(0, 0, 0) - self.panels.append(pannel) - self.boxsier.Add(pannel) - axes = self.__create_canvas(pannel, "{}({})".format(codes_name[i][0], codes_name[i][1]), codes_name[i][1], - codes_name[i][2]) - axes_list.append(axes) - - self.scroll.Layout() - # self.boxsier.Fit(self.scroll) - # - # 鍒濆鍖栨暟鎹� - drawManager = DrawManager(axes_list, codes_name) - drawManager.init_code_datas() - - def __create_canvas(self, pannel, title, name, price, close_callback=None): - def show_mouse_line(event): - # 鍒犻櫎涔嬪墠鐨勭嚎 - if title in self.mark_lines: - if self.mark_lines.get(title): - line = self.mark_lines.get(title).get("mouse") - if line is not None: - line.remove() - self.mark_lines.get(title).pop("mouse") - else: - self.mark_lines[title] = {} - try: - line = axes2.axhline(event.ydata, linestyle='-', color='white', lw=0.5) - self.mark_lines[title]["mouse"] = line - axes2.figure.canvas.draw() - except: - pass - - def clear_mouse_line(event): - print("clear_mouse_line") - if title in self.mark_lines: - if self.mark_lines.get(title): - line = self.mark_lines.get(title).get("mouse") - if line is not None: - line.remove() - self.mark_lines.get(title).pop("mouse") - axes2.figure.canvas.draw() - - def close_canvas(event): - print("鍏抽棴", title) - close_callback(title) - - width_dpi = self.Size[0] / (100 * self.col) - figure_score = Figure(figsize=(width_dpi, round(width_dpi * (4.5 / 7.8), 2))) - # 璁剧疆澶栬竟璺� - figure_score.subplots_adjust(left=0.01, bottom=0.15, right=0.85) - # 璁剧疆瀛椾綋棰滆壊 - plt.rcParams["text.color"] = "red" - plt.rcParams["axes.labelcolor"] = "red" - # 璁剧疆鍧愭爣杞存暟瀛楅鑹� - plt.rcParams["xtick.color"] = "white" - plt.rcParams["ytick.color"] = "white" - # 璁剧疆鍧愭爣杞撮鑹� - plt.rcParams["axes.edgecolor"] = "firebrick" - - # 瑙e喅涓枃涔辩爜闂 - plt.rcParams["font.sans-serif"] = ["SimHei"] # 璁剧疆瀛椾綋 - plt.rcParams["font.serif"] = ["SimHei"] - plt.rcParams["axes.unicode_minus"] = False # 璇ヨ鍙ヨВ鍐冲浘鍍忎腑鐨勨��-鈥濊礋鍙风殑涔辩爜闂 - - # 娴嬭瘯 - buttonaxe = plt.axes([0.94, 0.5, 0.1, 0.1]) - button1 = Button(buttonaxe, '鍏抽棴', color='white', hovercolor='yellow') - - axes = figure_score.add_subplot(1, 1, 1) - axes.autoscale(True) - - # axes_score.plot(t_score, s_score, 'ro', t_score, s_score, 'k') - axes.set_title(title) - axes.grid(color='firebrick', ls='-', lw=0.5) - axes.set_xlabel(f'鏃堕棿锛坽name}锛�') - axes.dist = 0 - - # axes.set_ylabel(u'浠锋牸') - # 鑾峰彇骞冲紑浠� - extra = 0 # (tool.get_limit_up_price(price)-decimal.Decimal(price))*decimal.Decimal(0.02) - - axes.set_ylim(tool.get_limit_down_price(price) - extra, tool.get_limit_up_price(price) + extra) - axes.patch.set_facecolor('black') - figure_score.patch.set_facecolor('black') - - axes2 = axes.twinx() - # axes2.grid(color='firebrick', ls='-', lw=0.5) - # axes2.grid(color='firebrick', ls='-', lw=0.5) - axes2.grid(False) - # 榧犳爣鍦ㄧ敾甯冪Щ鍔� - axes2.figure.canvas.mpl_connect('motion_notify_event', show_mouse_line) - # 榧犳爣绂诲紑鐢诲竷 - axes2.figure.canvas.mpl_connect('axes_leave_event', clear_mouse_line) - - # 璁剧疆绾靛潗鏍囪酱 - limit_up_price = float(tool.get_limit_up_price(price)) - max_rate = round((limit_up_price - price) / price, 4) * 100 - print("娑ㄥ仠鏈�澶ф瘮渚�", max_rate) - yticks2 = [] - for i in range(0, 21): - if i >= 10: - yticks2.append(0 - round(max_rate * (10 - i) / 10, 4)) - else: - yticks2.append(round(max_rate * (i - 10) / 10, 4)) - yticks2_labels = [] - yticks = [] - yticks_labels = [] - for i in range(0, len(yticks2)): - if i % 2 == 0: - yticks2_labels.append("{}%".format(abs(round(yticks2[i], 2)))) - else: - yticks2_labels.append("") - price_ = round((1 + yticks2[i] / 100) * price, 2) - yticks.append(price_) - if i % 2 == 0: - yticks_labels.append("") - # yticks_labels.append(round(yticks[i], 2)) - if i == 10: - axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=2) - else: - axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=1.2) - else: - # axes2.axhline(yticks2[i], linestyle='-', color='firebrick', lw=0.5) - yticks_labels.append("") - # 鍔犵矖涓酱绾� - - axes2.set_ylabel(u'娑ㄥ箙') - # 璁剧疆绾佃酱鐨勫�肩殑鑼冨洿 - axes2.set_ylim(0 - max_rate * (1), max_rate * (1)) - axes2.set_yticks(yticks2) - axes2.set_yticklabels(yticks2_labels) - axes.set_yticks(yticks) - axes.set_yticklabels(yticks_labels) - # 璁剧疆绾靛潗鏍囨暟鍊奸鑹� - for i in range(0, 9): - axes.get_yticklabels()[i].set_color("green") - axes2.get_yticklabels()[i].set_color("green") - for i in range(10, 10): - axes.get_yticklabels()[i].set_color("white") - axes2.get_yticklabels()[i].set_color("white") - for i in range(11, 21): - axes.get_yticklabels()[i].set_color("red") - axes2.get_yticklabels()[i].set_color("red") - line = axes2.plot([], [], color='white', linewidth=1) - average_line = axes2.plot([], [], color='yellow', linewidth=1) - cannvas = FigureCanvas(pannel, -1, figure_score) - axes2.text(1, 11.5, r'鐜颁环锛�0.0 娑ㄥ箙锛�0.00% \n鐣欐牸灞�锛�0%', fontsize=10, color='white') - axes2.text(-1, -11.5, r'鐜颁环锛�0.0 娑ㄥ箙锛�0.00% \n鐣欐牸灞�锛�0%', fontsize=10, color='white') - - axes2.spines['top'].set_visible(False) - axes.spines['top'].set_visible(False) - axes2.spines['bottom'].set_visible(False) - axes.spines['bottom'].set_visible(False) - return (axes2, line, average_line) - - def __set_juejin_params(self, event): - ps = self.GetPosition() - size = self.GetSize() - JueJinSettingFrame((ps[0] + size[0] / 2, ps[1] + size[1] / 2)).Show() - - def __check_juejin(self, event): - frame = wx.Frame(None, -1, '鎺橀噾鍙傛暟璁剧疆', size=(400, 100)) - frame.Center() - frame.Show() - - def __manage_code(self, event): - ps = self.GetPosition() - size = self.GetSize() - CodesSettingFrame((ps[0] + size[0] / 2, ps[1] + size[1] / 2), self.set_codes_success).Show() - - def __add_forbidden_codes(self, event): - ps = self.GetPosition() - size = self.GetSize() - FobiddenCodesFrame((ps[0] + size[0] / 2, ps[1] + size[1] / 2)).Show() - - def __manage_ths_pos(self, event): - ps = self.GetPosition() - size = self.GetSize() - THSPositionSettingFrame((ps[0] + size[0] / 2, ps[1] + size[1] / 2)).Show() - - def __ths_auto_click(self, event): - if event.Selection: - setting.set_ths_auto_click(1) - else: - setting.set_ths_auto_click(0) - - def set_codes_success(self): - print("璁剧疆浠g爜鎴愬姛鍥炶皟") - p2.send("resub") - self.__re_draw() - - def __show_top(self, event): - if event.Selection: - setting.set_stay_on_top(1) - self.WindowStyle = wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN | wx.STAY_ON_TOP - else: - setting.set_stay_on_top(0) - self.WindowStyle = wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN - - def __menu(self): - self.mainmenu = wx.MenuBar() - setting_ = wx.Menu() - setting_.Append(105, '&娣诲姞绂佹浠g爜', '') - setting_.AppendSeparator() - setting_.Append(104, '&閽変綇', '', kind=wx.ITEM_CHECK) - setting_.Check(104, setting.is_stay_on_top()) - setting_.AppendSeparator() - setting_.Append(101, '&鎺橀噾鍙傛暟閰嶇疆', 'Open a new document') - setting_.Append(102, '&鎺橀噾妫�娴�', 'Open a new document') - setting_.AppendSeparator() - setting_.Append(103, '&浠g爜绠$悊', 'Open a new document') - - self.mainmenu.Append(setting_, '&璁剧疆') - - auto_help = wx.Menu() - auto_help.Append(202, '&鍚岃姳椤鸿缃�', '') - auto_help.Append(201, '&鑷姩鐐瑰嚮', '', kind=wx.ITEM_CHECK) - - auto_help.Check(201, setting.is_ths_auto_click()) - - self.mainmenu.Append(auto_help, '&鑷姩鍖�') - # 璁剧疆浜嬩欢 - self.Bind(wx.EVT_MENU, self.__set_juejin_params, id=101) - self.Bind(wx.EVT_MENU, self.__check_juejin, id=102) - self.Bind(wx.EVT_MENU, self.__manage_code, id=103) - self.Bind(wx.EVT_MENU, self.__show_top, id=104) - self.Bind(wx.EVT_MENU, self.__add_forbidden_codes, id=105) - self.Bind(wx.EVT_MENU, self.__manage_ths_pos, id=202) - self.Bind(wx.EVT_MENU, self.__ths_auto_click, id=201) - - self.SetMenuBar(self.mainmenu) - - def OnExit(self, e): - try: - self.floatFrame.Close(True) - setting.set_window_info((self.Position[0], self.Position[1], self.Size[0], self.Size[1]), ( - self.floatFrame.Position[0], self.floatFrame.Position[1], self.floatFrame.Size[0], - self.floatFrame.Size[1])) - except Exception as e: - print("") - jueJinProcess.terminate() - sys.exit(0) - - def post_redraw(self, evt): - - if abs(self.last_size[0] - self.Size[0]) > 20: - print("--------post_redraw--------") - self.last_size = (self.Size[0], self.Size[1]) - self.__re_draw() - - def OnResize(self, e): - print("鍙樺寲鍚庣殑灏哄", e.Size) - # 鐣欏嚭婊氬姩鏉★紝鐣欏嚭涓婅竟璺� - if self.scroll: - self.scroll.Size = (e.Size[0] - 15, e.Size[1] - 60) - for p in self.panels: - p_height = round(e.Size[0] * (450 / 800)) - p.Size = (e.Size[0], p_height) - self.timer.Stop() - self.timer.StartOnce(1000) - # 闄嶄綆閲嶇粯棰戠巼 - # self.__re_draw() - - -# 缁樺浘绠$悊鍣� -class DrawManager: - - def __load_lack_datas(self, code, time_ranges): - codeDataManager = code_data_manager.CodeDataManager() - day = tool.get_now_date_str() - for time_range in time_ranges: - results = juejin_core.GPCodeManager().get_history_tick(code, day + " " + time_range[0], - day + " " + time_range[1]) - datas = [] - for data in results: - datas.append(juejin_core.parse_tick(data)) - # 淇濆瓨鏁版嵁 - - for data in datas: - # 09:25:00涔嬪墠鐨勬暟鎹笉淇濆瓨 - created_at = data["created_at"].strftime("%Y-%m-%d %H:%M:%S") - time_ = created_at[-8:] - if tool.trade_time_sub(time_, "09:25:00") < 0: - continue - if tool.trade_time_sub(time_, "15:00:00") > 0: - continue - if tool.trade_time_sub(time_, "11:30:00") > 0 and tool.trade_time_sub(time_, "13:00:00") < 0: - continue - - # 涓嶆槸浠婂ぉ鐨勬暟鎹笉淇濆瓨 - if day != created_at[:10]: - continue - codeDataManager.save_data(data) - - def init_code_datas(self): - global code_datas - global max_min_prices - codeDataManager = code_data_manager.CodeDataManager() - gpCodeManager = juejin_core.GPCodeManager() - code_datas = {} - max_min_prices = {} - codes = gpCodeManager.get_codes() - if codes: - # 鑾峰彇褰撴棩鐨勬渶楂樹环鏈�浣庝环 - res = juejin_core.GPCodeManager().get_min_and_max_price(codes) - for data in res: - max_min_prices[data[0]] = (data[1], data[2]) - - for code in codes: - # 鍔犺浇鍘嗗彶鏁版嵁 - code_datas[code] = [] - old_datas = codeDataManager.get_datas(code) - # 鑾峰彇缂哄け鐨勬暟鎹� - ranges = codeDataManager.get_lack_datas_time_range(old_datas) - if len(ranges) > 0: - self.__load_lack_datas(code, ranges) - old_datas = codeDataManager.get_datas(code) - - if old_datas: - code_datas[code].extend(old_datas) - self.update(code, code_datas[code]) - - # 鏇存柊鏁版嵁 - def __update_data(self, code, axes, datas, min_rate, max_rate): - def get_time_as_seconds(created_at): - time_ = created_at[-8:] - if tool.get_time_as_second("13:00:00") > tool.get_time_as_second(time_) > tool.get_time_as_second( - "11:30:00"): - time_ = "11:30:00" - time_s = int(time_.split(":")[0]) * 3600 + int(time_.split(":")[1]) * 60 + int( - time_.split(":")[2]) - 9 * 3600 - 60 * 30 - - if int(time_.replace(":", "")) > int("11:30:00".replace(":", "")): - time_s -= 90 * 60 - return time_s - - def seconds_2_time_str(seconds): - seconds += 9 * 3600 + 60 * 30 - if seconds > 11 * 3600 + 60 * 30: - seconds += 90 * 60 - h = seconds // 3600 - m = seconds % 3600 // 60 - s = seconds % 60 - return "{0:0>2}:{1:0>2}:{2:0>2}".format(h, m, s) - - # 鍒犻櫎9:30浠ュ墠鐨勬暟鎹� - for i in range(0, len(datas)): - time_ = datas[i]["created_at"][-8:] - if int(time_.replace(":", "")) >= int("093000"): - datas = datas[i:] - break - # 鍙栨渶杩�12鍒嗛挓鐨勬暟鎹� - for i in range(len(datas) - 1, -1, -1): - time_ = datas[i]["created_at"][-8:] - if tool.trade_time_sub(datas[-1]["created_at"][-8:], time_) >= 14 * 60: - datas = datas[i:] - break - - xs = [] - ys_rate = [] - ys_average_rate = [] - for data in datas: - xs.append(get_time_as_seconds(data["created_at"])) - ys_rate.append(data["rate"] * 100) - ys_average_rate.append(data["average_rate"] * 100) - - xticks = [] - xticklabels = [] - # 璁剧疆X杞磋寖鍥翠负09:30:00 鍒�15:00:00 - # x杞磋寖鍥翠负0-15鍒嗛挓 - end_x = "0000-00-00 " + tool.trade_time_add_second(datas[0]["created_at"][-8:], 15 * 60) - axes[0].set_xlim(get_time_as_seconds(datas[0]["created_at"]), get_time_as_seconds(end_x)) - - # if len(xs) < 2 or xs[-1] - xs[0] < 30 * 60: - # axes[0].set_xlim(xs[0], xs[0] + 30 * 60) - # else: - # axes[0].set_xlim(xs[0], xs[-1]) - xms = axes[0].get_xlim() - yms = axes[0].get_ylim() - step = (int(xms[1]) - int(xms[0])) // 30 - for i in range(int(xms[0]), int(xms[1] + 1), step): - xticks.append(i) - xticklabels.append("") - - axes[0].set_xticks(xticks) - axes[0].set_xticklabels(xticklabels) - - axes[1][0].set_data(xs, ys_rate) - axes[2][0].set_data(xs, ys_average_rate) - texts = axes[0].texts - texts[0].set_text("{}% \n鐣欐牸灞�锛�0%".format(round(datas[-1]["rate"] * 100, 2))) - texts[1].set_text("{}".format(datas[-1]["created_at"].split(" ")[1])) - texts[0].set_x(xms[1] - 80) - texts[0].set_y(yms[1] + 0.5) - texts[1].set_x(xms[0]) - texts[1].set_y(yms[0] - 1.5) - - # 鍒犻櫎涔嬪墠 - if code in self.lines: - for key in self.lines[code]: - line = self.lines[code][key] - line.remove() - self.lines.pop(code) - # 缁樺埗鏈�澶ф渶灏忓潗鏍� - line_min = axes[0].axhline(min_rate, linestyle='--', color='yellow', lw=0.5) - line_max = axes[0].axhline(max_rate, linestyle='--', color='yellow', lw=0.5) - self.lines[code] = {"min": line_min, "max": line_max} - axes[0].figure.canvas.draw() - axes[0].figure.canvas.flush_events() - - def __init__(self, axes_list, codes_info): - self.axes_list = axes_list - self.codes_info = codes_info - self.lines = {} - - def update(self, code, datas): - # 鑾峰彇鍓嶉珮鍜屽墠浣� - max_rate = None - min_rate = None - if code in max_min_prices: - pre_price = juejin_core.GPCodeManager().get_pre_prices(code) - min_rate = round((max_min_prices[code][0] - pre_price) / pre_price, 4) - max_rate = round((max_min_prices[code][1] - pre_price) / pre_price, 4) - - for data in datas: - rate = data["rate"] * 100 - created_at = data["created_at"][-8:] - if tool.get_time_as_second("15:00:00") >= tool.get_time_as_second(created_at) >= tool.get_time_as_second( - "09:30:00"): - if max_rate is None: - max_rate = rate - if min_rate is None: - min_rate = rate - if rate > max_rate: - max_rate = rate - if rate < min_rate: - min_rate = rate - - # 灞曠ず鏈�杩戠殑600涓� - datas = datas[-450:] - for i in range(0, len(self.codes_info)): - if self.codes_info[i][0] == code: - try: - self.__update_data(code, self.axes_list[i], datas, min_rate, max_rate) - except Exception as e: - logging.exception(e) - - -class mainApp(wx.App): - - def __refresh(self): - codes = juejin_core.GPCodeManager().get_codes() - last_time = round(time.time()) - while True: - try: - code = ocr_ths_code() - if not code: - time.sleep(0.1) - continue - # 1s鏇存柊涓�娆� - if round(time.time()) - last_time > 5: - codes = juejin_core.GPCodeManager().get_codes() - last_time = round(time.time()) - for index in range(0, len(codes)): - if codes[index] == code: - self.Frame.scrollTo(index) - break - except Exception as e: - print(str(e)) - time.sleep(0.005) - - def OnInit(self): - self.SetAppName(APP_TITLE) - self.Frame = mainFrame() - # self.Frame = FloatFrame(None) - self.Frame.Show() - t1 = threading.Thread(target=lambda: self.__refresh()) - # 鍚庡彴杩愯 + @pyqtSlot(str, str, str) + def http_request(self, path, params, callback_info): + url = path + "?" + if params: + params = json.loads(params) + url += "&".join([f"{key}={params[key]}" for key in params]) + print("http璇锋眰", url) + callback_info = json.loads(callback_info) + t1 = threading.Thread(target=lambda: self.__http_request(url, callback_info)) t1.setDaemon(True) t1.start() - return True + @pyqtSlot(str, str) + def socket_request(self, text, callback_info): + print("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)) + 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() + + # 鑾峰彇瀹㈡埛绔疘D + @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): + # 璁剧疆鐩爣浠g爜 + window_msg_queue.put_nowait({"type": "set_target_code", "data": {"code": code}}) -def recieve_tick(pipe): - codeDataManager = code_data_manager.CodeDataManager() - while True: - data = pipe.recv() - if data: - type = data["type"] - if type == 0: - # tick鏁版嵁 - data = data["data"] - code = data["code"] - if code not in code_datas: - code_datas[code] = [] - code_datas[code].append(data) - codeDataManager.save_data(data) - # 鏇存柊鏁版嵁 +class SecondWindowBridgeClass(BaseBridgeClass): + @pyqtSlot(str) + def set_target_code(self, code): + # 璁剧疆鐩爣浠g爜 + 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, 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 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): + 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(SecondWindow, self).__init__(parent) + self.setWindowTitle('鐪嬬洏鍓睆') + window_info = setting.get_kp_second_window_info() + if window_info: + self.move(window_info[0], window_info[1]) + self.resize(window_info[2], window_info[3]) + else: + 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 = SecondWindowBridgeClass(self.webview) + + 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: + # 瑙f瀽鏁版嵁 + # 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, 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}')") + + # 鏇存柊寮�鐩樺暒鏁版嵁 + def __update_kpl(self): + 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: + # 瑙f瀽鏁版嵁 + # 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: + # 瑙f瀽鏁版嵁 + # 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): + signal_update_code = pyqtSignal(str) + + def show_info(self, msg): + QMessageBox.information(self, "鎻愮ず", msg, QMessageBox.Yes) + + def show_warning(self, msg): + QMessageBox.warning(self, "鎻愮ず", msg, QMessageBox.Yes) + + 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) + + # 璁剧疆鐩爣浠g爜 + 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): + def __gpu_is_avaiable(): + if torch.cuda.is_available(): + self.show_info("GPU鍙敤") + else: + self.show_warning("GPU涓嶅彲鐢�") + + def __set_juejin_params(): + 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"璇嗗埆鍒扮殑浠g爜锛歿code}") + except Exception as e: + self.show_warning(f"璇嗗埆鍑洪敊锛歿str(e)}") + + def __download_codes(): + try: + result = self.__request("", 72) + result = json.loads(result) + if result['code'] == 0: + codes_dict = result['data'] + if codes_dict: + for key in codes_dict: + # 灏嗕唬鐮佷繚瀛樺埌妗岄潰 + path = f"C:\\Users\\Administrator\\Desktop\\娑ㄥ仠浠g爜{key}.txt" + with open(path, mode='w') as f: + for c in codes_dict[key]: + f.write(c) + f.write("\n") + self.show_info("涓嬭浇鎴愬姛") + else: + self.show_warning(result['msg']) + except Exception as e: + self.show_warning(str(e)) + + def __manage_code(): + ps = (self.x(), self.y()) + 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_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('&璁剧疆') + + action = QAction("&GPU妫�娴�", self) + action.triggered.connect(__gpu_is_avaiable) + setting_.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_delegating_window) + view_.addAction(action) + + 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__() + self.wx_pipe = wx_pipe + self.setWindowTitle('鐪嬬洏椤甸潰') + window_info = setting.get_kp_window_info() + if window_info: + self.move(window_info[0], window_info[1]) + self.resize(window_info[2], window_info[3]) + 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) + 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() + 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")) + + 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() + try: + setting.set_kp_window_info((self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) + except Exception as e: + print("") + self.wx_pipe.send(json.dumps({"type": "exit"})) + wxGuiProcess.terminate() + wxGuiProcess.join() + sys.exit(0) + + # 璇诲彇娑堟伅 + def read_msg(self): + client = setting.get_client() + if not client: + client = 'hxh' + while True: + if tool.is_trade_time(): try: - drawManager.update(code, code_datas[code]) - print("鎺ュ彈鍒扮殑tick鏁版嵁:", data) + 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 ths_auto_click(): - hwnd = ths_util.get_ths_second_screen_menu_hwnd() +def recieve_code(pipe, mainWindow): + latest_code = '' while True: try: - if hwnd is None or not win32gui.IsWindowVisible(hwnd): - # print("鏈壘鍒板悓鑺遍『鍓睆鍙ユ焺") - hwnd = ths_util.get_ths_second_screen_menu_hwnd() - - if hwnd is None: - continue - if not setting.is_ths_auto_click(): - continue - ps = setting.get_ths_auto_click_positions() - if not ps: - continue - ps_new = [] - for p in ps: - p = eval(p) - ps_new.append(p) - space = setting.get_ths_auto_click_time_space() - if space is None: - space = 500 - ths_util.betch_click(hwnd, ps_new, round(space / 1000, 4)) + data = pipe.recv() + if data: + data = json.loads(data) + if data["type"] == "code": + if latest_code != data["code"]: + latest_code = data["code"] + mainWindow.signal_update_code.emit(latest_code) except Exception as e: - pass - finally: - time.sleep(0.02) + logging.exception(e) -def ths_auto_refresh(): - hwnd = ths_util.get_trade_refesh_hwnd() - while True: - try: - if hwnd is None or not win32gui.IsWindowVisible(hwnd): - # print("鏈壘鍒板悓鑺遍『浜ゆ槗鍒锋柊鍙ユ焺") - hwnd = ths_util.get_trade_refesh_hwnd() - - if hwnd is None: - continue - if not setting.is_ths_trade_auto_refresh(): - continue - rect = win32gui.GetWindowRect(hwnd) - win32_util.visual_click(hwnd, (160, (rect[3] - rect[1]) // 2)) - time_space = setting.get_ths_auto_refresh_time_space() - if time_space is None: - time_space = 500 - time.sleep(round(time_space / 1000, 4)) - except Exception as e: - pass - finally: - time.sleep(0.02) - - -if __name__ == "__main__1": - hwnd = ths_util.get_ths_main_content_hwnd() - if not hwnd: - raise Exception("鐪嬬洏椤甸潰鍙ユ焺鏈幏鍙栧埌") - # 鍙ユ焺鎴浘 - rect = win32gui.GetWindowRect(hwnd) - w = 150 - height = 45 - top = 38 - # img = win32_util.window_capture(hwnd, (rect[2] - rect[0] -100 , 25, rect[2] - rect[0], 55)) - # img = win32_util.window_capture(hwnd, rect) - img = win32_util.window_capture(hwnd, (0, 0, (rect[2] - rect[0]) * 15 // 10, (rect[3] - rect[1]) * 15 // 10)) +# 鎵撳寘鍛戒护 +# cd D:\workspace\GP\trade_desk +# D:\workspace\GP\trade_desk\dist\env\pk_env\Scripts\pyinstaller.exe main.spec +# 涓轰簡涓嶅嚭鐜版剰澶栫殑bug锛岃繍琛屾椂璇峰皢鐩綍鏀惧湪鑻辨枃璺緞 if __name__ == "__main__": - print(pow(3, 1)) - global p2 + freeze_support() p1, p2 = multiprocessing.Pipe() - global jueJinProcess - jueJinProcess = multiprocessing.Process(target=juejin_core.run, args=(p1,)) - jueJinProcess.start() + global wxGuiProcess + wxGuiProcess = Process(target=gui_wx.run, args=(p1,)) + wxGuiProcess.start() - t1 = threading.Thread(target=lambda: recieve_tick(p2)) + app = QApplication(sys.argv) + browser = MainWindow(p2) + t1 = threading.Thread(target=lambda: recieve_code(p2, browser)) # 鍚庡彴杩愯 t1.setDaemon(True) t1.start() - - t2 = threading.Thread(target=lambda: ths_auto_click()) - # 鍚庡彴杩愯 - t2.setDaemon(True) - t2.start() - - t3 = threading.Thread(target=lambda: ths_auto_refresh()) - # 鍚庡彴杩愯 - t3.setDaemon(True) - t3.start() - - app = mainApp(redirect=False) - app.MainLoop() + sys.exit(app.exec_()) -- Gitblit v1.8.0