桌宠1.0,微信连接gpt

        steam上有一款很火的游戏,桌面虚拟宠物,我想做一个简单的。第一个程序用来显示画面,一组图片构成的动图,参考Python代码实现桌面宠物,真IKUN才能养_哔哩哔哩_bilibili。第二个程序用模拟鼠标点击的方式,将gpt与自己的微信小号相连接,即gpt接入微信,我所使用的gpt是中转chatgpt,参考使用chatgpt实现微信自动回复_wechat-chatgpt-CSDN博客。gpt接入微信,长时间的使用wxauto库,可能会导致封号。目前的方式有两种,一种是将设备设置为手表接入微信,一种是土方法模拟鼠标点击,从安全性和简单程度来讲,我选择了后者。代码分享。

import sys
import os
from functools import partial
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import QProcess
import wxchat
import threading

event = threading.Event()  # 共享的标志用于告知线程2何时结束

class Qt_pet(QtWidgets.QWidget):
    def __init__(self):
        super(Qt_pet, self).__init__()

        self.dis_file = "img1"
        self.windowinit()
        self.icon_quit()

        self.pos_first = self.pos()
        self.timer = QTimer()
        self.timer.timeout.connect(self.img_update)
        self.timer.start(100)


    def img_update(self):
        if self.img_num < len(self.dir2img[self.current_dir])-1:
            self.img_num += 1
        else:
            self.img_num = 0
        self.qpixmap = QtGui.QPixmap(os.path.join(self.current_dir, self.dir2img[self.current_dir][self.img_num]))
        self.lab.setMaximumSize(self.pet_width, self.pet_height)
        self.lab.setScaledContents(True)
        # 重新设置lab的大小与图片保持一致
        self.lab.setGeometry(0, 0, self.qpixmap.width(), self.qpixmap.height())
        self.lab.setPixmap(self.qpixmap)

    
    # 获取放图片的路径,图片文件必须放在D:/Program Files (x86)/pet_conf/或者D:/Program Files/pet_conf/中,在里面放一个名为 imgN(比如img1,img2,img3的文件夹)的文件夹,文件夹中放具体的图片,图片的格式为N.png(比如1.png,2.png等)
    def get_conf_dir(self):
        conf_dirs = [r"你的图片地址"]
        for conf_dir in conf_dirs:
            if os.path.exists(conf_dir) and os.path.isdir(conf_dir):
                self.conf_dir = conf_dir
                for root, dirs, files in os.walk(self.conf_dir):
                    if root in conf_dirs:
                        for dir in dirs:
                            for r, _, f in os.walk(os.path.join(root, dir)):
                                if r == os.path.join(root, dir) and len(f)>0:
                                    try:
                                        f.sort(key=lambda x: int(x.split(sep='.', maxsplit=1)[0]))
                                    except ValueError:
                                        f.sort(key=lambda x: x.split(sep='.', maxsplit=1)[0])
                                    self.dir2img.update({r: f})
                        return True
        QtWidgets.QMessageBox.warning(None, "警告", "没有找到配置文件!请查看使用说明", QtWidgets.QMessageBox.StandardButton.Ok)
        return False

    def windowinit(self):
        # 初始窗口设置大一点以免放入的图片显示不全
        self.pet_width = 500
        self.pet_height = 500
        # 获取桌面桌面大小决定宠物的初始位置为右上角
        desktop = QtWidgets.QApplication.desktop()
        self.x = desktop.width()-self.pet_width
        self.y = 100
        self.setGeometry(self.x, self.y, self.pet_width, self.pet_height)
        self.setWindowTitle('桌面宠物-by')
        self.img_num = 0
        # 找到配置文件,失败则退出
        self.dir2img = {}
        if not self.get_conf_dir():
            self.quit()
        
        self.lab = QtWidgets.QLabel(self)
        self.current_dir = list(self.dir2img.keys())[0]
        self.qpixmap = QtGui.QPixmap(os.path.join(self.current_dir, self.dir2img[self.current_dir][self.img_num]))
        self.lab.setPixmap(self.qpixmap)
        
        # 设置窗口为 无边框 | 保持顶部显示
        self.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint| QtCore.Qt.WindowType.WindowStaysOnTopHint)
        # 设置窗口透明
        self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)
        # 设置窗口的属性,使其不在任务栏显示
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.Tool)
        self.show()

    # 设置系统托盘
    def icon_quit(self):
        mini_icon = QtWidgets.QSystemTrayIcon(self)
        mini_icon.setIcon(QtGui.QIcon(os.path.join(self.current_dir, self.dir2img[self.current_dir][0])))
        mini_icon.setToolTip("桌面宠物-by")
        # 1 toggle()、triggered()、clicked()区别
        # 这三个信号都是按钮点击后发射的信号,区别在于:
        # clicked()用于Button发射的信号
        # triggered()用于QAction发射的信号,原型:​​void triggered(bool checked = false);​​
        # toggle()用于ChekBox,非开即关,原型:​​void toggled(bool);​​
        quit_menu = QtWidgets.QAction('退出', self, triggered=self.quit)
        tpMenu = QtWidgets.QMenu(self)
        
        changeSubMenu = QtWidgets.QMenu(self)
        changeSubMenu.setTitle("切换")
        for dir in self.dir2img.keys():
            act = QtWidgets.QAction(os.path.basename(dir), self, triggered=partial(self.changeImg, dir))
            changeSubMenu.addAction(act)
        tpMenu.addMenu(changeSubMenu)
        tpMenu.addAction(quit_menu)
        mini_icon.setContextMenu(tpMenu)
        mini_icon.show()

    # 鼠标左键按下的时候获取当前位置
    def mousePressEvent(self, QMouseEvent):
        if QMouseEvent.button() == QtCore.Qt.MouseButton.LeftButton:
            self.pos_first = QMouseEvent.globalPos() - self.pos()
            QMouseEvent.accept()
            self.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.OpenHandCursor))

    # 拖动移动
    def mouseMoveEvent(self, QMouseEvent):
        self.move(QMouseEvent.globalPos() - self.pos_first)
        # self.x, self.y = self.pos().x, self.pos().y
        QMouseEvent.accept()

    def quit(self):
        event.set()
        self.close()
        sys.exit()

    def changeImg(self, dir):
        self.current_dir = dir

