admin
2023-07-19 466c85355b49b2363b7ea6bc4871bcd0e01d7447
HOST修改
8个文件已修改
3个文件已添加
609 ■■■■ 已修改文件
cnn/cnn.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnn/cnn_demo.py 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gui_wx.py 301 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kpl/gui.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
network_util.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
setting.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test.png 补丁 | 查看 | 原始文档 | blame | 历史
test.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
win32_util.dll 补丁 | 查看 | 原始文档 | blame | 历史
cnn/cnn.py
@@ -12,11 +12,11 @@
        self.conv = nn.Sequential(
            # [BATCH_SIZE, 1, 28, 28]
            # (通道大小,特征图数量,卷积核大小,步长,边缘填充像素)
            nn.Conv2d(1, 32, 5, 1, 2),
            nn.Conv2d(1, 32, 3, 1, 2),
            nn.ReLU(),
            nn.MaxPool2d(2),
            # [BATCH_SIZE, 32, 14, 14]
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.Conv2d(32, 64, 3, 1, 2),
            # [BATCH_SIZE, 64, 14, 14]
            nn.ReLU(),
            nn.MaxPool2d(2)
cnn/cnn_demo.py
New file
@@ -0,0 +1,210 @@
import os
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import Dataset, DataLoader
from PIL import Image
def default_loader(path):
    return Image.open(path)
class MyDataset(Dataset):
    # 使用__init__()初始化一些需要传入的参数及数据集的调用
    def __init__(self, dir_path, resize, target_transform=None, loader=default_loader):
        super(MyDataset, self).__init__()
        # 对继承自父类的属性进行初始化
        dirs = os.listdir(dir_path)
        for d in dirs:
            if
        fh = open(txt, 'r')
        imgs = []
        # 按照传入的路径和txt文本参数,以只读的方式打开这个文本
        for line in fh:  # 迭代该列表,按行循环txt文本中的内容
            line = line.strip('\n')
            line = line.rstrip('\n')
            # 删除本行string字符串末尾的指定字符,默认为空白符,包括空格、换行符、回车符、制表符
            words = line.split()
            # 用split将该行分割成列表,split的默认参数是空格,所以不传递任何参数时分割空格
            imgs.append((words[0], int(words[1])))
            # 把txt里的内容读入imgs列表保存
        self.imgs = imgs
        # 重新定义图像大小
        self.transform = transforms.Compose([transforms.Resize(size=(resize, resize)), transforms.ToTensor()])
        self.target_transform = target_transform
        self.loader = loader
    # 使用__getitem__()对数据进行预处理并返回想要的信息
    def __getitem__(self, index):
        fn, label = self.imgs[index]
        # fn是图片path
        img = self.loader(fn)
        # 按照路径读取图片
        if self.transform is not None:
            img = self.transform(img)
            # 数据标签转换为Tensor
        return img, label
        # return回哪些内容,那么在训练时循环读取每个batch时,就能获得哪些内容
    # 使用__len__()初始化一些需要传入的参数及数据集的调用
    def __len__(self):
        return len(self.imgs)
class CNN(nn.Module):
    # 定义网络结构
    def __init__(self):
        super(CNN, self).__init__()
        # 图片是灰度图片,只有一个通道
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32,
                               kernel_size=3, stride=1, padding=2)
        self.relu1 = nn.ReLU()
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64,
                               kernel_size=3, stride=1, padding=2)
        self.relu2 = nn.ReLU()
        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(in_features=8 * 8 * 64, out_features=256)
        self.relu3 = nn.ReLU()
        self.fc2 = nn.Linear(in_features=256, out_features=10)
    # 定义前向传播过程的计算函数
    def forward(self, x):
        # 第一层卷积、激活函数和池化
        x = self.conv1(x)
        x = self.relu1(x)
        x = self.pool1(x)
        # 第二层卷积、激活函数和池化
        x = self.conv2(x)
        x = self.relu2(x)
        x = self.pool2(x)
        # 将数据平展成一维
        x = x.view(-1, 8 * 8 * 64)
        # 第一层全连接层
        x = self.fc1(x)
        x = self.relu3(x)
        # 第二层全连接层
        x = self.fc2(x)
        return x
# 加载MNIST数据集
transforms = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
train_dataset = datasets.MNIST('../data', train=True, download=True,
                               transform=transforms)
