欢迎光临UUpython
最大、最新、最全的Python代码收集站

[GUI]插入排序演示

uupython阅读(362)

这段代码实现了一个使用 tkinter 绘制动画演示插入排序的小程序。程序随机生成一个包含 1 到 30 的数字列表,然后展示每一步插入排序的过程。

主要步骤如下:

  1. insertSort() 函数:生成一个随机数组并保存插入排序的每一步结果到 sortL 列表中。每一步排序后的结果都被保存。
  2. draw() 函数:根据 sortL 列表的内容,绘制排序的过程。通过 canvas 组件在窗口中绘制矩形条和相应的数字。
  3. 创建主窗口 root,设置标题、大小、位置、不可调整大小等属性。
  4. 创建 “单步排序” 按钮 stepBtn 和 “重置数据” 按钮 resetBtn,分别对应单步演示和重置数据操作。
  5. 创建 canvas 组件用于绘制矩形条和数字,设置背景颜色、高度、宽度等属性。
  6. 在循环中根据排序过程,绘制矩形条和相应的数字。在绘制的过程中,如果当前索引等于正在排序的数字的索引,则使用红色标记。
  7. 通过点击 “单步排序” 按钮,可以逐步演示排序过程。
  8. “重置数据” 按钮可以重新生成随机数据并重置排序过程。
  9. 程序在运行后会自动调用 insertSort() 生成随机数据并调用 draw() 绘制排序过程。
  10. 最后通过 root.mainloop() 进入主循环,等待用户交互。

请注意,这个程序在 tkinter 窗口中展示了插入排序的排序过程,可以点击 “单步排序” 按钮以步骤方式演示排序,点击 “重置数据” 按钮可以重新生成随机数据并重置排序过程。

# coding: utf-8
import tkinter as tk
import random
import copy
import tkinter.messagebox
 
width = 30  # 矩形条宽度
x0 = 80  # 矩形条x轴初始值
y0 = 350  # 矩形条最高度
index = 0  # 待排序数字的下标标记
sortL = []  # 存储插入排序的每一步结果
 
root = tk.Tk()
root.title("动画演示插入排序")
root.geometry('640x500+250+250')
root.resizable(False, False)
 
def insertSort():
    """
    生成随机数组, 并且保存插入排序的每步结果, 保存到sortL
    :param num:
    :return:
    """
    global sortL
    # 随机生成数据列表
    num = [i for i in range(1, 31, 1)]
    random.shuffle(num)
    num = num[:15]  # 取随机数组的前15个组成列表
 
    sortL.append(copy.deepcopy(num))  # 存储每次排序结果
    # 插入排序算法
    for i in range(1, len(num)):
        key = num[i]
        j = i - 1
        while j >= 0 and key < num[j]:
            num[j + 1] = num[j]
            j -= 1
        num[j + 1] = key
        sortL.append(copy.deepcopy(num))  # 存储每次排序结果
    sortL.append(copy.deepcopy(num))
 
 
def draw():
    """
    绘制结果
    :return:
    """
    global width, x0, y0, index, sortL
    x0 = 80  # x 坐标初始化
    print(sortL[index])
 
    def step():
        # 删除每一个矩形以及字符
        for i in range(15):
            canvas.delete(str(i))
            canvas.delete("string" + str(i))
        draw()  # 重新绘制
    stepBtn = tk.Button(root, text="单步排序", width=8, height=1, command=step)
    stepBtn.place(x=200, y=420)
 
    def reset():
        global index
        index = 0
        sortL.clear()  # 清空结果列表
        insertSort()  # 执行插入排序算法
        draw()  # 绘制结果列表中的每一项
    resetBtn = tk.Button(root, text="重置数据", width=8, height=1, command=reset)
    resetBtn.place(x=350, y=420)
 
    canvas = tk.Canvas(root, bg='white', height=400, width=1000)
    canvas.place(x=0, y=0)
    for i in range(15):
        # 绘制矩形条
        if index + 1 == i:  # 用红色标记待排序的数字
            canvas.create_rectangle(x0, y0 - sortL[index][i] * 10,
                                    x0 + width, y0, width=3, fill='red',
                                    tags=str(i))
        else:
            canvas.create_rectangle(x0, y0 - sortL[index][i] * 10, x0 + width,
                                    y0, width=3, tags=str(i))
        # 绘制文本
        canvas.create_text(x0 + width // 2, y0 - sortL[index][i] * 10 -
                           width // 2, text=str(sortL[index][i]),
                           font="time 10 bold underline",
                           tags="string" + str(i))
        x0 = x0 + width
    if index == 14:
        tk.messagebox.showinfo('信息', '排序完成')
    index += 1
 
 
if __name__ == "__main__":
    insertSort()
    draw()
    root.mainloop()

os模块重命名手机照片

uupython阅读(382)

这段代码是用来将特定文件夹内的 .jpg 图像文件按照一定规则进行重命名的操作。这里的规则是将文件名中 IMG_ 后的数字部分提取出来,并以数字的顺序重新命名文件。

以下是代码的主要部分:

  1. reg 正则表达式对象:用于从文件名中提取 IMG_ 后的数字部分。
  2. path:需要进行处理的文件夹路径。
  3. os.walk(path):遍历路径下的所有文件和子文件夹,获取每个文件夹的路径(dirpath)、子文件夹列表(_)和文件名列表(filename)。
  4. glob(osp.join(dirpath, '*.jpg')):使用 glob 函数获取当前文件夹下所有 .jpg 文件的列表。
  5. 遍历 jpgs 列表,对每个 .jpg 文件进行处理:
  • 提取文件名中的数字部分。
  • 使用索引加一(格式化为两位数)作为新的文件名。
  • 构建新的文件路径 dst
  • 使用 os.rename() 函数进行重命名。

注意:

  • 该代码根据文件名中 IMG_ 后的数字部分进行重命名,但在文件名中没有 IMG_ 的情况下,可能会出现错误。你可能需要添加一些条件来处理这种情况。
  • 在进行文件重命名时,需要确保新的文件名是唯一的,否则可能会覆盖已有的文件。在你的代码中,使用索引 jpgs.index(jpg) 确保了新文件名的唯一性。
  • 代码中有一段注释掉的部分,似乎是将文件名中的 '微信截图' 替换为 'IMG',但是这段代码没有被执行,你可以根据需要进行调整。
  • 文件操作涉及文件重命名,建议在实际操作前备份文件,以防止意外的数据损失。
import os
import os.path as osp
import re
import shutil
from glob import glob
reg=re.compile(r'(?<=IMG_).*')
 
path=r'./'
for dirpath,_,filename in os.walk(path):
        jpgs=glob(osp.join(dirpath,'*.jpg'))        
        if jpgs:
                for jpg in jpgs:
                        name,_=osp.splitext(jpg)
                        nm=osp.basename(name)
                        mat=reg.search(nm)
                        if mat:
                                res=str(jpgs.index(jpg)+1).zfill(2)
                                print(res)
                                src=jpg
                                dst=osp.join(dirpath,res+'.jpg')
                                os.rename(src,dst)
                                 
 
# for dirpath,_,filename in os.walk('./'):
#   jp=glob(osp.join(dirpath,'*.jpg'))
#   for s in jp:
#       jg=s.replace('微信截图','IMG')
#       os.rename(s,jg)                                

微信机器人

uupython阅读(624)