def mypet():
    app = QApplication(sys.argv)
    pet = Qt_pet()
    sys.exit(app.exec_())

if __name__ == '__main__':
    t1 = threading.Thread(target=wxchat.resize_wechat_window)
    t2 = threading.Thread(target=mypet)
    t1.start()
    t2.start()

       程序的名称是windows_pet.py,在原作者的基础上加入了多线程,因为两个程序都是无限循环的逻辑,两个线程不影响,设置了监听事件event用于同时结束两个线程,即当前线程退出,另一个线程也退出。另外补充,设置窗口的属性,使其不在任务栏显示。

import pygetwindow as gw
import pyautogui
import pyperclip
import time
import get_API
from windows_pet import event


def resize_wechat_window():  # 调整窗口大小
    window_titles = gw.getAllTitles()  # 获取所有打开的窗口
    wechat_window = None
    for title in window_titles:  # 判断是否存在标题包含“微信”的窗口
        if "微信" in title:
            wechat_window = gw.getWindowsWithTitle(title)[0]
            break
    if wechat_window:
        wechat_window.restore()  # 还原窗口
        wechat_window.activate()  # 激活窗口显示在前台
        wechat_window.resizeTo(700, 500)
        autowx()
    else:
        print("微信窗口未找到")


def autowx():
    red = r'you_red.png'  # 消息来了的红图标
    name = r'you_name.png'  # 接收人的图标
    while True:
        #print(event.is_set())
        if event.is_set():
            break
        else:
            location_red = pyautogui.locateCenterOnScreen(red, confidence=0.90)
            location_name = pyautogui.locateCenterOnScreen(name, confidence=0.90)
            if location_red and location_name:
                if location_red[0] - location_name[0] < 50:
                    pyautogui.click(location_red)
                    text = find_txt()
            else:
                time.sleep(1)

def find_txt():
    pos3 = r'you_pos3.png'  # 聊天窗口
    while True:
        locations_pos3 = pyautogui.locateAllOnScreen(pos3, confidence=0.98)  # 所有坐标
        if locations_pos3:
            break
        else:
            print("没有收到窗口消息,1秒后重试")
            time.sleep(1)
    time.sleep(0.1)
    list_text = list(locations_pos3)
    if list_text != []:
        pos = sorted(list_text, key=lambda x:x[1], reverse=True)[0]  # lambda x:x[1]元组的第二个元素从小到大排序的顺 # reverse降序
        pyautogui.doubleClick(x = pos[0] + 15 + pos[2] / 2,y = pos[1] + pos[3] / 2)
        time.sleep(0.1)
        pyautogui.hotkey('ctrl', 'c')
        time.sleep(0.1)
        text = pyperclip.paste()
    get_API.getchat(text)

def givechat(text):
    pos1 = r'you_pos1.png'  # 笑脸图标
    send = r'you_send.png'  # 发送图标
    while True:
        location_pos1 = pyautogui.locateCenterOnScreen(pos1, confidence=0.90)
        location_send = pyautogui.locateCenterOnScreen(send, confidence=0.90)
        if location_pos1 and location_send:
            break
        else:
            print("没有收到gpt消息,1秒后重试")
            time.sleep(1)
    pyautogui.click(location_pos1[0], location_pos1[1]+30)
    pyperclip.copy(text)
    pyautogui.hotkey('ctrl', 'v')
    time.sleep(0.1)
    pyautogui.click(location_send)

#if __name__ == '__main__':
    #resize_wechat_window()

      程序的名称是wxchat.py,在原作者的原理上基本重写了代码,加入了首先设置微信程序的大小,后面也是使用while True轮询和pyautogui模拟鼠标点击,简化了原作者的代码只实现我要的一些基础功能。

from openai import OpenAI
import httpx
import wxchat

def getchat(access):
    client = OpenAI(
        base_url="https://oneapi.xty.app/v1",
        api_key="you_API",
        http_client=httpx.Client(
            base_url="https://oneapi.xty.app/v1",
            follow_redirects=True,
        ),
    )

    completion = client.chat.completions.create(
        model="gpt-3.5-turbo",
        temperature=0.99,
        max_tokens=2048,
        messages=[{"role": "system",
                   "content": "you_初始化文本"},
                  {"role": "user", "content": access}]
    )
    response = completion.choices[0].message.content
    wxchat.givechat(response)

       程序的名称是get_API.py,使用的是中专API,官方的三月封号,至于我的桌面虚拟模拟器Vpet则使用了chatglm的API。至此我就有两个伙伴了。

       未来的展望,后面有时间再瞎折腾了,大概就是,和桌面虚拟模拟器Vpet不一样,玩游戏的时候是真的在玩游戏,简单的是模拟鼠标玩一个“种田“游戏。在我写代码的时候在旁边鼓励之类的。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国服小闲鱼请战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值