test_dataset = datasets.MNIST('../data', train=False,
                              transform=transforms)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=True)
# 训练过程
def train(epoch, model, train_loader, test_loader):
    correct = 0
    total = 0
    running_loss = 0
    for x, y in train_loader:
        # 把数据放到GPU上
        x, y = x.to(device), y.to(device)
        y_pred = model(x)
        loss = loss_fn(y_pred, y)
        # 梯度清零
        optimizer.zero_grad()
        loss.backward()  # backward 反向传播
        optimizer.step()
        # 计算损失过程
        with torch.no_grad():
            y_pred = torch.argmax(y_pred, dim=1)
            correct += (y_pred == y).sum().item()
            total += y.size(0)
            running_loss += loss.item()
        # 循环完一次后, 计算损失
    epoch_loss = running_loss / len(train_loader.dataset)
    epoch_acc = correct / total
    # 测试数据的代码
    test_correct = 0
    test_total = 0
    test_running_loss = 0
    with torch.no_grad():
        for x, y in test_loader:
            x, y = x.to(device), y.to(device)
            y_pred = model(x)
            loss = loss_fn(y_pred, y)
            # 计算损失
            y_pred = torch.argmax(y_pred, dim=1)
            test_correct += (y_pred == y).sum().item()
            test_total += y.size(0)
            test_running_loss += loss.item()
    # 计算平均损失
    test_epoch_loss = test_running_loss / len(test_loader.dataset)
    test_epoch_acc = test_correct / test_total
    # 打印输出
    print('epoch:', epoch,
          'loss:', round(epoch_loss, 3),
          'accuracy:', round(epoch_acc, 3),
          'test_loss:', round(test_epoch_loss, 3),
          'test_accuracy:', round(test_epoch_acc, 3))
    return epoch_loss, epoch_acc, test_epoch_loss, test_epoch_acc
# 定义测试函数
def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()
    test_loss /= len(test_loader.dataset)
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))
# 定义设备和模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = CNN().to(device)
# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()
# optimizer 优化器, 防止过拟合
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
epochs = 20
train_loss = []
train_acc = []
test_loss = []
test_acc = []
# 训练模型
for epoch in range(1, 11):
    epoch_loss, epoch_acc, test_epoch_loss, test_epoch_acc = train(epoch, model,
                                                                   train_loader, test_loader)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(test_epoch_loss)
    test_acc.append(test_epoch_acc)
# 保存模型
# 模型保存
PATH = './mnist_net.pth'
torch.save(model.state_dict(), PATH)
constant.py
New file
@@ -0,0 +1,2 @@
SERVER_HOST = "111.230.16.67"
WEB_HOST = "192.168.3.252"
gui_wx.py
@@ -1,5 +1,8 @@
import array
import ctypes
import json
import socket
import struct
import sys
import time
@@ -7,6 +10,7 @@
import win32con
import win32gui
import constant
import ocr_util
import opencv_util
import setting
@@ -33,7 +37,6 @@
APP_TITLE = "卖票看板"
APP_ICON = ""
SERVER_HOST = "192.168.3.252"
SOCKET_PORT = 9001
HTTP_PORT = 9004
@@ -202,7 +205,7 @@
    def __request(self, codes):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 201, "data": {"codes": codes}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -338,6 +341,7 @@
    return code