import pymysql
from flask import Flask, request, jsonify
import json
import requests
from wx_api import send_message, query_info_by_wxid, query_group_list, query_group_members, confirm_payment,agree
from find_info import get_wx_info
from datetime import datetime
 
 
app = Flask(__name__)
# 连接到本地 MySQL 数据库
connection = pymysql.connect(host='localhost', user='root', password='123456', database='KGGOGO', charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
 
def process_event_10009(message_dict):
    rootID = "wxid_0q2jr040l8hf22"
    rootID1 = "1"
    #群ID
    fromWxid = message_dict['data']['data'].get('fromWxid')
    msg = message_dict['data']['data'].get('msg')
    timeStamp = message_dict['data']['data'].get('timeStamp')
 
    #管理员功能
    if fromWxid == rootID or fromWxid == rootID1:
        #上传商品命令 XX团购XX元
        if '功能' in msg:
            send_message(fromWxid, "命令包含:\n 功能:查询功能和其命令 \n XX团购XX元:上传XX商品 团购一份价格为XX\n修改XX为XX元:修改XX商品,价格一份变为XX元)\n 开始接龙XX:开始接龙XX商品,")
        if '团购' in msg and '元' in msg :
            # 获取商品名称和价格
            start_idx = msg.index('团购')
            start_idx1 = msg.index('团购') + 2
            end_idx = msg.index('元')
            name = msg[0:start_idx]
            price = msg[start_idx1:end_idx]
            # 添加到数据库
            try:
                with connection.cursor() as cursor:
                    # 插入数据到商品列表表中
                    sql1 = "select `商品名称` from `商品列表` where `商品名称` = %s "
                    cursor.execute(sql1,(name,))
                    result = cursor.fetchall()
                    if result:
                        send_message(fromWxid, f" {name} 商品已经有了,可以更改其价格或上传其他商品 ")
                    else:
                        sql2 = "INSERT INTO `商品列表` (`商品名称`, `团购价格`) VALUES (%s, %s)"
                        cursor.execute(sql2, (name, price))
                        # 提交更改
                        connection.commit()
                        send_message(fromWxid, f"上传商品成功\n上传 {name} 商品 一份{price}元")
            except Exception as e:
                send_message(fromWxid, f"错误{e},请联系管理员")
 
        if '删除' in msg:
            try:
                start_idx = msg.index('删除') + 2
                end_idx = msg.index('商')
                name = msg[start_idx:end_idx]
                #删除某商品
                with connection.cursor() as cursor:
                    sql = "DELETE FROM `商品列表` WHERE `商品名称` = %s "
                    cursor.execute(sql, (name,))
 
                # 提交更改
                connection.commit()
                send_message(fromWxid, f"商品 {name} 已删除。")
 
            except Exception as e:
                send_message(fromWxid, f"错误{e},请联系管理员")
 
        if '修改' in msg and '为' in msg and '元' in msg:
            try:
                # 获取商品名称和价格
                start_idx = msg.index('修改') + 2
                end_idx = msg.index('为')
                name = msg[start_idx:end_idx]
 
                start_idx = msg.index('为') + 1
                end_idx = msg.index('元')
                price = msg[start_idx:end_idx]
 
                # 更新商品价格到数据库
                with connection.cursor() as cursor:
                    sql = "UPDATE `商品列表` SET `团购价格` = %s WHERE `商品名称` = %s"
                    cursor.execute(sql, (price, name))
 
                # 提交更改
                connection.commit()
                send_message(fromWxid, f"商品'{name}'的价格已更新为'{price}'元。")
 
            except Exception as e:
                send_message(fromWxid, f"错误{e},请联系管理员")
        #商品 或 团品 查询 已经有的商品和价格列表
        if '商品' in msg or '团品' in msg :
            try:
                # 查询商品列表和价格
                with connection.cursor() as cursor:
                    sql = "SELECT `商品名称`, `团购价格` FROM `商品列表`"
                    cursor.execute(sql)
                    result = cursor.fetchall()
 
                # 输出查询结果
                if result:
                    for row in result:
                        send_message(fromWxid,f"商品名称:{row['商品名称']},团购价格:{row['团购价格']}元")
                else:
                    send_message(fromWxid,"暂无商品信息。")
 
            except Exception as e:
                send_message(fromWxid, f"错误{e},请联系管理员")
 
 
        #停止接龙命令 ,让数据库 拼单状态为1的=0
        elif '截单' in msg:
            try:
                # 获取数据库游标
                with connection.cursor() as cursor:
                    # 将拼单状态为1的记录更新为0
                    sql_update  = "UPDATE 团购单号信息表 SET 是否在接龙 = 0 "
                    sql_update1 = "UPDATE 商品列表 SET 是否正在接龙 = 0 "
                    sql_update2 = "UPDATE 接龙 SET 是否接龙 = 0 "
                    sql_update3 = "UPDATE 接龙 SET 接龙msg = '' "
                    cursor.execute(sql_update)
                    cursor.execute(sql_update1)
                    cursor.execute(sql_update2)
                    cursor.execute(sql_update3)
                    # 提交更改
                connection.commit()
                send_message(fromWxid, "已截单")
            except Exception as e:
                # 处理可能的异常
                send_message(fromWxid, f"错误{e},截单失败,请联系管理员")
        #开始接龙命令 开始接龙XX ,查找该商品,并且使其是否正在接龙=1,并在团购订单信息中添加信息
 
        elif '开始接龙' in msg:
            # 将时间戳转换为 datetime 对象
            timeStamp = float(timeStamp)
            dt_object = datetime.fromtimestamp(timeStamp / 1000.0)  # 需要除以1000转换为秒
            # 将 datetime 对象格式化为字符串
            formatted_time = dt_object.strftime('%Y%m%d')
          # 格式化后的时间字符串,例如:20230807
            try:
                # 获取数据库游标
                with connection.cursor() as cursor:
                    # 获取商品名称
                    start_idx = msg.index('开始接龙') + 4
                    name = msg[start_idx:]
 
                    # 在"商品列表"表中查找商品
                    sql_select = "SELECT * FROM 商品列表 WHERE 商品名称 = %s"
                    cursor.execute(sql_select, (name,))
                    result = cursor.fetchone()
 
                    if result:
                        dingdanhao = formatted_time + name
                        sql1 = "SELECT `团购价格` FROM `商品列表` WHERE 商品名称 = %s"
                        cursor.execute(sql1, (name,))
                        result = cursor.fetchone()
                        price = result['团购价格']
                        # 如果商品存在,插入新的团购信息到团购单号信息表中
                        sql_insert = "INSERT INTO `团购单号信息表` (`团购单号`, `商品`, `商品价格`, `是否在接龙`) VALUES (%s, %s, %s,%s)"
                        cursor.execute(sql_insert, (dingdanhao, name, price,1))
 
 
                        # 更新商品列表中的是否正在接龙状态为1
                        sql_update2 = "UPDATE 商品列表 SET 是否正在接龙 = 1 WHERE 商品名称 = %s"
                        cursor.execute(sql_update2, (name,))
 
                        connection.commit()
 
                        send_message(fromWxid, "开始成功,机器人开始工作啦")
                    else:
                        # 如果商品不存在,返回提示信息
                        send_message(fromWxid,f"商品列表没有{name}商品,请上传后再接龙。")
            except Exception as e:
                # 处理可能的异常
                send_message(fromWxid, f"错误{e},开始接龙失败,请联系管理员")
        #没付款查询
        elif '没付款' in msg:
            try:
            # 获取数据库游标
                with connection.cursor() as cursor:
                    sql = "SELECT 微信名称 FROM 团购信息 WHERE 是否付款 = 0"
                    cursor.execute(sql)
                    result = cursor.fetchone()
                    send_message(fromWxid, result)
                connection.commit()
            except Exception as e:
                # 处理可能的异常
                send_message(fromWxid, f"错误{e},查询失败,请联系管理员")
 
        #查询团购谁没拿的命令
        elif '没拿' in msg:
            try:
                # 获取数据库游标
                with connection.cursor() as cursor:
                    # 查询拼单状态为0的微信名称
                    sql = "SELECT 微信名称,团购商品 FROM 团购信息 WHERE 是否已领 = 0"
                    cursor.execute(sql)
                    result = cursor.fetchall()
                    wx_and_goods = [(row['微信名称'], row['团购商品']) for row in result]
                    send_message(fromWxid, wx_and_goods)
                connection.commit()
            except Exception as e:
                # 处理可能的异常
                send_message(fromWxid, f"错误{e},查询失败,请联系管理员")
    else:
        # 会员,付款和完成订单,积分以及积分 查询兑换
        #首先如果没在数据库,进入数据库
        if '积分' in msg:
            try:
                # 获取数据库游标
                with connection.cursor() as cursor:
                    # 查询wxid所在行的剩余积分
                    sql = "SELECT 剩余积分 FROM wx会员 WHERE 微信ID = %s"
                    cursor.execute(sql, (fromWxid,))
                    result = cursor.fetchone()
 
                    if result:
                        remaining_points = result['剩余积分']
                        send_message(fromWxid, f"你的积分为{remaining_points}。")
                        send_message(fromWxid, "输入'兑换'可以积分兑换鸡蛋,100积分获得五个鸡蛋。鸡蛋需要当天领取")
            except Exception as e:
                # 处理可能的异常
                send_message(fromWxid, "异常错误,请联系管理员")
        elif '兑换' in msg:
            try:
                # 获取数据库游标
                with connection.cursor() as cursor:
                    # 查询wxid所在行的剩余积分
                    sql = "SELECT 剩余积分 FROM wx会员 WHERE 微信ID = %s"
                    cursor.execute(sql, (fromWxid,))
                    result = cursor.fetchone()
 
                    if result:
                        remaining_points = result['剩余积分']
 
                        if remaining_points >= 100:
                            # 更新剩余积分和已兑换积分并输出兑换成功信息
                            new_remaining_points = remaining_points - 100
                            sql_update = "UPDATE wx会员 SET 剩余积分 = %s, 已兑换积分 = 已兑换积分 + 100 WHERE 微信ID = %s"
                            cursor.execute(sql_update, (new_remaining_points, fromWxid))
                            connection.commit()
                            send_message(fromWxid, "兑换成功,请当天领取鸡蛋。")
                        else:
                            send_message(fromWxid, "剩余积分不足100。")
            except Exception as e:
                # 处理可能的异常
                send_message(fromWxid, "异常错误,请联系管理员")
 
        elif '完成' in msg:
            try:
                # 获取数据库游标
                with connection.cursor() as cursor:
                    # 更新团购信息表中对应wxid的行,将完成状态设置为1
                    sql_update = "UPDATE 团购信息 SET 是否完成 = 1,是否领取 =1 WHERE 微信ID = %s"
                    cursor.execute(sql_update, (fromWxid,))
                    #查询团购信息,用wx查询订单,是否付款,如果付款=1,增加 商品价格*份数   ,else print(“机器人没收到付款,统计功能失败,可以联系管理员”)
                    #缺少订单唯一标识
                    sql_update1 = "UPDATE vx会员 SET 历史获得积分 = 1,已兑换积分 =1 WHERE 剩余积分 = %s"
                    connection.commit()
                    print("团购信息已更新,已完成团购。")
            except Exception as e:
                # 处理可能的异常
                print("更新团购信息失败:", e)
        elif '成为会员' in msg:
        # 如果 wxid 不在本地表中
            if not is_wxid_in_local_table(fromWxid):
                # 查询用户信息并添加到本地 MySQL 数据库的 wx会员 表和团购信息表
                user_info = query_user_info(fromWxid)
                if user_info:
                    add_user_to_local_table(user_info)
                    send_message(fromWxid,"恭喜成为会员,团购积累积分可兑换鸡蛋,100积分兑换5个鸡蛋")
 
 
def process_event_10003(message_dict):
    # 确认收款,看收款的金额是否正确,正确接受,并查询数据,上传确认付款
    money = user_dict['data']['data'].get('money')
    fromWxid = user_dict['data']['data'].get('fromWxid')
    transferid = user_dict['data']['data'].get('transferid')
    nick = get_wx_info(fromWxid).get('nick')
    #从数据库团购单号信息找到正在团购的商品单号,
 
    dingdanhao = dingdanhao + '-' + wx_info['nick']
    sql_query = "SELECT 份数, 团品价格 FROM 团购信息 WHERE wxid = %s and 是否付款 = 0 and 订单号 = %s"
    cursor.execute(sql_query, (fromWxid, dingdanhao))
 
    result = cursor.fetchone()
 
    if result:
        groupbuy_count = result['份数']
        groupbuy_price = result['团品价格']
 
        # 计算期望收款金额
        expected_money = groupbuy_count * groupbuy_price
 
        if money == expected_money:
            confirm_payment(fromWxid, transferid)
            a = f"您已经付款成功,一共收到{money}元。/n拿到团品后输入完成可获得积分哦,积分可以兑换鸡蛋,但是请不要提前输入完成)"
            send_message(fromWxid,a)
        else:
            # 输出金额不正确的提示信息
            error_msg = f"您定了{groupbuy_count}份,一份{groupbuy_price}元,需要转账{expected_money}元,数额不对无法收款,请转账准确金额,多余金额24小时后自动退款"
            send_message(fromWxid,error_msg)
    else:
        # 输出找不到团购信息的提示信息
        print("找不到对应的团购信息,无法确认收款。")
 
 
def process_event_10008(message_dict):
    wxid = message_dict.get('wxid')
    des = message_dict['data'].get('des')
    timeStamp = message_dict['data']['data'].get('timeStamp')
    fromWxid = message_dict['data']['data'].get('fromWxid')
    finalFromWxid = message_dict['data']['data'].get('finalFromWxid')
    msg = message_dict['data']['data'].get('msg')
 
    # 在这里进行 event 为 10008 的逻辑处理
    # 如果 msg 中包含 "#接龙" 字样,执行接龙功能
    if "接龙" in msg:
        result = do_jielong(fromWxid,finalFromWxid, msg,timeStamp)
        return result
 
def process_event_10011(message_dict):
    v3 = message_dict['data']['data']['v3']
    v4 = message_dict['data']['data']['v4']
    wxid =message_dict['data']['data']['wxid']
    response_data = agree(v3, v4)
    if response_data["msg"] == "操作成功":
        send_message(wxid, "向我发送 '成为会员',成功团购就可获得积分,积分可兑换鸡蛋哦 ")
 
def do_jielong(fromWxid,finalFromWxid,msg,timeStamp):
    info = get_wx_info(finalFromWxid)
    # 如果是新的接龙信息,储存该信息
    # 这里查询数据库 接龙 开始接龙为1的
    try:
        with connection.cursor() as cursor:
            # 查询接龙msg,where 所在群 = ‘’
            sql = "SELECT `接龙msg` FROM `接龙` WHERE `所在群` = %s"
            cursor.execute(sql, (fromWxid,))
            result = cursor.fetchone()
            jielong_info = result.get('接龙msg', '')
    except Exception as e:
        send_message(fromWxid, f"错误{e},请联系管理员")
    #管理员在群里发送#接龙 让大家接龙
    if "#接龙" in msg and not jielong_info:
 
    #上传数据库 ’接龙msg‘表  , 表里有     团购单号       接龙  是否接龙  是否截单  ,接龙是否为空
        jielong_info = msg
    #更新数据库 接龙 信息
        reply = "大家好,接龙开始了!\n加我好友,群里直接回复’接龙+份数‘就可以参与接龙了。\n接龙更方便"
        # 更新 '接龙msg' 字段
        try:
            with connection.cursor() as cursor:
                # 更新接龙msg字段
                sql = "UPDATE `接龙` SET `接龙msg` = %s WHERE `所在群` = %s"
                cursor.execute(sql, (jielong_info, fromWxid))
                connection.commit()
                send_message(fromWxid, reply)
        except Exception as e:
            send_message(fromWxid, "失败,可以联系管理员")
 
    # 如果接龙信息已储存,且有人回复“我要接龙”,无论会员不会员,更新接龙信息,
    #查询数据库  接龙为1 的行里 接龙是否不空
    elif "#接龙" in msg and jielong_info and len(msg)>20:
        try:
            with connection.cursor() as cursor:
                # 更新接龙msg字段
                sql = "UPDATE `接龙` SET `接龙msg` = %s WHERE `所在群` = %s"
                cursor.execute(sql, (msg, fromWxid))
                connection.commit()
                return True  # 更新成功返回True
 
        except Exception as e:
            print("数据库更新出错:", str(e))
            return False  # 更新失败返回False
#判断是否为会员
    elif "接龙" in msg and "#接龙" not in msg and jielong_info:
        try:
            with connection.cursor() as cursor:
                # 查询wxid所在行的信息
                sql = "SELECT * FROM wx会员 WHERE 微信ID = %s"
                cursor.execute(sql, (wxid,))
                result = cursor.fetchone()
 
                if result:
                    nick = info.get('nick')
                    msg1 = chinese_number_to_integer(msg)
                    if jielong_number_match:
                        jielong_number = re.search(r'\d+', msg1)
                    else:
                        # 如果没有找到接龙份数,则默认为一份
                        jielong_number = 1
 
                    if nick:
                        jielong_info += f"\n{len(jielong_info.splitlines())}. {nick.strip()} {jielong_number}份"
                        # 发送接龙信息到群里
                        send_message(wxid, jielong_info)
                        try:
                            with connection.cursor() as cursor:
                                # 更新接龙msg字段
                                sql = "UPDATE `接龙` SET `接龙msg` = %s  WHERE `所在群` = %s"
                                cursor.execute(sql, (msg, fromWxid))
                                connection.commit()
                                return True  # 更新成功返回True
 
                        except Exception as e:
                            print("数据库更新出错:", str(e))
                            return False  # 更新失败返回False
                        #从团购单号信息表找取 是否在接龙 = 1 的 名称 价格 单号
                        groupbuy_info = query_groupbuy_info()
                        if groupbuy_info:
                            # 将会员参与团购信息添加到本地 MySQL 数据库的 #添加到团购信息里
                            add_groupbuy_to_local_table(groupbuy_info, finalFromWxid,fromWxid,jielong_number)
 
                        # 向用户发送一串信息
                        send_auto_reply(FromWxid, "您已成功参与接龙,谢谢!")
                        send_auto_reply(FromWxid, "金额可直接转我,订单完成后积分")
 
 
                else:
                    content = "你好我是接龙小机器人,添加我好友后,向我发送'成为会员'在群里发送'接龙'可以直接参与接龙哦"
                    send_message(fromWxid, content)
                    return
 
        except Exception as e:
            print("数据库查询出错:", str(e))
            return None
 
 
def is_wxid_in_local_table(wxid):
    with connection.cursor() as cursor:
        sql = "SELECT COUNT(*) AS count FROM `wx会员` WHERE `微信ID`=%s"
        cursor.execute(sql, (wxid,))
        result = cursor.fetchone()
        return result['count'] > 0
 
 
def query_user_info(wxid):
    user_info = []
    info = get_wx_info(wxid)
    nick = info.get('nick')
    vxid = info.get('wxid')
    wxNum = info.get('wxNum')
    user_info.append((nick, vxid, wxNum))
    return user_info
 
 
def add_user_to_local_table(user_info):
    # 在这里实现将用户信息添加到本地 MySQL 数据库的数据表
    with connection.cursor() as cursor:
        sql = "INSERT INTO `wx会员` (`微信名称`, `微信ID`, `微信号`) VALUES (%s, %s, %s)"
        cursor.executemany(sql, user_info)
 
        sql1 = "INSERT INTO `会员团购表` (`微信名称`, `微信ID`, `微信号`) VALUES (%s, %s, %s)"
        cursor.executemany(sql1, user_info)
 
        connection.commit()
 
 
def query_groupbuy_info():
    groupbuy_info = []
    with connection.cursor() as cursor:
        sql = "SELECT 商品, 商品价格, 团购单号 FROM 团购单号信息表 WHERE 是否在接龙 = 1"
        cursor.execute(sql)
        result = cursor.fetchone()
 
        if result:
            商品名称 = result["商品"]
            商品价格 = result["商品价格"]
            团购单号 = result["团购单号"]
            groupbuy_info.append((商品名称, 价格, 团购单号))
 
    return groupbuy_info
 
 
def add_groupbuy_to_local_table(info, wxid,a,jielong_number):
    wx_info = get_wx_info(wxid)
    dingdanhao=info[0][2] + '-' + wx_info['nick']
    with connection.cursor() as cursor:
        sql = "INSERT INTO `团购信息` (`微信名称`, `微信ID`, `微信号`, `所在群`, `团购单号`, `团购商品`, `商品价格`, `份数`, `订单号`) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)"
        cursor.execute(sql, (wx_info['nick'], wx_info['wxid'], a,wx_info['wxNum'], info[0][2], info[0][0], info[0][1],jielong_number,dingdanhao),)
 
def chinese_number_to_integer(chinese_number):
    chinese_numbers = {
        "一": 1, "二": 2, "三": 3, "四": 4, "五": 5,
        "六": 6, "七": 7, "八": 8, "九": 9, "十": 10,
        "十一": 11, "十二": 12, "十三": 13, "十四": 14, "十五": 15,
        "十六": 16, "十七": 17, "十八": 18, "十九": 19, "二十": 20,
        "二十一": 21, "二十二": 22, "二十三": 23, "二十四": 24, "二十五": 25,
        "二十六": 26, "二十七": 27, "二十八": 28, "二十九": 29, "三十": 30,
        "三十一": 31, "三十二": 32, "三十三": 33, "三十四": 34, "三十五": 35,
        "三十六": 36, "三十七": 37, "三十八": 38, "三十九": 39, "四十": 40,
        "四十一": 41, "四十二": 42, "四十三": 43, "四十四": 44, "四十五": 45,
        "四十六": 46, "四十七": 47, "四十八": 48, "四十九": 49, "五十": 50
    }
 
    number = ""
    result = 0
    for char in chinese_number:
        if char in chinese_numbers:
            number += str(chinese_numbers[char])
        else:
            number += char
 
    try:
        result = int(number)
    except ValueError:
        print("Invalid input")
 
    return result
 
@app.route('/callback', methods=['POST'])
def receive_message():
    message = request.get_data()
    message_dict = json.loads(message.decode('utf-8'))
 
    event = message_dict.get('event')
 
    if event == 10008:
        result = process_event_10008(message_dict)
        return jsonify({"status": "success", "result": result})
 
    elif event == 10009:
        result = process_event_10009(message_dict)
        return jsonify({"status": "success", "result": result})
 
    elif event == 10003:
        result = process_event_10003(message_dict)
        return jsonify({"status": "success"})
 
    elif event == 10011:
        result = process_event_10011(message_dict)
        return jsonify({"status": "success"})
 
    return jsonify({"status": "success"})
 
 
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

批量打印excel文件

uupython阅读(342)

这段代码涉及文件处理、正则表达式、打印操作以及文件排序等功能。以下是代码的主要部分:

  1. reg 正则表达式对象:用于从字符串中提取数字开头的序号。
  2. path1:文件夹路径,其中包含需要打印的文件。
  3. ls 列表:存储一系列字符串,每个字符串表示一个文件名。
  4. lss 列表:将 ls 列表切分成每个子列表包含 15 个文件名。
  5. lt 列表:存储从 ls 列表中每个文件名提取的数字开头的序号。
  6. lg 列表:获取文件夹下以数字开头的文件名(带有 id 号)。
  7. lg.sort():对 lg 列表进行排序,排序的依据是将数字开头的序号按照 lt 列表中的顺序排列。
  8. patt 正则表达式对象:用于匹配文件名中是否包含 .xlsx 后缀。
  9. files 列表:通过筛选文件名后缀为 .xlsx,得到文件名的完整路径。
  10. win32api.ShellExecute():调用 Windows API,执行打印操作,第一个参数是命令,这里是 "print",第二个参数是要打印的文件名,第三个参数是工作目录,这里是 "." 表示当前目录。
  11. time.sleep(5):等待 5 秒,以便打印操作有足够的时间完成。
  12. 最后的循环遍历 files 列表,执行打印操作,并输出打印完成信息。

注意:

  • 这段代码假设系统中有关于 .xlsx 后缀的默认打印程序。如果需要将文件打印到特定的打印机或以特定的打印设置进行打印,可能需要更多的配置。
  • 打印时间的等待可以根据实际情况进行调整。
  • 在使用 win32api.ShellExecute() 时,需确保对应的 .xlsx 文件可以被默认打印程序正确解析和打印。
  • 请确保在实际使用中考虑错误处理和程序的鲁棒性。
import re
import os
import os.path as osp
import win32print
import tempfile
import win32api
import shutil
import time
reg=re.compile(r'^\d+')#正则表达式
 
path1=r'G:\桌面\新建文件夹\打印1'
 
ls=['32657-华为T园区3号楼-PTN7900-SPEH1','32665-华为T园区4号楼-PTN7900-SPEH1','12033-大朗1扩壹-PTN7900-SPNH1','12041-大朗4扩壹-PTN7900-SPNH1','16161-樟木头1扩壹-PTN7900-SPNH1',
'16169-樟木头4-PTN7900-SPNH1','16201-凤岗7-PTN7900-SPNH1','20233_SPNH5/1_常平2_7900E-12','3953-万江3-PTN7900-SPNH1','3961-万江4-PTN7900-SPNH1','7937_SPNH2/1_寮步3_7900E-12',
'3881_SPNH1/2_柏洲边_7900E-24','8017-石排2-SPNH1-7900E','8009-石排4-SPNH1-7900E','20321-横沥6-PTN7900-SPNH1','20264-横沥2-PTN7900-SPNH1','20225-常平第三机房-PTN7900-SPNH1',
'120249-常平第八机房-PTN7900-SPNH1','108025-大朗第三机房-PTN7900-REG石排-SPNH1','6097_大朗PTNH10_大朗1扩壹_PTN7900','6113_大朗PTNH10_大朗2_PTN7900','10161_常平PTNH10_常平4_PTN7900',
'10145_常平PTNH10_常平3_PTN7900','20265-横沥2-PTN7900-SPNH1.1','20257-横沥4-PTN7900-SPNH1','3865_SPNH1/1_牛山_7900E-24','20361-常平第二传输机房-PTN7900-企石REG-SPNH1',
'20369-常平第二传输机房-PTN7900-谢岗REG-SPNH1','5265_城区PTNH26_篁胜扩容壹_PTN7900','19777_城区PTNH31_柏洲边_PTN7900','19761_城区PTNH31_温塘二市_PTN7900','16177-清溪3-PTN7900-SPNH1',
'16185-清溪4-PTN7900-SPNH1','20289-桥头3-PTN7900-SPNH1','20297-桥头2扩壹-PTN7900-SPNH1','16153-塘厦第二传输机房六楼-PTN7900-SPNH1','16129-塘厦镇第五传输机房七楼-PTN7900-SPNH1',
'12113-东坑4-PTN7900-SPNH1','12121-东坑5-PTN7900E-东坑SPNH汇聚环1','26417-东城4-PTN7900E-东城SPNH汇聚环2','26385-蓢基湖-PTN7900-SPNH2','26401-寮步2扩壹-PTN7900-SPNH2','26409-寮步5-PTN7900-SPNH2',
'20345-桥头4-PTN7900-SPNH1','20353-桥头5-PTN7900-SPNH1','8065_寮步PTNH12_寮步3_PTN7900','8081_寮步PTNH12_寮步4_PTN7900','43010-麻涌2-PTN6700-SPNZ1','143011-麻涌1扩壹-PTN6700-麻涌SPNZ汇聚1',
'42498-中堂1扩壹-PTN6700-SPNZ1','42499-中堂4-PTN6700-SPN1','17665_桥头PTNH1_桥头1扩壹PTN3900','17666-桥头2-PTN3900-桥头1']
 
lss=[ls[x:x+15] for x in range(0,len(ls),15)]
 
lt=[]
for i in ls:
    t=reg.search(i).group()#正则表达式提取
    lt.append(t)
 
lg=os.listdir(path1)#带有id号开头的名字很长的xlsx文件列表
lg.sort(key=lambda x: lt.index(reg.search(x).group()))#对文件名以列表里的id号的顺序进行排序,特别关键的步骤
 
patt=re.compile(r"(.xlsx)$")    
files=[osp.join(path1,s) for s in lg if patt.findall(s)]  #获取文件夹下的文件名,并拼接完整路径。
for filename in files:    
    win32api.ShellExecute(0,"print",filename,None,".",0 )
    time.sleep(5)
    print(osp.basename(filename)+"已打印")

[GUI]音乐下载器

uupython阅读(391)

这段代码实现了一个音乐破解软件的图形界面,可以搜索和下载音乐。以下是代码的主要部分:

  1. SetUI 类:这个类用于创建界面窗口和定义界面元素。
  2. set_ui() 方法:设置了界面的各种元素,包括标签、单选按钮、输入框、按钮和表格。
  3. get_KuWoMusic() 方法:获取酷我音乐搜索结果,将搜索到的歌曲信息展示在表格中。
  4. get_song_url() 方法:在表格中选择歌曲后,获取歌曲的下载地址。
  5. download_music() 方法:下载选择的歌曲。
  6. progress_bar() 方法:实现一个简单的进度条。
  7. ui_center() 方法:将窗口居中显示。
  8. loop() 方法:进入主循环,等待用户交互事件。

注意:

  • 这个代码使用了 tkinter 来创建图形界面,并使用了 requests 库来进行网络请求和下载。
  • get_KuWoMusic() 方法发送网络请求获取搜索结果,并将结果显示在界面的表格中。
  • get_song_url() 方法获取选中歌曲的下载地址。
  • download_music() 方法下载选中的歌曲,保存到本地。
  • 请注意,这段代码实现了基本的功能,但可能需要进一步的错误处理和用户体验优化,例如处理网络请求失败、下载进度显示等。也请确保使用网络爬虫时遵守网站的使用条款,以避免侵权问题。
import os
import tkinter as tk
import webbrowser
import requests
import tkinter.messagebox as mes_box
import PySimpleGUI as sg
from tkinter import ttk
from retrying import retry
 
 
class SetUI(object):
    """
    音乐弹框界面
    """
 
    def __init__(self, weight=1000, height=600):
        self.ui_weight = weight
        self.ui_height = height
        self.title = " 音乐破解软件 "
        self.ui_root = tk.Tk(className=self.title)
        self.ui_url = tk.StringVar()
        self.ui_var = tk.IntVar()
        self.ui_var.set(1)
        self.show_result = None
        self.song_num = None
        self.response_data = None
        self.song_url = None
        self.song_name = None
        self.song_author = None
 
    def set_ui(self):
        """
        设置简易UI界面
        :return:
        """
        # Frame空间
        frame_1 = tk.Frame(self.ui_root)
        frame_2 = tk.Frame(self.ui_root)
        frame_3 = tk.Frame(self.ui_root)
        frame_4 = tk.Frame(self.ui_root)
 
        # ui界面中菜单设计
        ui_menu = tk.Menu(self.ui_root)
        self.ui_root.config(menu=ui_menu)
        file_menu = tk.Menu(ui_menu, tearoff=0)
        ui_menu.add_cascade(label='菜单', menu=file_menu)
        file_menu.add_command(label='使用说明', command=lambda: webbrowser.open('www.baidu.com'))
        file_menu.add_command(label='关于作者', command=lambda: webbrowser.open('www.baidu.com'))
        file_menu.add_command(label='退出', command=self.ui_root.quit)
 
        # 控件内容设置
        choice_passageway = tk.Label(frame_1, text='请选择音乐搜索通道:', padx=10, pady=10)
        passageway_button_1 = tk.Radiobutton(frame_1, text='酷我', variable=self.ui_var, value=1, width=10, height=3)
        passageway_button_2 = tk.Radiobutton(frame_1, text='网易云', variable=self.ui_var, value=2, width=10, height=3)
        passageway_button_3 = tk.Radiobutton(frame_1, text='QQ音乐', variable=self.ui_var, value=3, width=10, height=3)
        passageway_button_4 = tk.Radiobutton(frame_1, text='酷狗', variable=self.ui_var, value=4, width=10, height=3)
        input_link = tk.Label(frame_2, text="请输入歌曲名或歌手:")
        entry_style = tk.Entry(frame_2, textvariable=self.ui_url, highlightcolor='Fuchsia', highlightthickness=1,
                               width=35)
        label2 = tk.Label(frame_2, text=" ")
        play_button = tk.Button(frame_2, text="搜索", font=('楷体', 11), fg='Purple', width=2, height=1,
                                command=self.get_KuWoMusic)
        label3 = tk.Label(frame_2, text=" ")
        # 表格样式
        columns = ("序号", "歌手", "歌曲", "专辑")
        self.show_result = ttk.Treeview(frame_3, height=20, show="headings", columns=columns)
        # 下载
        download_button = tk.Button(frame_4, text="下载", font=('楷体', 11), fg='Purple', width=6, height=1, padx=5,
                                    pady=5, command=self.download_music)
 
        # 控件布局
        frame_1.pack()
        frame_2.pack()
        frame_3.pack()
        frame_4.pack()
        choice_passageway.grid(row=0, column=0)
        passageway_button_1.grid(row=0, column=1)
        passageway_button_2.grid(row=0, column=2)
        passageway_button_3.grid(row=0, column=3)
        passageway_button_4.grid(row=0, column=4)
        input_link.grid(row=0, column=0)
        entry_style.grid(row=0, column=1)
        label2.grid(row=0, column=2)
        play_button.grid(row=0, column=3, ipadx=10, ipady=10)
        label3.grid(row=0, column=4)
        self.show_result.grid(row=0, column=4)
        download_button.grid(row=0, column=5)
 
        # 设置表头
        self.show_result.heading("序号", text="序号")
        self.show_result.heading("歌手", text="歌手")
        self.show_result.heading("歌曲", text="歌曲")
        self.show_result.heading("专辑", text="专辑")
        # 设置列
        self.show_result.column("序号", width=100, anchor='center')
        self.show_result.column("歌手", width=200, anchor='center')
        self.show_result.column("歌曲", width=200, anchor='center')
        self.show_result.column("专辑", width=300, anchor='center')
 
        # 鼠标点击
        self.show_result.bind('<ButtonRelease-1>', self.get_song_url)
 
    @retry(stop_max_attempt_number=5)
    def get_KuWoMusic(self):
        """
        获取qq音乐
        :return:
        """
        # 清空treeview表格数据
        for item in self.show_result.get_children():
            self.show_result.delete(item)
        headers = {
            'accept': 'application/json, text/plain, */*',
            'accept - encoding': 'gzip, deflate',
            'accept - language': 'zh - CN, zh;q = 0.9',
            'cache - control': 'no - cache',
            'Connection': 'keep-alive',
            'csrf': 'HH3GHIQ0RYM',
            'Referer': 'http://www.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6',
            'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/99.0.4844.51 Safari/537.36',
            'Cookie': '_ga=GA1.2.218753071.1648798611; _gid=GA1.2.144187149.1648798611; _gat=1; '
                      'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1648798611; '
                      'Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1648798611; kw_token=HH3GHIQ0RYM'
        }
        search_input = self.ui_url.get()
        if len(search_input) > 0:
            search_url = 'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?'
            search_data = {
                'key': search_input,
                'pn': '1',
                'rn': '80',
                'httpsStatus': '1',
                'reqId': '858597c1-b18e-11ec-83e4-9d53d2ff08ff'
            }
            try:
                self.response_data = requests.get(search_url, params=search_data, headers=headers, timeout=20).json()
                if 'data' in self.response_data and 'list' in self.response_data['data']:
                    songs_data = self.response_data['data']['list']
                    if int(self.response_data['data']['total']) <= 0:
                        mes_box.showerror(title='错误', message='搜索: {} 不存在.'.format(search_input))
                    else:
                        for i in range(len(songs_data)):
                            self.show_result.insert('', i, values=(i + 1, songs_data[i]['artist'], songs_data[i]['name'],
                                                                   songs_data[i]['album']))
                else:
                    mes_box.showerror(title='错误', message='返回的数据不包含所需的字段')
            except TimeoutError:
                mes_box.showerror(title='错误', message='搜索超时,请重新输入后再搜索!')
        else:
            mes_box.showerror(title='错误', message='未输入需查询的歌曲或歌手,请输入后搜索!')
 
    def get_song_url(self, event):
        """
        获取下载歌曲的地址
        :return:
        """
        # treeview中的左键单击
        for item in self.show_result.selection():
            item_text = self.show_result.item(item, "values")
            # 获取
            self.song_num = int(item_text[0])
        # 获取下载歌曲的地址
        if self.song_num is not None:
            songs_data = self.response_data['data']['list']
            songs_req_id = self.response_data['reqId']
            song_rid = songs_data[self.song_num - 1]['rid']
            music_url = 'http://www.kuwo.cn/api/v1/www/music/playUrl?mid={}&type=convert_url3' \
                        '&httpsStatus=1&reqId={}' \
                .format(song_rid, songs_req_id)
            response_data = requests.get(music_url).json()
            self.song_url = response_data['data'].get('url')
            self.song_name = songs_data[self.song_num - 1]['name']
            self.song_author = songs_data[self.song_num - 1]['artist']
        else:
            mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择')
 
    def download_music(self):
        """
        下载音乐
        :return:
        """
        if self.song_num is not None:
            song_name = self.song_name + '--' + self.song_author + ".mp3"
            try:
                save_path = os.path.join('./wangYiYun/{}'.format(song_name)).replace('\\', '/')
                true_path = os.path.abspath(save_path)
                if not os.path.exists(os.path.dirname(true_path)):
                    os.makedirs(os.path.dirname(true_path))
                resp = requests.get(self.song_url)
                with open(save_path, 'wb') as file:
                    file.write(resp.content)
                    mes_box.showinfo(title='下载成功', message='歌曲:%s,保存地址为%s' % (self.song_name, true_path))
            except Exception:
                mes_box.showerror(title='错误', message='未找到存放歌曲的文件夹')
        else:
            mes_box.showerror(title='错误', message='未选择要下载的歌曲,请选择后下载')
 
    def progress_bar(self, file_size):
        """
        任务加载进度条
        :return:
        """
        layout = [[sg.Text('任务完成进度')],
                  [sg.ProgressBar(file_size, orientation='h', size=(40, 20), key='progressbar')],
                  [sg.Cancel()]]
 
        # window只需将自定义的布局加载出来即可 第一个参数是窗口标题。
        window = sg.Window('机器人执行进度', layout)
        # 根据key值获取到进度条
        _progress_bar = window['progressbar']
        for i in range(file_size):  # 循环
            event, values = window.read(timeout=10)
            if event == 'Cancel' or event is None:
                break
            _progress_bar.UpdateBar(i + 1)
 
    def ui_center(self):
        """
        UI界面窗口设置:居中
        """
        ws = self.ui_root.winfo_screenwidth()
        hs = self.ui_root.winfo_screenheight()
        x = int((ws / 2) - (self.ui_weight / 2))
        y = int((hs / 2) - (self.ui_height / 2))
        self.ui_root.geometry('{}x{}+{}+{}'.format(self.ui_weight, self.ui_height, x, y))
 
    def loop(self):
        """
        函数说明:loop等待用户事件
        """
        self.ui_root.resizable(False, False)  # 禁止修改窗口大小
        self.ui_center()  # 窗口居中
        self.set_ui()
        self.ui_root.mainloop()
 
 
if __name__ == '__main__':
    a = SetUI()
    a.loop()

聊天室3.0

uupython阅读(479)

1.服务端:

from socket import *import threading
import time
import struct
import os
 
 
 
user = {}  # 储存用户信息
 
 
def chatRecord(dataSocket):
    print("开始发送聊天记录")
    with open("Version 3.0\Liaotiainjjilu.txt", 'rb') as rf:
        # 持续读取文件并发送数据
        for data in rf:
            dataSocket.sendall(data)
    dataSocket.send("gaspatlazidbaafdsfaya".encode()) 
    print("聊天记录发送完成")
    time.sleep(0.5)
 
def imageChat(info, dataSocket):
    size_data = dataSocket.recv(4)  # 以4个字节接收图像大小信息
    image_size = int.from_bytes(size_data, byteorder='big')  # 将字节转换为整数
 
    timeNow = str(time.time())
     
    image_path = 'Version 3.0\\serverlog\\{}.png'.format(timeNow)
 
    time.sleep(0.05)
    # 接收图像数据
    image_data = b''
    while len(image_data) < image_size:
        data = dataSocket.recv(1024)
        if not data:
            break
        image_data += data
     
    # 将图像数据保存为文件
    with open(image_path, 'wb') as file:
        file.write(image_data)
     
    print('图像接收完成')
 
    """---------------接收完图像后发送给所有人--------------------"""
 
    print("开始发送")
    for k in user:  # 遍历user
 
        # fs = "C " + info.split(' ', 1)[1]  # 聊天内容
        # user[k].send(fs.encode())  # 发送聊天内容
 
        # Note.write(fs)
        time.sleep(0.05)
        texts = "IMAGE " + info.split(' ', 1)[1] + " " + timeNow
        time.sleep(0.05)
        user[k].send(texts.encode()) 
 
        with open(image_path, 'rb') as file:
            image_data = file.read()
         
        # 发送图像大小信息
        image_size = len(image_data)
        size_data = image_size.to_bytes(4, byteorder='big')  # 将整数转换为字节
        user[k].sendall(size_data)
         
        # 发送图像数据
        user[k].sendall(image_data)
        time.sleep(1)
 
 
        # user[k].send("gaspatlazidbaafdsfaya".encode()) 
     
    print("发送完成")
 
    f = open('Version 3.0\Liaotiainjjilu.txt', 'a', encoding='utf-8')
    f.write("IMAGERECORD " + info.split(' ', 1)[1] + " " + timeNow  + " " + str(time.strftime('%Y-%m-%d %H:%M:%S')))
    f.write('\n')
    f.close()
 
    print("写入完成")
 
 
def userLogin(info, dataSocket):
    """
    录入用户登录业务
    """
    print(info)
    user_text = open(r"Version 3.0\user_text.txt", mode="r", encoding="utf-8")
    lines = user_text.readlines()
    IF_REG = 0
    if len(info.split(' ', 2)) == 1:  # 没看懂(
        dataSocket.send("NO".encode())
    elif info.split(' ', 2)[1] in user:  # 如果这个用户名已经在user里了
        dataSocket.send("NO".encode())  # 拒接注册
 
    for user_len in range(0, len(lines)):
        # print(lines[user_len].split(" ", 1)[0] + " " + lines[user_len].split(" ", 1)[1] + '\n')
 
        if (lines[user_len].split(" ", 1)[0] == info.split(' ', 2)[1] and lines[user_len].split(" ", 1)[1] == info.split(' ', 2)[2]+'\n'):
            user[info.split(' ', 2)[1]] = dataSocket    # 添加用户名为键,用户连接为值
            dataSocket.send("OK".encode())  # 返回"OK"
 
 
            chatRecord(dataSocket)
 
 
 
            IF_REG = 1  # 是否注册为1
            for ll in user:
                if (user[ll] == user[ll]):
                    for key in user.keys():
                        ppp = "R " + key
                        user[ll].send(ppp.encode())
                        # Note.write(ppp)
 
                        time.sleep(0.3)
    print(user)
    if IF_REG == 0:
        print("NO")
        dataSocket.send("NO".encode())
 
 
def UserChar(dataSocket, addr):
    """
    处理用户聊天
    """
    print(info.split(maxsplit=1)[1], end=" ")  # 在服务端打印聊天信息
 
    print(addr, end=" ")  # 在服务端打印ip地址
    print(time.strftime('%Y-%m-%d %H:%M:%S'))  # 在服务端打印时间   
 
    for k in user:  # 遍历user
        # print(info.split(' ', 1)[1])
        if user[k] != dataSocket:  # 发送至所有人(除了自己)
            fs = "C " + info.split(' ', 1)[1]  # 聊天内容
            user[k].send(fs.encode())  # 发送聊天内容
 
            # Note.write(fs)
 
 
def Init():
    while True:
        dataSocket, addr = listenSocket.accept()  # 获得一个客户端的连接(阻塞式,只有客户端连接后,下面才执行)
        print('接受一个客户端连接:', addr)
 
        if (1 == 1):
            xd = threading.Thread(target=deal, args=(dataSocket, addr))
            xd.start()  # 启动一个线程
 
def deal(dataSocket, addr):
    global recved, info
     
    try:
        while True:
             
                recved = dataSocket.recv(1024)  # 最大接收字节
                info = recved.decode()  # 接受的消息
                if len(info) == 0:  # 如果接受的消息长度为0
                    # UserExit(dataSocket)
                    # IF_REG = 0  # 是否注册为1
 
                    for key, k in list(user.items()):  # 与消息长度为0一样的操作    key:键,k值
                        # print("user k:", k, "  user:", user, "  dataSocket:", dataSocket)
 
                        # 处理用户意外断开
                        if k == dataSocket:# user k: <socket.socket fd=188, family=2, type=1, proto=0, laddr=('192.168.0.103', 80), raddr=('119.3.215.140', 50361)> user key: Admin
                            # print(user[k])
                            del user[key]
                            # print(user)
 
                            for ka in user:
                                # print("进入循环删除")
                                print(key + "已退出群聊")
                                # user[ka].send((key + "已退出群聊").encode())
                                user[ka].send(("E " + key).encode())
                                IF_REG = 0
                                dataSocket.close()
                                break
                    print(user)        
                    break
 
                if info.split(' ', 1)[0] == "IMAGE":
                    print("收到请求(图片")
                    imageChat(info, dataSocket)
 
                elif info.split(' ', 1)[0] == 'R':
                    userLogin(info, dataSocket)
                     
                 
                elif info.split(maxsplit=1)[0] == "C":  # 如果请求是聊天
                    UserChar(dataSocket, addr) 
                    f = open('Version 3.0\Liaotiainjjilu.txt', 'a', encoding='utf-8')
                    f.write("CHATRECORD " + info.split(' ', 1)[1].split(": ", 1)[0] + " " + info.split(' ', 1)[1].split(": ", 1)[1] + " " + time.strftime('%Y-%m-%d %H:%M:%S'))
                    f.write('\n')
                    f.close()
                    # print("写入成功!")
    except Exception as e: 
        print('报错:', e)
        for key, k in list(user.items()):  # 与消息长度为0一样的操作    key:键,k值
            # print("user k:", k, "  user:", user, "  dataSocket:", dataSocket)
 
            # 处理用户意外断开
            if k == dataSocket:# user k: <socket.socket fd=188, family=2, type=1, proto=0, laddr=('192.168.0.103', 80), raddr=('119.3.215.140', 50361)> user key: Admin
                # print(user[k])
                del user[key]
                # print(user)
 
                for ka in user:
                    # print("进入循环删除")
                    print(key + "已退出群聊")
                    # user[ka].send((key + "已退出群聊").encode())
                    user[ka].send(("E " + key).encode())
                    IF_REG = 0
                    dataSocket.close()
                    break
 
            print(user)
 
 
 
 
 
if __name__ == "__main__":
    listenSocket = socket(AF_INET, SOCK_STREAM)
 
    # listenSocket.setsockopt(SOL_SOCKET, SOCK_STREAM, True)
    # listenSocket.ioctl(SIO_KEEPALIVE_VALS, (1, 60 * 1000, 30 * 1000))
 
    # socket绑定地址和端口
    listenSocket.bind(('0.0.0.0', 1234))
    listenSocket.listen()
 
 
 
    print(f'服务端启动成功,等待客户端连接...')
    Init()

2.客户端:

"""
作者:Mike_python
时间:2023/2/26
完稿:2023/7/23
文件内容:客户端
"""
 
from tkinter import *
from ttkbootstrap import *
from tkinter import messagebox as mg
import socket
import threading
import time
import sys
import os
from tkinter.font import Font
from PIL import ImageTk, Image
from tkinter import filedialog
 
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
 
 
def centerWindow(root, width, height):
    """
    窗口居中代码
    """
    screenwidth = root.winfo_screenwidth()  # 获取显示屏宽度
    screenheight = root.winfo_screenheight()  # 获取显示屏高度
    size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)  # 设置窗口居中参数
    root.geometry(size)  # 让窗口居中显示
 
   
 
def loginSendToServer(root, passwordWar, usernameWar):
    """验证登录"""
    global client
     
    client.connect(('202.189.5.24', 49405))
 
    client.send(("R "+usernameWar.get() + " " + passwordWar.get()).encode())   # 发送注册请求
 
 
    while True:
 
        data = client.recv(1024)
        info = data.decode()
 
        if (info == 'OK'):
            login_root.withdraw()# 隐藏登录窗口
     
            main()
            break
 
             
        elif (info == 'NO'):
            mg.showerror("","用户名或密码错误!")
            sys.exit(0)
 
 
def insert_newline(*args):
    """Control-Return后的换行"""
    send_entry.insert("insert", "\n")
    return "break"
 
def fasong_Init(*args):
    """fasong的桥梁"""
    fasong()
    # send_entry.delete("0.0", END)   # 设置发送为空
    return 'break'
 
def fasong(*args): 
    re_data = send_entry.get("1.0", END)[:-1]
    if 'exit' == re_data:   # 判断是否退出
        client.send(("Q "+ username).encode())  # 发送退出的请求
        client.close()
 
    elif (re_data != " \n" and re_data != "\n" and re_data != "" and re_data != " "):    # 判断内容不为空
         
        time_ = time.strftime('%Y-%m-%d %H:%M:%S')                  # 以下为自己说的话
 
        chat_text.config(state=NORMAL)
 
        #f1 = Font("微软雅黑", 8)
        chat_text.tag_config("tag_3", font=("微软雅黑", 9), foreground="grey")
        chat_text.insert(END, time_, "tag_3")   # 发送时间
        chat_text.insert(END, "\n")
 
        #f = Font("微软雅黑", 13)
        chat_text.tag_config("tag_41", font=("微软雅黑", 14), foreground="#808080")
        chat_text.insert(END, username + ":", "tag_41")    # 发送文本内容c:\迅雷下载\SimplifiedChinese\SourceHanSansSC-Medium.otf
        chat_text.insert(END, "\n")
         
        #f = Font("微软雅黑", 12)
        chat_text.tag_config("tag_4", font=("微软雅黑", 13), foreground="#2E8B57")
        chat_text.insert(END, re_data, "tag_4")    # 发送文本内容
        chat_text.insert(END, "\n")
 
        chat_text.update_idletasks()
 
        chat_text.config(state=DISABLED)
        chat_text.see("end")    # 转到最后一行
 
        chat_text.update_idletasks()
 
 
        # send_entry.first()
        # send_entry.delete(0.1,2.0)      # 设置发送为空
        # send_entry.insert('1 wordstart' , "s")
        # time.sleep(0.1)
        send_entry.delete("0.0", END)   # 设置发送为空
 
        time.sleep(0.15)
        client.send(("C " + username + ": " + re_data).encode()) 
 