#
# # 代码属性
# class CodeAttributeFrame(wx.Frame):
@@ -409,109 +413,147 @@
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "悬浮盯盘", style=wx.CAPTION ^ wx.MINIMIZE_BOX ^ wx.CLOSE_BOX ^ wx.STAY_ON_TOP,
                          size=(435, 220))
        #
        self.SetBackgroundColour(wx.Colour(224, 224, 224))
        self.SetTransparent(230)
        self.Bind(wx.EVT_CLOSE, self.OnExit)
        # 设置字体大小
        font = self.GetFont()
        font.SetPixelSize(wx.Size(0, 11))
        self.SetFont(font)
        # 读取配置信息
        window_info = setting.get_float_watch_window_info()
        if window_info:
            self.SetPosition(wx.Point(window_info[0], window_info[1]))
            # self.Size = wx.Size(window_info[2], window_info[3])
        boxsier = wx.FlexGridSizer(5, 3, 4, 5)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_remove_black = wx.Button(self, label="移除黑名单", size=(65, 30))
        boxsier = wx.BoxSizer(wx.VERTICAL)
        # ------所有控件定义--------
        btn_width = 60
        self.btn_already_canceled = wx.Button(self, label="撤单", size=(-1, 40))
        self.btn_sell = wx.Button(self, label="卖100%", size=(-1, 40))
        font = self.btn_already_canceled.GetFont()
        font.SetPixelSize(wx.Size(0, 16))
        self.btn_already_canceled.SetFont(font)
        self.btn_sell.SetFont(font)
        self.btn_remove_black = wx.Button(self, label="移除黑名单", size=(btn_width, 30))
        self.btn_close_buy = wx.Button(self, label="关闭交易", size=(65, 30))
        self.btn_close_buy.SetForegroundColour("#FF3232")
        bs1.Add(self.btn_remove_black)
        bs1.Add(self.btn_close_buy)
        boxsier.Add(bs1, 0, wx.TOP, 5)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_remove_white = wx.Button(self, label="移除白名单", size=(65, 30))
        self.btn_remove_white = wx.Button(self, label="移除白名单", size=(btn_width, 30))
        self.btn_open_buy = wx.Button(self, label="开启交易", size=(65, 30), )
        self.btn_open_buy.SetForegroundColour("#00e600")
        bs1.Add(self.btn_open_buy, 0, wx.TOP, 5)
        bs1.Add(self.btn_remove_white, 0, wx.TOP, 5)
        boxsier.Add(bs1, 0, wx.LEFT, 0)
        # 买想买
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_buy_mode_want = wx.Button(self, label="仅买想买", size=(65, 30))
        self.btn_buy_mode_all = wx.Button(self, label="全部都买", size=(65, 30), )
        # self.btn_buy_mode_all.SetForegroundColour("#00e600")
        bs1.Add(self.btn_buy_mode_want, 0, wx.TOP, 5)
        bs1.Add(self.btn_buy_mode_all, 0, wx.TOP, 5)
        self.check_auto_refresh = wx.CheckBox(self, size=(-1, -1), label="交易刷新")
        self.want_list = wx.Button(self, label="想买单", size=(40, 20))
        self.btn_want_buy = wx.Button(self, label="加入想买单", size=(btn_width, 30))
        boxsier.Add(bs1, 0, wx.LEFT, 0)
        self.check_auto_click = wx.CheckBox(self, size=(-1, -1), label="分组刷新")
        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)
        # 已撤单
        self.btn_already_canceled = wx.Button(self, label="已撤单", size=(65, 25))
        self.check_focus = wx.CheckBox(self, size=(-1, -1), label="抢占焦点")
        boxsier.Add(self.btn_already_canceled, 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=(65, 25))
        bs1.Add(self.btn_want_buy)
        self.check_trade_quick_key = wx.CheckBox(self, size=(-1, -1), label="交易快捷键")
        boxsier.Add(bs1, 0, wx.LEFT, 20)
        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)
        # 加空白
        boxsier.Add(wx.BoxSizer(wx.HORIZONTAL), 0, wx.TOP, 5)
        self.btn_want_buy_remove = wx.Button(self, label="移除想买单", size=(65, 25))
        boxsier.Add(self.btn_want_buy_remove, 0, wx.LEFT, 65)
        self.btn_want_buy_remove = wx.Button(self, label="移除想买单", size=(btn_width, 30))
        self.edit_code = wx.TextCtrl(self, size=(80, -1))
        boxsier.Add(self.edit_code)
        self.edit_code.Show(False)
        self.notify_text = wx.StaticText(self, label="", size=(80, -1))
        boxsier.Add(self.notify_text, 0, wx.LEFT, -45)
        #
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.pause_buy_list = wx.Button(self, label="暂不买单", size=(55, 20))
        bs1.Add(self.pause_buy_list, 0, wx.TOP, 2)
        self.btn_pause_buy = wx.Button(self, label="加入暂不买", size=(65, 25))
        bs1.Add(self.btn_pause_buy)
        boxsier.Add(bs1, 0, wx.LEFT, 10)
        self.pause_buy_list = wx.Button(self, label="不买单", size=(40, 20))
        self.btn_pause_buy = wx.Button(self, label="加入暂不买", size=(btn_width, 30))
        # 代码
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        self.btn_black = wx.Button(self, label="加入黑名单", size=(65, 30))
        bs1.Add(self.btn_black)
        self.black_list = wx.Button(self, label="黑名单", size=(45, 20))
        self.btn_black = wx.Button(self, label="加入黑名单", size=(btn_width, 30))
        self.black_list = wx.Button(self, label="黑名单", size=(40, 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=(65, 30))
        self.white_list = wx.Button(self, label="白名单", size=(45, 20))
        self.btn_white = wx.Button(self, label="加入白名单", size=(btn_width, 30))
        self.white_list = wx.Button(self, label="白名单", size=(40, 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, 17)
        self.btn_pause_buy_remove = wx.Button(self, label="移除暂不买", size=(btn_width, 30))
        self.btn_pause_buy_remove = wx.Button(self, label="移除暂不买", size=(65, 25))
        boxsier.Add(self.btn_pause_buy_remove, 0, wx.LEFT, 65)
        # ------布局--------
        # 第1排 撤单与卖
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        bs1.Add(self.btn_already_canceled, 1, wx.ALL | wx.EXPAND, 2)
        bs1.Add(self.btn_sell, 1, wx.ALL | wx.EXPAND, 2)
        boxsier.Add(bs1, 0, wx.ALL | wx.EXPAND, 0)
        boxsier.Add(wx.StaticText(self, size=wx.Size(-1, 5)), 0, wx.ALL | wx.EXPAND, 0)
        # 第2排 白名单 黑名单 暂不买单 想买单
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        # 白名单
        bs2 = wx.BoxSizer(wx.HORIZONTAL)
        bs_v = wx.BoxSizer(wx.VERTICAL)
        bs_v.Add(self.btn_white)
        bs_v.Add(self.btn_remove_white)
        bs2.Add(bs_v)
        bs2.Add(self.white_list, 0, wx.ALL | wx.EXPAND, 0)
        bs1.Add(bs2, 1, wx.ALL | wx.EXPAND, 1)
        # 黑名单
        bs2 = wx.BoxSizer(wx.HORIZONTAL)
        bs_v = wx.BoxSizer(wx.VERTICAL)
        bs_v.Add(self.btn_black)
        bs_v.Add(self.btn_remove_black)
        bs2.Add(bs_v)
        bs2.Add(self.black_list, 0, wx.ALL | wx.EXPAND, 0)
        bs1.Add(bs2, 1, wx.ALL | wx.EXPAND, 1)
        # 暂不买单
        bs2 = wx.BoxSizer(wx.HORIZONTAL)
        bs_v = wx.BoxSizer(wx.VERTICAL)
        bs_v.Add(self.btn_pause_buy)
        bs_v.Add(self.btn_pause_buy_remove)
        bs2.Add(bs_v)
        bs2.Add(self.pause_buy_list, 0, wx.ALL | wx.EXPAND, 0)
        bs1.Add(bs2, 1, wx.ALL | wx.EXPAND, 1)
        # 想买单
        bs2 = wx.BoxSizer(wx.HORIZONTAL)
        bs_v = wx.BoxSizer(wx.VERTICAL)
        bs_v.Add(self.btn_want_buy)
        bs_v.Add(self.btn_want_buy_remove)
        bs2.Add(bs_v)
        bs2.Add(self.want_list, 0, wx.ALL | wx.EXPAND, 0)
        bs1.Add(bs2, 1, wx.ALL | wx.EXPAND, 1)
        boxsier.Add(bs1, 0, wx.ALL | wx.EXPAND, 0)
        boxsier.Add(wx.StaticText(self, size=wx.Size(-1, 5)))
        # 第3排 交易操作位
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        bs_v = wx.BoxSizer(wx.VERTICAL)
        bs_v.Add(self.check_auto_refresh)
        bs_v.Add(self.check_auto_click)
        bs1.Add(bs_v)
        bs_v = wx.BoxSizer(wx.VERTICAL)
        bs_v.Add(self.check_focus)
        bs_v.Add(self.check_trade_quick_key)
        bs1.Add(bs_v, 0, wx.LEFT, 5)
        blank_label = wx.StaticText(self)
        bs1.Add(blank_label, 1, wx.ALL | wx.EXPAND, 1)
        bs1.Add(self.btn_close_buy)
        bs1.Add(self.btn_open_buy)
        bs1.Add(self.btn_buy_mode_want)
        bs1.Add(self.btn_buy_mode_all)
        boxsier.Add(bs1, 0, wx.ALL | wx.EXPAND, 1)
        # 绑定
        self.btn_open_buy.Bind(wx.EVT_BUTTON, self.__open_buy)
@@ -535,17 +577,18 @@
        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.check_focus.Bind(wx.EVT_CHECKBOX, self.__auto_focus_check)
        self.check_trade_quick_key.Bind(wx.EVT_CHECKBOX, self.__trade_quick_key_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))
        self.pause_buy_list.Bind(wx.EVT_BUTTON, lambda e: self.show_list(e, "暂不买列表", 413))
        root_boxsier = wx.BoxSizer(wx.VERTICAL)
        root_boxsier.Add(boxsier, 1, wx.LEFT, 10)
        self.label_attribute = wx.StaticText(self, label="")
        self.label_attribute.SetForegroundColour(wx.Colour(255, 0, 0))
        root_boxsier.Add(self.label_attribute, 0, wx.LEFT, 10)
        root_boxsier.Add(self.label_attribute, 0, wx.LEFT | wx.TOP | wx.RIGHT, 5)
        root_boxsier.Add(boxsier, 1, wx.ALL, 5)
        self.SetSizer(root_boxsier)
@@ -557,7 +600,8 @@
        self.Bind(wx.EVT_TIMER, self.clear_msg, self.timer)
    def clear_msg(self, event):
        self.notify_text.SetLabelText("")
        self.label_attribute.SetLabelText("")
        self.label_attribute.SetForegroundColour("#000000")
    def __ocr_code(self):
        code = self.edit_code.GetValue()
@@ -576,14 +620,14 @@
        self.edit_code.SetValue(code)
    def show_warning(self, content):
        self.notify_text.SetLabel(content)
        self.notify_text.SetForegroundColour("#FF7F27")
        self.label_attribute.SetLabel(content)
        self.label_attribute.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.label_attribute.SetLabel(content)
        self.label_attribute.SetForegroundColour("#008000")
        self.timer.Stop()
        self.timer.StartOnce(20000)
@@ -747,6 +791,19 @@
            self.check_auto_refresh.SetValue(True)
        else:
            self.check_auto_refresh.SetValue(False)
        auto_focus = setting.get_float_frame_auto_focus()
        if auto_focus:
            self.check_focus.SetValue(True)
        else:
            self.check_focus.SetValue(False)
        trade_quick_key = setting.get_float_frame_trade_quick_key()
        if trade_quick_key:
            self.check_trade_quick_key.SetValue(True)
        else:
            self.check_trade_quick_key.SetValue(False)
        self.__init_trade_state()
        self.__init_trade_mode()
@@ -792,9 +849,21 @@
        else:
            setting.set_ths_trade_auto_refresh(False)
    def __auto_focus_check(self, event):
        if event.Selection:
            setting.set_float_frame_auto_focus(True)
        else:
            setting.set_float_frame_auto_focus(False)
    def __trade_quick_key_check(self, event):
        if event.Selection:
            setting.set_float_frame_trade_quick_key(True)
        else:
            setting.set_float_frame_trade_quick_key(False)
    def __request(self, codes, type):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": type, "data": {"codes": codes}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -804,7 +873,7 @@
    def __request_list(self, type):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": type, "data": {}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -815,7 +884,7 @@
    def __request_buy(self, is_open):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 501, "data": {"open": is_open}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -827,7 +896,7 @@
    # 获取买入状态
    def __request_buy_state(self):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 502, "data": {}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -840,7 +909,7 @@
    def __request_buy_mode(self):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 504, "data": {}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -851,7 +920,7 @@
    def __request_set_buy_mode(self, mode):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 503, "data": {"mode": mode}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -863,7 +932,7 @@
    # 查询是否可以撤单
    def __request_can_cancel_buy(self, code):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 420, "data": {"codes": [code]}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -875,7 +944,7 @@
    # 撤单
    def __request_cancel_buy(self, code):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 80, "data": {"code": code}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -922,7 +991,7 @@
    def __request_attribute(self, code):
        client = socket.socket()  # 生成socket,连接server
        ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
        client.connect(ip_port)
        data = {"type": 430, "data": {"code": code}}
        client.send(json.dumps(data).encode("utf-8"))
@@ -930,16 +999,64 @@
        client.close()
        return result.decode("gbk")
    def focus(self, hwnd, code):
        try:
            int_buffer = array.array("L", [0])
            char_buffer = array.array('b',
                                      json.dumps({"type": "set_code", "data": {"code": code}}).encode())
            int_buffer_address = int_buffer.buffer_info()[0]
            char_buffer_address, char_buffer_size = char_buffer.buffer_info()
            copy_struct = struct.pack("PLP", int_buffer_address, char_buffer_size, char_buffer_address)
            win32gui.SendMessage(hwnd, win32con.WM_COPYDATA, None, copy_struct)
            # pythoncom.CoInitialize()
            # shell = client.Dispatch("WScript.Shell")
            # shell.SendKeys('%')
            # # win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
            # win32gui.SetForegroundWindow(hwnd)
            # win32gui.PumpMessages()
            # win32gui.SetFocus(hwnd)
            # lib = CDLL("D:/workspace/GP/dll/Dll/x64/Debug/Dll.dll")
            # win32gui.SendMessage(hwnd, win32con.WM_SETFOCUS, 0, 0)
            # print("执行结果", lib.focus(hwnd))
            # remote_thread = win32process.GetWindowThreadProcessId(hwnd)[0]
            # tid = win32api.GetCurrentThreadId()
            # win32process.AttachThreadInput(tid, remote_thread, True)
            # prev_handle = win32gui.SetFocus(hwnd)
            # print("之前的焦点句柄", prev_handle,hwnd)
        except Exception as e:
            logging.exception(e)
            pass
    def is_admin(self):
        try:
            return ctypes.windll.shell32.IsUserAnAdmin()
        except:
            return False
    # 设置代码,请求代码属性
    def setCode(self, code):
        # 获取代码属性描述
        #auto_focus = setting.get_float_frame_auto_focus()
        if True:
            print("是否有管理员权限", self.is_admin())
            # 窗口显示在最前面
            hwnds = win32_util.search_window("悬浮盯盘")
            if hwnds:
                print("句柄", hwnds[0])
                time.sleep(0.1)
                wx.CallAfter(lambda: self.focus(hwnds[0], code))
            # wx.CallAfter(lambda: self.SetFocus())
        try:
            result = self.__request_attribute(code)
            result = json.loads(result)
            if result['code'] == 0:
                code_info = result['data']['code_info']
                desc = f"{code_info[1]} {code_info[0]} {result['data']['desc']}"
                wx.CallAfter(lambda : self.label_attribute.SetLabelText(desc))
                wx.CallAfter(lambda: self.label_attribute.SetLabelText(desc))
        except Exception as e:
            wx.CallAfter(lambda: self.label_attribute.SetLabelText(str(e)))
@@ -1223,6 +1340,7 @@
                p.Size = (e.Size[0], p_height)
        self.timer.Stop()
        self.timer.StartOnce(1000)
        # 降低重绘频率
        # self.__re_draw()
@@ -1230,6 +1348,11 @@
        print("设置代码成功回调")
        p2.send("resub")
        self.__re_draw()
        self.timer.Stop()
        self.timer.StartOnce(1000)
        self.Size = wx.Size(self.Size[0], self.Size[1] + 10)
        time.sleep(0.1)
        self.Size = wx.Size(self.Size[0], self.Size[1] - 10)
# 绘图管理器
kpl/gui.py
@@ -309,7 +309,7 @@
            "type": type,
            "data": datas
        }
        requests.post("http://192.168.3.252:9004/upload_kpl_data", json.dumps(root_data))
        requests.post("http://111.230.16.67:9004/upload_kpl_data", json.dumps(root_data))
    def OnExit(self, e):
        sys.exit(0)