def sendImage():
    time.sleep(1)
    image_path = filedialog.askopenfilename()
    if (len(image_path)>=1):
 
        with open(image_path, 'rb') as file:
            image_data = file.read()
         
 
        client.send(("IMAGE " + username).encode()) 
 
        # 发送图像大小信息
        image_size = len(image_data)
        size_data = image_size.to_bytes(4, byteorder='big')  # 将整数转换为字节
        client.sendall(size_data)
         
        # 发送图像数据
        client.sendall(image_data)
 
        """发送后将图片放到text中"""
        # time_ = time.strftime('%Y-%m-%d %H:%M:%S')                  # 以下为自己说的话
 
        # chat_text.config(state=NORMAL)
 
        # #f1 = Font("微软雅黑", 8)
        # chat_text.tag_config("tag_3", font=("微软雅黑", 9), foreground="grey")
        # chat_text.insert(END, time_, "tag_3")   # 发送时间
        # chat_text.insert(END, "\n")
 
        # #f = Font("微软雅黑", 13)
        # chat_text.tag_config("tag_41", font=("微软雅黑", 14), foreground="#808080")
        # chat_text.insert(END, username + ":", "tag_41")    # 发送文本内容c:\迅雷下载\SimplifiedChinese\SourceHanSansSC-Medium.otf
        # chat_text.insert(END, "\n")
         
        # image = Image.open(image_path)
        # pphoto = ImageTk.PhotoImage(image)
        # chat_text.image_create(END, image=pphoto)#用这个方法创建一个图片对象,并插入到“END”的位置
        # chat_text.insert(END, "\n")
        # chat_text.image = pphoto
 
        # chat_text.update_idletasks()
        # chat_text.update()
 
        chat_text.config(state=DISABLED)
        chat_text.see("end")    # 转到最后一行
 
        # chat_text.update_idletasks()
 
         
        print('图像发送完成')
        mg.showinfo("", "发送图片完成")
     
def insert_image(canvas, image):
    canvas.create_image(0, 0, anchor="nw", image=image)
 
ls=[]
for i in range(0, 1000):
    ls.append(str(i))
i=0
def show_image(image_path):
    global i
    image = Image.open(image_path)
    ls[i] = ImageTk.PhotoImage(image)
    chat_text.image_create(END, image=ls[i])#用这个方法创建一个图片对象,并插入到“END”的位置
    chat_text.tag_configure("{}".format(str(i)), wrap="none")
    chat_text.insert(END, "\n")
    chat_text.image = ls[i]
    i+=1
 
 
def jieshou():
    global i
    while True:
        # time.sleep(0.3)
        try:
            try:
                data = client.recv(5000)
                res = data.decode()
            except UnicodeDecodeError:
                # 忽略无法解码的数据
                continue
            if(res != ''):
 
                # print("1")
                if (res.split(" ", 2)[0]=="C"): # 如果为聊天的请求
                    # print(res.split(" ", 1)[0])
                    # print(res.split(" ", 1)[1])
                    # print(res)
                    time_ = time.strftime('%Y-%m-%d %H:%M:%S')
 
                    chat_text.config(state=NORMAL)
                    f1 = Font(size=10)
                    chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                    chat_text.insert(END, time_, "tag_1")
                    chat_text.insert(END, "\n")
 
                    f = Font(size=15)
                    chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                    chat_text.insert(END, res.split(" ", 2)[1], "tag")
                    chat_text.insert(END, "\n")
                     
                    f = Font(size=14)
                    chat_text.tag_config("tag_2", font=("微软雅黑", 13), foreground="black")
                    chat_text.insert(END, res.split(" ", 2)[2], "tag_2")
                    chat_text.insert(END, "\n")
 
                    chat_text.config(state=DISABLED)
                    chat_text.see("end")
 
 
                if(res.split(" ", 1)[0]=="R"):    # 在线用户请求
                    afd = False
                    print(res.split(" ", 1)[1])
                    for kk in range(0, online_user.size()): # 循环判断在线列表里是否有用户名
                        if online_user.get(kk) == (res.split(" ", 1)[1]):   # 检测到是
                            afd = True  # 判断变量为真
                            break   # 退出
                    if (afd ==  False): # 如果判断变量为假
                        online_user.insert(END,res.split(" ", 1)[1])    # 插入用户名
 
 
                if(res.split(" ", 1)[0]=="E"):    # 退出请求
                    print("收到退出请求")
                    for kk in range(0, online_user.size()): # 循环判断要删除的用户名
                        if online_user.get(kk) == (res.split(" ", 1)[1]):   
                            online_user.delete(kk)  # 从在线列表去除
                            online_user.update()
                            break
 
                if(res.split(" ", 1)[0] == "IMAGE"):
                    print("开始接收图像")
 
                    image_path = './log\\image\\{}.png'.format(res.split(" ", 2)[2])
                     
 
                    size_data = client.recv(4)  # 以4个字节接收图像大小信息
                    image_size = int.from_bytes(size_data, byteorder='big')  # 将字节转换为整数
 
                    image_data = b''
                    while len(image_data) < image_size:
                        data = client.recv(1024)
                        if not data:
                            break
                        image_data += data
                     
                    # 将图像数据保存为文件
                    with open(image_path, 'wb') as file:
                        file.write(image_data)
 
 
                    time_ = time.strftime('%Y-%m-%d %H:%M:%S')                  # 以下为别人
 
                    chat_text.config(state=NORMAL)
 
                    #f1 = Font("微软雅黑", 8)
                    chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                    chat_text.insert(END, time_, "tag_1")
                    chat_text.insert(END, "\n")
 
                    f = Font(size=15)
                    chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                    chat_text.insert(END, res.split(" ", 2)[1], "tag")
                    chat_text.insert(END, "\n")
                     
 
                     
                    # image = Image.open(image_path)
                    # pphoto = ImageTk.PhotoImage(image)
                    # chat_text.image_create(END, image=pphoto)#用这个方法创建一个图片对象,并插入到“END”的位置
                    # chat_text.insert(END, "\n")
                    # chat_text.image = pphoto
 
                    show_image(image_path)
 
                    chat_text.update_idletasks()
                    chat_text.update()
 
                    chat_text.config(state=DISABLED)
                    chat_text.see("end")    # 转到最后一行
                     
                    print('图像接收完成')
                         
 
 
        # else:
        #     continue
        except Exception as e:  
            print("ERROR!:", e)
 
            #break
 