main.py
@@ -6,6 +6,7 @@
from multiprocessing import freeze_support
import sys
import torch
import win32gui
from PyQt5.QtGui import QFont, QPalette, QColor, QTextOption
from PyQt5.QtWebChannel import QWebChannel
@@ -15,14 +16,16 @@
from PyQt5.QtCore import Qt, pyqtSlot, QObject, pyqtSignal, QTimer, QUrl, QPoint
import constant
import gui_wx
import network_util
import setting
import tool
import win32_util
freeze_support()
URL_MSG_LIST = "http://192.168.3.252/kp/msg_list.html"
URL_MSG_LIST = f"http://{constant.WEB_HOST}/kp/msg_list.html"
class BaseBridgeClass(QObject):
@@ -89,6 +92,14 @@
    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()
@@ -96,18 +107,20 @@
    # 设置信息
    def setMsg(self, msg):
        # TODO 测试
        self.msgChange.emit(msg)
    def __init__(self):
        super().__init__()
        window_height = 80
        padding = 10
        window_info = setting.get_float_watch_window_info()
        if window_info:
            self.move(window_info[0] + padding - 3, window_info[1] - window_height - 30)
            self.resize(window_info[2] - (padding - 2) * 2, window_height)
        else:
            self.resize(300, 50)
        self.resize(300, 50)
        hwnds = win32_util.search_window("悬浮盯盘")
        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)
@@ -237,8 +250,8 @@
    # 设置目标代码
    def set_target_code(self, code):
        print("set_target_code")
        self.webview.page().runJavaScript(f"app.set_target_code('{code}')")
        self.wx_pipe.send(json.dumps({"type": "set_code", "code": code}))
        self.webview.page().runJavaScript(f"app.set_target_code('{code}')")
    # 菜单及菜单点击事件
    def __menu(self):
@@ -371,11 +384,11 @@
        self.setCentralWidget(self.webview)
        self.show()
        self.webview.load(QUrl("http://192.168.3.252/kp/index23-05-04.html"))
        self.webview.load(QUrl(f"http://{constant.WEB_HOST}/kp/index23-05-04.html"))
        # 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.252/kp/codes_list.html")
        self.secondWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/codes_list.html")
        # self.secondWindow.loadUrl("http://127.0.0.1:8848/kp/codes_list.html")
        # 绑定槽函数
network_util.py
@@ -3,14 +3,15 @@
import requests
SERVER_HOST = "192.168.3.252"
import constant
SOCKET_PORT = 9001
HTTP_PORT = 9004
def socket_request(data):
    client = socket.socket()  # 生成socket,连接server
    ip_port = (SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
    ip_port = (constant.SERVER_HOST, SOCKET_PORT)  # server地址和端口号(最好是10000以后)
    client.connect(ip_port)
    client.send(json.dumps(data).encode("utf-8"))
    # 读取内容
setting.py
@@ -35,6 +35,7 @@
    cp = __read_setting()
    return int(cp.get("config", "stay_on_top"))
# -------------------------------客户端标识--------------------------
# 设置是否置顶
def set_client(client):
@@ -255,6 +256,42 @@
        return val
# 获取悬浮盯盘是否可以自动获取焦点
def set_float_frame_auto_focus(can_focus):
    cp = __read_setting()
    cp.set("config", "float_frame_auto_focus", f"{1 if can_focus else 0}")
    __write_setting(cp)
def get_float_frame_auto_focus():
    cp = __read_setting()
    val = __get_setting(cp, "config", "float_frame_auto_focus")
    if val is None:
        return False
    else:
        if int(val) > 0:
            return True
        return False
# 获取悬浮盯盘是否可以自动获取焦点
def set_float_frame_trade_quick_key(can_focus):
    cp = __read_setting()
    cp.set("config", "float_frame_trade_quick_key", f"{1 if can_focus else 0}")
    __write_setting(cp)
def get_float_frame_trade_quick_key():
    cp = __read_setting()
    val = __get_setting(cp, "config", "float_frame_trade_quick_key")
    if val is None:
        return False
    else:
        if int(val) > 0:
            return True
        return False
if __name__ == "__main__":
    print(get_ths_auto_click_time_space())
    set_ths_auto_click_time_space(1000)
test.png

test.py
@@ -1,9 +1,10 @@
import datetime
import json
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
class MainWindow(QtWidgets.QMainWindow):
@@ -22,6 +23,12 @@
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    browser = MainWindow()
    sys.exit(app.exec())
    # app = QtWidgets.QApplication(sys.argv)
    # browser = MainWindow()
    # sys.exit(app.exec())
    # test =""
    # print(test)
    n = datetime.datetime.now()
    data = {"t": n.microsecond}
    print(json.dumps(data))
win32_util.dll
Binary files differ