def receiveFile():
    """接收聊天记录"""
    try:
        time.sleep(0.1)
        print("开始接收聊天记录")
        with open("./log\\聊天记录({}).txt".format(username), 'wb') as file:
            while True:
                # 从客户端接收数据
                 
 
                data = client.recv(30000)
                info = data.decode()
 
                file.write(data)# 将接收到的数据写入文件
 
                if ('gaspatlazidbaafdsfaya' in info):
                    print("exit")
                    file.close()
                    break
    except:
        mg.showerror("", "聊天记录读取失败(图片)")
   
 
 
def putChatToText():
    """将读取到的历史消息放置到聊天界面上"""
 
    user_text = open("./log\\聊天记录({}).txt".format(username), mode="r", encoding="utf-8")
    lines = user_text.readlines()
    for user_len in range(0, len(lines)-1):
        try:
            if (lines[user_len].split(" ", 3)[0] == "CHATRECORD"):
                chat_text.config(state=NORMAL)
 
                f1 = Font(size=10)
                chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                chat_text.insert(END, lines[user_len].split(" ", 3)[3], "tag_1")
                # chat_text.insert(END, "\n")
 
                f = Font(size=15)
                chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                chat_text.insert(END, lines[user_len].split(" ", 3)[1], "tag")
                chat_text.insert(END, "\n")
                 
                f = Font(size=14)
                chat_text.tag_config("tag_2", font=("微软雅黑", 13))
                chat_text.insert(END,lines[user_len].split(" ", 3)[2], "tag_2")
                chat_text.insert(END, "\n")
 
                chat_text.config(state=DISABLED)
                chat_text.see("end")
 
                 
            elif (lines[user_len].split(" ", 3)[0] == "IMAGERECORD"):
                chat_text.config(state=NORMAL)
 
                f1 = Font(size=10)
                chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                chat_text.insert(END, lines[user_len].split(" ", 3)[3], "tag_1")
                # chat_text.insert(END, "\n")
 
                f = Font(size=15)
                chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                chat_text.insert(END, lines[user_len].split(" ", 2)[1], "tag")
                chat_text.insert(END, "\n")
                 
                # image = Image.open('Version 3.0\\log\\image\\{}.png'.format(lines[user_len].split(" ", 3)[2]))
                # pphoto = ImageTk.PhotoImage(image)
                # chat_text.image_create(END, image=pphoto)#用这个方法创建一个图片对象,并插入到“END”的位置
                # chat_text.insert(END, "\n")
                # chat_text.image = pphoto
 
                show_image('./log\\image\\{}.png'.format(lines[user_len].split(" ", 3)[2]))
 
                chat_text.config(state=DISABLED)
                chat_text.see("end")
        except:
            chat_text.config(state=NORMAL)
            chat_text.tag_config("tag_31", font=("微软雅黑", 14), foreground="red")
            chat_text.insert(END, "历史消息放置失败", "tag_31")
            chat_text.insert(END, "\n")
 
            chat_text.config(state=DISABLED)
            chat_text.see("end")
 
 
    chat_text.config(state=NORMAL)
    chat_text.tag_config("tag_31", font=("微软雅黑", 14), foreground="blue")
    chat_text.insert(END, "-----------------------以上为历史消息-----------------------", "tag_31")
    chat_text.insert(END, "\n")
 
    chat_text.config(state=DISABLED)
    chat_text.see("end")
 
 
         
def SystemSetting():
    setting_root = Toplevel(login_root)
    setting_root.title("设置")
    centerWindow(setting_root, 400, 200)
 
 
 
def main():
    """登录后主界面"""
 
    global chat_text, send_entry, online_user, username
     
    # root = login_root.Toplevel(themename="morph")
    username = usernameWar.get()
 
    try:
        receiveFile()
    except:
        mg.showerror("", "聊天记录读取错误!")
 
     
 
    root = Toplevel(login_root)
    root.title("聊天界面")
    centerWindow(root, 900, 600)
 
    def exit_():
        root.destroy()
        os._exit(0)
 
 
             
             
     
  
    new_thread = threading.Thread(target=jieshou, name="T1")   
    # 启动新线程
    new_thread.start()
 
    new_thread1 = threading.Thread(target=fasong, name="T2")
    # 启动新线程
    new_thread1.start()
 
 
    """------------------------------------------------frame左(聊天区域)------------------------------------------------左侧frame"""
 
 
    centerFrame = Frame(root, width=650, height=560)
    centerFrame.place(x=20, y=20)
 
    """------------------------------文本接收-------------------------------------------"""
    text_frame = Frame(centerFrame)
    text_frame.place(x = 10, y = 10)
    gun_song_tiao_y = Scrollbar(text_frame, bootstyle="secondary-round")
    gun_song_tiao_x = Scrollbar(text_frame, orient=HORIZONTAL, bootstyle="secondary-round")
 
    chat_text = Text(text_frame, height=21, width=67, wrap='none', relief=GROOVE, font=('微软雅黑', 11))#, state=DISABLED
 
    gun_song_tiao_y.pack(side=RIGHT,fill=Y)
    gun_song_tiao_x.pack(side=BOTTOM, fill=X)
 
    chat_text.pack()
 
    gun_song_tiao_y.config(command=chat_text.yview)
    gun_song_tiao_x.config(command=chat_text.xview)
                            
    chat_text.config(yscrollcommand=gun_song_tiao_y.set)
    chat_text.config(xscrollcommand=gun_song_tiao_x.set)
    """------------------------------文本接收-------------------------------------------"""
 
 
 
    """------------------------------发送框-------------------------------------------"""
    send_entry = Text(centerFrame, width=55, height=4, font=("微软雅黑", 13)) # 发送区域
    send_entry.place(x=10, y=460)
 
 
    send_button = Button(centerFrame, text="\n发 送\n", command=fasong_Init)     # 发送按钮
    send_button.place(x=585, y=460)
 
    phtotICON = Image.open(r"./log\图片1_pic-one.png")
    photowidth, photoheight = phtotICON.size
    photonew_width = int(photowidth * 0.06)  # 调整宽度为原始宽度的50%
    photonew_height = int(photoheight * 0.06)  # 调整高度为原始高度的50%
    photoimage = phtotICON.resize((photonew_width, photonew_height))  # 调整图像大小
    photo = ImageTk.PhotoImage(photoimage)
 
    image_button = Button(centerFrame, image=photo, bootstyle="info-outline", command=sendImage)
    image_button.place(x=575, y=530)
 
    phtotICON1 = Image.open(r"./log\设置_setting-three.png")
    photowidth1, photoheight1 = phtotICON1.size
    photonew_width1 = int(photowidth1 * 0.06)  # 调整宽度为原始宽度的50%
    photonew_height1 = int(photoheight1 * 0.06)  # 调整高度为原始高度的50%
    photoimage1 = phtotICON1.resize((photonew_width1, photonew_height1))  # 调整图像大小
    photo1 = ImageTk.PhotoImage(photoimage1)
 
    settingButton = Button(centerFrame, image=photo1, bootstyle="info-outline", command=SystemSetting)
    settingButton.place(x=613, y=530)
 
 
    send_entry.bind("<Return>", fasong_Init)
    send_entry.bind("<Control-Return>", insert_newline)
    """------------------------------发送框-------------------------------------------"""
 
 
    """------------------------------------------------右侧frame(在线列表)------------------------------------------------左侧frame"""
    RightFrame = Frame(root, width=200, height=560)
    RightFrame.place(x=680, y=20)
 
    online_user = Listbox(RightFrame, height=30, width=35)
    online_user.place(x=5, y=5)
    online_user.config(font=("微软雅黑", 14))
 
 
    putChatToText()
 
 
    root.protocol("WM_DELETE_WINDOW", exit_)
    root.mainloop()
 
def reg_():
    """注册"""
    mg.showinfo("", "请前往鱼c论坛注册")
 
 
 
 
def login():
    """登录界面"""
    # global passwordWar, usernameWar, root
 
    def bind_return_key(event=None):
        """回车后进行登录验证"""
        loginSendToServer(login_root, passwordWar, usernameWar)
 
    def SetFocusToPassword(*args):
        """将焦点设置到PasswordEntry"""
        passwordEntry.focus_set()
 
 
 
    global login_root, usernameWar
    global username
 
 
    login_root = Window(themename="morph")
    login_root.title("登录界面")
    centerWindow(login_root, 500, 600)
 
 
    passwordWar = StringVar()
    usernameWar = StringVar()
 
     
 
    # 用户名部分
    Label(login_root, text='用户名:', font=("微软雅黑", 14)).place(x=40, y=80)
    usernameEntry = Entry(login_root, font=('微软雅黑', 13), width=22, bootstyle="dark", textvariable=usernameWar)
    usernameEntry.place(x=140, y=80)
 
    usernameEntry.focus_set() # 使焦点一开始就在输入用户名上
 
 
    # 密码部分
    Label(login_root, text='密   码:', font=("微软雅黑", 14)).place(x=40, y=160)
    passwordEntry = Entry(login_root, font=('微软雅黑', 13), width=22, show='*', bootstyle="dark", textvariable=passwordWar)
    passwordEntry.place(x=140, y=160)
 
 
    # 登录按钮
    loginButton = Button(login_root, text="登录", bootstyle="info-outline", width=8, command=lambda: loginSendToServer(login_root, passwordWar, usernameWar))
    loginButton.place(x=200, y=300)
    # 注册按钮
    regButton = Button(login_root, text="没有账号?点我注册", bootstyle="info-link", width=20, command=reg_).place(x=150, y=360)
 
     
    usernameEntry.bind("<Return>", SetFocusToPassword) # 绑定回车到输入密码
    passwordEntry.bind("<Return>", bind_return_key) # 绑定回车进行登录
 
    login_root.mainloop()
 
 
if __name__ == "__main__":
 
    login()

简易学生管理系统

uupython阅读(357)

这段代码实现了一个简单的命令行学生信息管理系统。用户可以通过命令来添加、删除、修改、查询和列出学生信息,还可以清屏。以下是代码的主要部分:

  1. print_menu(): 打印菜单选项。
  2. add_student(students): 添加学生信息,包括用户名、密码和学号。
  3. delete_student(students): 删除学生信息,需要输入学号和密码进行确认。
  4. modify_student(students): 修改学生信息,可以修改用户名、密码和学号,需要输入学号和密码进行确认。
  5. query_student(students): 查询学生信息,根据关键字查询学生的用户名、学号或 UID。
  6. list_students(students): 列出所有学生信息,显示每个学生的 UID、用户名和学号。
  7. read_file(): 从文件中读取已有的学生信息。
  8. save_file(): 保存学生信息到文件。
  9. 主程序入口循环通过命令行界面提供菜单选项,用户可以输入数字或命令来选择操作。

注意:

  • 代码中使用了一个类 MyClass 来存储版本号,并使用了 @property 装饰器来定义属性的获取方法。
  • 用户信息以列表 students 存储,每个用户以字典形式表示。
  • 学生信息保存在文件 Students.txt 中,使用 eval() 函数来读取和写入。
  • 用户可以输入 6 清屏,这在双击运行脚本时可以清除终端屏幕。
  • 在处理文件操作时,代码进行了错误处理,避免文件不存在或出现异常。

请注意,这个管理系统在真实环境中可能还需要更多的安全性和错误处理措施,以确保用户数据的准确性和安全性。

import os
print("tyh学生管理系统,版本:",end="")
class MyClass:
    def __init__(self, value):
        self._value = value
         
    @property
    def value(self):
        return self._value
         
VER = MyClass(1.0)
print(VER.value)
 
# 打印菜单
def print_menu():
    print("=" * 30)
    print("1. 添加学生")
    print("2. 删除学生")
    print("3. 修改学生信息")
    print("4. 查询学生")
    print("5. 列出所有学生信息")
    print("6. 清屏(仅限双击运行时使用)")
    print("0. 退出系统")
    print("=" * 30)
 
# 添加学生
def add_student(students):
    username = input("请输入用户名:")
    password = input("请输入密码:")
    student_id = input("请输入学号:")
    uid = len(students) + 1  # 确保uid唯一
    for student in students:
        if student["username"] == username:
            print("用户名已存在,请重新输入")
            return
        if student["student_id"] == student_id:
            print("学号已存在,请重新输入")
            return
    student = {"username": username, "password": password, "student_id": student_id, "uid": uid}
    students.append(student)
    with open("Students.txt", "a") as f:
        f.write(f"{uid},{username},{password},{student_id}\n")
    print("添加成功!")
 
# 删除学生
def delete_student(students):
    student_id = input("请输入学号:")
    password = input("请输入密码:")
    for student in students:
        if student["student_id"] == student_id:
            if student["password"] == password:
                students.remove(student)
                with open("Students.txt", "w") as f:
                    for s in students:
                        f.write(f"{s['uid']},{s['username']},{s['password']},{s['student_id']}\n")
                print("删除成功!")
                return
            else:
                print("密码错误,请重新输入")
                return
    print("学号不存在,请重新输入")
 
# 修改学生信息
def modify_student(students):
    student_id = input("请输入学号:")
    for student in students:
        if student["student_id"] == student_id:
            if input("请输入密码:") == student["password"]:    
                username = input("请输入新的用户名(按回车不修改):")
                if username:
                    for s in students:
                        if s["username"] == username and s["student_id"] != student_id:
                            print("用户名已存在,请重新输入")
                            return
                    student["username"] = username
                password = input("请输入新的密码(按回车不修改):")
                if password:
                    student["password"] = password
                student_id = input("请输入新的学号(按回车不修改):")
                if student_id:
                    for s in students:
                        if s["student_id"] == student_id and s["uid"] != student["uid"]:
                            print("学号已存在,请重新输入")
                            return
                    student["student_id"] = student_id
                with open("Students.txt", "w") as f:
                    for s in students:
                        f.write(f"{s['uid']},{s['username']},{s['password']},{s['student_id']}\n")
                print("修改成功!")
                return
            else:
                print("密码错误!")
                return
    print("学号不存在,请重新输入")
 
# 查询学生
def query_student(students):
    keyword = input("请输入查询关键字:")
    for student in students:
        if keyword == student["username"] or keyword == student["student_id"] or keyword == str(student["uid"]):
            print(f"用户名:{student['username']}\t学号:{student['student_id']}\tuid:{student['uid']}")  #密码:{student['password']}
    print("查询完毕!")
 
# 列出所有学生信息
def list_students(students):
    print("所有学生信息如下:")
    for student in students:
        print("UID: {},\t 用户名: {},\t 学号: {}".format(student["uid"], student["username"], student["student_id"], student["password"]))
 
# 读取文件中已有学生信息
def read_file():
    try:
        with open("Students.txt", "r") as f:
            students = eval(f.read())
    except FileNotFoundError:
        save_file()
    except:
        students=[]
        try:
            with open("Students.txt", "r") as f:
                st = f.read()
                print(st)
            with open("temp.txt","w") as f:
                f.write(st)
            print("程序出现错误,已备份文件,现在学生已清空,可联系作者恢复")
        except:
            print("程序出现严重错误,未备份文件,现在学生已清空,数据不可恢复,如有必要,联系作者")
    return students
 
# 保存已有学生信息
def save_file():
    try:
        with open("Students.txt", "w") as f:
            f.write(str(students))
    except:
        pass
    return None
 
students = read_file()
while True:
    print_menu()
    temp=input("请输入命令:")
    if temp=="1":
        add_student(students)
    elif temp=='2':
        delete_student(students)
    elif temp=='3':
        modify_student(students)
    elif temp=='4':
        query_student(students)
    elif temp=='5':
        list_students(students)
    elif temp=='6':
        os.system('cls' if os.name == 'nt' else 'clear')
        print("tyh学生管理系统,版本:",end="")
        print(VER.value,end="")
    elif temp=='0':
        save_file()
        break
    else:
        print("无效命令!")
    print()
    save_file()

简易信息管理系统(无GUI)

uupython阅读(351)

这段代码实现了一个简单的学生信息管理系统,可以通过菜单进行学生信息的录入、查找、删除、修改、排序、统计以及显示所有学生信息等功能。以下是代码的主要部分:

  1. menu(): 显示功能菜单。
  2. main(): 主函数,根据用户选择执行相应功能。
  3. insert(): 录入学生信息,将学生信息保存到文件。
  4. save(student): 将学生信息保存到文件。
  5. search(): 查找学生信息,根据ID或姓名查询学生信息。
  6. delete(): 删除学生信息,根据学生ID删除信息。
  7. modify(): 修改学生信息,根据学生ID修改信息。
  8. sort(): 排序学生信息,根据不同的属性进行升序或降序排序。
  9. total(): 统计学生总数。
  10. show(): 显示所有学生信息。
  11. show_student(studentList): 在控制台中以表格形式显示学生信息。
  12. 主程序入口使用 if __name__ == "__main__": 进行判断。

这段代码通过终端交互的方式,让用户可以对学生信息进行增删改查等操作。用户可以根据菜单选择不同的功能。学生信息以字典的形式保存在列表中,而列表中的每个元素代表一个学生的信息。学生信息被保存在名为 students.txt 的文本文件中。

请注意,这只是一个简单的学生信息管理系统示例,功能相对基础。在实际应用中,可能需要更完善的错误处理、数据校验等功能。

# _*_ coding:utf-8   _*_
import re  # 导入正则表达式模块
import os  # 导入操作系统模块
 
filename = "students.txt"  # 定义保存学生信息的文件名
 
 
def menu():
    # 输出菜单
    print('''
    ╔———————学生信息管理系统————————╗
    │                                              │
    │   =============== 功能菜单 ===============   │
    │                                              │
    │   1 录入学生信息                             │
    │   2 查找学生信息                             │
    │   3 删除学生信息                             │
    │   4 修改学生信息                             │
    │   5 排序                                     │
    │   6 统计学生总人数                           │
    │   7 显示所有学生信息                         │
    │   0 退出系统                                 │
    │  ==========================================  │
    │  说明:通过数字或↑↓方向键选择菜单          │
    ╚———————————————————————╝
    ''')
 
 
def main():
    ctrl = True  # 标记是否退出系统
    while (ctrl):
        menu()  # 显示菜单
        option = input("请选择:")  # 选择菜单项
        option_str = re.sub("\D", "", option)  # 提取数字
        if option_str in ['0', '1', '2', '3', '4', '5', '6', '7']:
            option_int = int(option_str)
            if option_int == 0:  # 退出系统
                print('您已退出学生成绩管理系统!')
                ctrl = False
            elif option_int == 1:  # 录入学生成绩信息
                insert()
            elif option_int == 2:  # 查找学生成绩信息
                search()
            elif option_int == 3:  # 删除学生成绩信息
                delete()
            elif option_int == 4:  # 修改学生成绩信息
                modify()
            elif option_int == 5:  # 排序
                sort()
            elif option_int == 6:  # 统计学生总数
                total()
            elif option_int == 7:  # 显示所有学生信息
                show()
 
 
'''1 录入学生信息'''
 
 
def insert():
    stdentList = []        # 保存学生信息的列表
    mark = True  # 是否继续添加
    while mark:
        id = input("请输入ID(如 1001):")
        if not id:  # ID为空,跳出循环
            break
        name = input("请输入名字:")
        if not name:  # 名字为空,跳出循环
            break
        try:
            english = int(input("请输入英语成绩:"))
            python = int(input("请输入Python成绩:"))
            c = int(input("请输入C语言成绩:"))
        except:
            print("输入无效,不是整型数值....重新录入信息")
            continue
        stdent = {"id": id, "name": name, "english": english, "python": python, "c": c}  # 将输入的学生信息保存到字典
        stdentList.append(stdent)  # 将学生字典添加到列表中
        inputMark = input("是否继续添加?(y/n):")
        if inputMark == "y":  # 继续添加
            mark = True
        else:  # 不继续添加
            mark = False
    save(stdentList)  # 将学生信息保存到文件
    print("学生信息录入完毕!!!")
 
 
# 将学生信息保存到文件
def save(student):
    try:
        students_txt = open(filename, "a")  # 以追加模式打开
    except Exception as e:
        students_txt = open(filename, "w")  # 文件不存在,创建文件并打开
    for info in student:
        students_txt.write(str(info) + "\n")  # 按行存储,添加换行符
    students_txt.close()  # 关闭文件
 
 
'''2 查找学生成绩信息'''
 
 
def search():
    mark = True
    student_query = []  # 保存查询结果的学生列表
    while mark:
        id = ""
        name = ""
        if os.path.exists(filename):  # 判断文件是否存在
            mode = input("按ID查输入1;按姓名查输入2:")
            if mode == "1":
                id = input("请输入学生ID:")
            elif mode == "2":
                name = input("请输入学生姓名:")
            else:
                print("您的输入有误,请重新输入!")
                search()  # 重新查询
            with open(filename, 'r') as file:  # 打开文件
                student = file.readlines()  # 读取全部内容
                for list in student:
                    d = dict(eval(list))  # 字符串转字典
                    if id is not "":  # 判断是否按ID查
                        if d['id'] == id:
                            student_query.append(d)  # 将找到的学生信息保存到列表中
                    elif name is not "":  # 判断是否按姓名查
                        if d['name'] == name:
                            student_query.append(d)  # 将找到的学生信息保存到列表中
                show_student(student_query)  # 显示查询结果
                student_query.clear()  # 清空列表
                inputMark = input("是否继续查询?(y/n):")
                if inputMark == "y":
                    mark = True
                else:
                    mark = False
        else:
            print("暂未保存数据信息...")
            return
 
 
'''3 删除学生成绩信息'''
 
 
def delete():
    mark = True  # 标记是否循环
    while mark:
        studentId = input("请输入要删除的学生ID:")
        if studentId is not "":  # 判断要删除的学生是否存在
            if os.path.exists(filename):  # 判断文件是否存在
                with open(filename, 'r') as rfile:  # 打开文件
                    student_old = rfile.readlines()  # 读取全部内容
            else:
                student_old = []
            ifdel = False  # 标记是否删除
            if student_old:  # 如果存在学生信息
                with open(filename, 'w') as wfile:  # 以写方式打开文件
                    d = {}  # 定义空字典
                    for list in student_old:
                        d = dict(eval(list))  # 字符串转字典
                        if d['id'] != studentId:
                            wfile.write(str(d) + "\n")  # 将一条学生信息写入文件
                        else:
                            ifdel = True  # 标记已经删除
                    if ifdel:
                        print("ID为 %s 的学生信息已经被删除..." % studentId)
                    else:
                        print("没有找到ID为 %s 的学生信息..." % studentId)
            else:  # 不存在学生信息
                print("无学生信息...")
                break  # 退出循环
            show()  # 显示全部学生信息
            inputMark = input("是否继续删除?(y/n):")
            if inputMark == "y":
                mark = True  # 继续删除
            else:
                mark = False  # 退出删除学生信息功能
 
 
'''4 修改学生成绩信息'''
 
 
def modify():
    show()  # 显示全部学生信息
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
    else:
        return
    studentid = input("请输入要修改的学生ID:")
    with open(filename, "w") as wfile:  # 以写模式打开文件
        for student in student_old:
            d = dict(eval(student))  # 字符串转字典
            if d["id"] == studentid:  # 是否为要修改的学生
                print("找到了这名学生,可以修改他的信息!")
                while True:  # 输入要修改的信息
                    try:
                        d["name"] = input("请输入姓名:")
                        d["english"] = int(input("请输入英语成绩:"))
                        d["python"] = int(input("请输入Python成绩:"))
                        d["c"] = int(input("请输入C语言成绩:"))
                    except:
                        print("您的输入有误,请重新输入。")
                    else:
                        break  # 跳出循环
                student = str(d)  # 将字典转换为字符串
                wfile.write(student + "\n")   # 将修改的信息写入到文件
                print("修改成功!")
            else:
                wfile.write(student)  # 将未修改的信息写入到文件
    mark = input("是否继续修改其他学生信息?(y/n):")
    if mark == "y":
        modify()  # 重新执行修改操作
 
 
'''5 排序'''
 
 
def sort():
    show()  # 显示全部学生信息
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as file:  # 打开文件
            student_old = file.readlines()  # 读取全部内容
            student_new = []
        for list in student_old:
            d = dict(eval(list))  # 字符串转字典
            student_new.append(d)  # 将转换后的字典添加到列表中
    else:
        return
    ascORdesc = input("请选择(0升序;1降序):")
    if ascORdesc == "0":  # 按升序排序
        ascORdescBool = False           # 标记变量,为False表示升序排序
    elif ascORdesc == "1":  # 按降序排序
        ascORdescBool = True          # 标记变量,为True表示降序排序
    else:
        print("您的输入有误,请重新输入!")
        sort()  
    mode = input("请选择排序方式(1按英语成绩排序;2按Python成绩排序;3按C语言成绩排序;0按总成绩排序):")
    if mode == "1":  # 按英语成绩排序
        student_new.sort(key=lambda x: x["english"], reverse=ascORdescBool)
    elif mode == "2":  # 按Python成绩排序
        student_new.sort(key=lambda x: x["python"], reverse=ascORdescBool)
    elif mode == "3":  # 按C语言成绩排序
        student_new.sort(key=lambda x: x["c"], reverse=ascORdescBool)
    elif mode == "0":  # 按总成绩排序
        student_new.sort(key=lambda x: x["english"] + x["python"] + x["c"], reverse=ascORdescBool)
    else:
        print("您的输入有误,请重新输入!")
        sort()
    show_student(student_new)  # 显示排序结果
 
 
''' 6 统计学生总数'''
 
 
def total():
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
            if student_old:
                print("一共有 %d 名学生!" % len(student_old))
            else:
                print("还没有录入学生信息!")
    else:
        print("暂未保存数据信息...")
 
 
''' 7 显示所有学生信息 '''
 
 
def show():
    student_new = []
    if os.path.exists(filename):  # 判断文件是否存在
        with open(filename, 'r') as rfile:  # 打开文件
            student_old = rfile.readlines()  # 读取全部内容
        for list in student_old:
            student_new.append(eval(list))  # 将找到的学生信息保存到列表中
        if student_new:
            show_student(student_new)
    else:
        print("暂未保存数据信息...")
 
 
# 将保存在列表中的学生信息显示出来
def show_student(studentList):
    if not studentList:
        print("(o@.@o) 无数据信息 (o@.@o) \n")
        return
    format_title = "{:^6}{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^10}"
    print(format_title.format("ID", "名字", "英语成绩", "Python成绩", "C语言成绩", "总成绩"))
    format_data = "{:^6}{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}"
    for info in studentList:
        print(format_data.format(info.get("id"), info.get("name"), str(info.get("english")), str(info.get("python")),
                                 str(info.get("c")),
                                 str(info.get("english") + info.get("python") + info.get("c")).center(12)))
 
 
if __name__ == "__main__":
    main()

[GUI]fps游戏辅助屏幕准星工具

uupython阅读(448)

这段代码使用 tkinter 创建一个透明的顶级窗口,然后在窗口中绘制一个十字准星,并将窗口设置为全屏显示。以下是代码的主要部分:

  1. 获取屏幕的宽度和高度,使用 pyautogui.size() 函数。
  2. 创建一个透明的顶级窗口,并使用窗口属性来设置透明颜色、全屏显示、置顶显示等。
  3. 创建一个画布(Canvas)来进行绘图。
  4. 使用 canvas.create_line() 函数在画布上绘制两条线,形成十字准星,以突出屏幕中心。
  5. 启动 tkinter 主循环,以保持画面不关闭。

这段代码的目的似乎是在屏幕中心绘制一个十字准星,但值得注意的是,代码中使用的 pyautogui 库用于获取屏幕尺寸,并非绘图的主要部分。如果只是想要在屏幕中心绘制十字准星,可以直接使用 tkinter 绘图功能,而无需引入 pyautogui 库。例如:

import tkinter as tk

# 创建一个透明的顶级窗口
window = tk.Tk()
window.attributes("-transparentcolor", "white")
window.attributes("-fullscreen", True)
window.lift()
window.attributes('-topmost', True)
window.configure(bg='white')

# 创建一个画布来绘图
canvas = tk.Canvas(window, bg='white', highlightthickness=0)
canvas.pack(fill=tk.BOTH, expand=tk.YES)

# 获取屏幕宽度和高度
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()

# 绘制十字准星
canvas.create_line(screen_width / 2, screen_height/2+10, screen_width / 2, screen_height/2-10, width=2, fill='red')
canvas.create_line(screen_width/2+10, screen_height / 2, screen_width/2-10, screen_height / 2, width=2, fill='red')

# 开启循环,保持画面不关闭
window.mainloop()

这样,你可以在屏幕中心绘制一个十字准星,而不需要使用额外的库。

import tkinter as tk
import pyautogui

# 获取屏幕宽度和高度
screen_width,screen_height = pyautogui.size()

# 创建一个透明的顶级窗口
window = tk.Tk()
window.attributes("-transparentcolor", "white")
window.attributes("-fullscreen", True)
window.lift()
window.attributes('-topmost', True)
window.configure(bg='white')

# 创建一个画布来绘图
canvas = tk.Canvas(window, bg='white', highlightthickness=0)
canvas.pack(fill=tk.BOTH, expand=tk.YES)

# 绘制十字准星
canvas.create_line(screen_width / 2, screen_height/2+10, screen_width / 2, screen_height/2-10, width=2, fill='red')
canvas.create_line(screen_width/2+10, screen_height / 2, screen_width/2-10, screen_height / 2, width=2, fill='red')

# 开启循环,保持画面不关闭
window.mainloop()

[GUI]阿里云DDNS更新器

uupython阅读(548)

这段代码实现了一个用于自动更新阿里云 DNS 记录的 GUI 程序。用户可以输入阿里云的 Access Key ID、Access Key Secret、域名和子域名,然后点击按钮来检查当前的公网 IP 地址,与 DNS 记录中的 IP 地址进行比较,如果不一致,则自动更新 DNS 记录。

以下是代码的主要部分:

  1. config.ini 配置文件中读取默认的 Access Key ID、Access Key Secret、域名和子域名。
  2. 创建一个 tkinter 主窗口,并设置窗口大小和标题。
  3. 创建输入框和标签,用于输入 Access Key ID、Access Key Secret、域名和子域名。如果配置文件中存在默认值,则会预填充输入框。
  4. 创建一个滚动文本框,用于显示输出信息。
  5. get_current_ip 函数:通过向 ipinfo.io 发送请求,获取当前主机的公网 IP 地址。
  6. compute_signature 函数:根据给定的参数和 Access Key Secret 计算签名。
  7. send_request 函数:构造请求参数,发送请求并返回响应结果。
  8. get_record_value 函数:获取当前子域名的 DNS 记录值和记录 ID。
  9. update_dns 函数:更新 DNS 记录。
  10. start_process 函数:开始更新 DNS 记录的流程。获取当前 IP 地址,与 DNS 记录中的 IP 进行比较,如果不一致,则更新 DNS 记录。
  11. 创建一个更新按钮,当点击按钮时会调用 start_process 函数。
  12. 启动 tkinter 主循环。

请注意,这是一个用于阿里云 DNS 记录更新的示例代码,其中可能会缺少某些错误处理和细节。为了确保程序的稳定性和安全性,你可能需要添加适当的错误处理和用户交互提示。同时,确保在使用敏感信息(如 Access Key 和 Access Key Secret)时,注意安全性。

import configparser
import sys
import requests
import urllib.parse
import hmac
import base64
import hashlib
import time
import uuid
from datetime import datetime
import tkinter as tk
from tkinter import scrolledtext
 
# 尝试从配置文件中读取配置
config = configparser.ConfigParser()
config.read('config.ini')
 
try:
    access_key_id_default = config.get('aliyun', 'access_key_id')
    access_key_secret_default = config.get('aliyun', 'access_key_secret')
    domain_default = config.get('aliyun', 'domain')
    subdomain_default = config.get('aliyun', 'subdomain')
except:
    access_key_id_default = ""
    access_key_secret_default = ""
    domain_default = ""
    subdomain_default = ""
 
# 创建主窗口并设置窗口大小和标题
root = tk.Tk()
root.geometry('400x350')
root.title('阿里云DDNS')
 
# 创建输入框和对应的标签,如果配置文件存在,则预填充输入框
access_key_id_label = tk.Label(root, text="Access Key ID:")
access_key_id_label.pack()
access_key_id_entry = tk.Entry(root, width=50)
access_key_id_entry.insert(0, access_key_id_default)
access_key_id_entry.pack()
 
access_key_secret_label = tk.Label(root, text="Access Key Secret:")
access_key_secret_label.pack()
access_key_secret_entry = tk.Entry(root, width=50)
access_key_secret_entry.insert(0, access_key_secret_default)
access_key_secret_entry.pack()
 
domain_label = tk.Label(root, text="Domain:")
domain_label.pack()
domain_entry = tk.Entry(root, width=50)
domain_entry.insert(0, domain_default)
domain_entry.pack()
 
subdomain_label = tk.Label(root, text="Subdomain:")
subdomain_label.pack()
subdomain_entry = tk.Entry(root, width=50)
subdomain_entry.insert(0, subdomain_default)
subdomain_entry.pack()
 
# 创建一个滚动文本框来显示输出
output_text = scrolledtext.ScrolledText(root, height=10, width=50)
output_text.pack()
 
# 获取当前主机的公网IP
def get_current_ip():
    try:
        response = requests.get('http://ipinfo.io/json')
        return response.json()['ip']
    except Exception as e:
        output_text.insert(tk.END, f'获取当前IP失败: {str(e)}\n')
        return None
 
# 生成签名
def compute_signature(access_key_secret, parameters):
    sorted_parameters = sorted(parameters.items(), key=lambda item:item[0])
    canonicalized_query_string = urllib.parse.urlencode(sorted_parameters)
    string_to_sign = 'GET&%2F&' + urllib.parse.quote(canonicalized_query_string, safe='~')
    h = hmac.new((access_key_secret + "&").encode('utf-8'), string_to_sign.encode('utf-8'), hashlib.sha1)
    signature = base64.encodebytes(h.digest()).strip()
    return signature.decode('utf-8')
 
# 发送请求
def send_request(parameters):
    common_parameters = {
        'Format': 'JSON',
        'Version': '2015-01-09',
        'AccessKeyId': access_key_id_entry.get(),
        'SignatureMethod': 'HMAC-SHA1',
        'Timestamp': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        'SignatureVersion': '1.0',
        'SignatureNonce': str(uuid.uuid1()),
    }
    parameters.update(common_parameters)
    parameters['Signature'] = compute_signature(access_key_secret_entry.get(), parameters)
    url = 'https://alidns.aliyuncs.com/?' + urllib.parse.urlencode(parameters)
    try:
        response = requests.get(url)
        return response.json()
    except Exception as e:
        output_text.insert(tk.END, f'发送请求失败: {str(e)}\n')
        return None
 
# 获取DNS记录的当前值
def get_record_value():
    parameters = {
        'Action': 'DescribeSubDomainRecords',
        'SubDomain': f"{subdomain_entry.get()}.{domain_entry.get()}",
    }
    records = send_request(parameters)
    if records and records['TotalCount'] != 0:
        for record in records['DomainRecords']['Record']:
            if record['Type'] == 'A':  # 检查记录类型是否为'A'
                output_text.insert(tk.END, f"找到A记录,RecordId:{record['RecordId']},值:{record['Value']}\n")
                return record['Value'], record['RecordId']
    return None, None
 
# 更新DNS记录
def update_dns(record_id, ip):
    parameters = {
        'Action': 'UpdateDomainRecord',
        'RecordId': record_id,
        'RR': subdomain_entry.get(),
        'Type': 'A',
        'Value': ip,
    }
    response = send_request(parameters)
    if response:
        output_text.insert(tk.END, f'DNS记录已更新为 {ip}\n')
    return response
 
# 创建一个按钮,当点击这个按钮时会调用 update_dns_records 函数
def start_process():
    current_ip = get_current_ip()
    if current_ip:
        output_text.insert(tk.END, f'当前IP为 {current_ip}\n')
        record_value, record_id = get_record_value()
 
        if record_value is None or record_id is None:  
            output_text.insert(tk.END, '未找到当前DNS记录\n')
        else:
            output_text.insert(tk.END, f'当前DNS记录为 {record_value}\n')
            if record_value != current_ip:
                response = update_dns(record_id, current_ip)
                if response and response.get('RecordId') == record_id:  
                    output_text.insert(tk.END, 'DNS记录更新成功\n')
            else:
                output_text.insert(tk.END, '无需更新DNS记录\n')
 
update_button = tk.Button(root, text="更新DNS记录", command=start_process)
update_button.pack()
 
# 启动主循环
root.mainloop()