当前位置:   article > 正文

桌宠1.0,微信连接gpt_pythongpt桌宠

pythongpt桌宠

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

  1. import sys
  2. import os
  3. from functools import partial
  4. from PyQt5.QtGui import *
  5. from PyQt5.QtCore import *
  6. from PyQt5.QtWidgets import *
  7. from PyQt5 import QtGui, QtCore, QtWidgets
  8. from PyQt5.QtCore import QProcess
  9. import wxchat
  10. import threading
  11. event = threading.Event() # 共享的标志用于告知线程2何时结束
  12. class Qt_pet(QtWidgets.QWidget):
  13. def __init__(self):
  14. super(Qt_pet, self).__init__()
  15. self.dis_file = "img1"
  16. self.windowinit()
  17. self.icon_quit()
  18. self.pos_first = self.pos()
  19. self.timer = QTimer()
  20. self.timer.timeout.connect(self.img_update)
  21. self.timer.start(100)
  22. def img_update(self):
  23. if self.img_num < len(self.dir2img[self.current_dir])-1:
  24. self.img_num += 1
  25. else:
  26. self.img_num = 0
  27. self.qpixmap = QtGui.QPixmap(os.path.join(self.current_dir, self.dir2img[self.current_dir][self.img_num]))
  28. self.lab.setMaximumSize(self.pet_width, self.pet_height)
  29. self.lab.setScaledContents(True)
  30. # 重新设置lab的大小与图片保持一致
  31. self.lab.setGeometry(0, 0, self.qpixmap.width(), self.qpixmap.height())
  32. self.lab.setPixmap(self.qpixmap)
  33. # 获取放图片的路径,图片文件必须放在D:/Program Files (x86)/pet_conf/或者D:/Program Files/pet_conf/中,在里面放一个名为 imgN(比如img1,img2,img3的文件夹)的文件夹,文件夹中放具体的图片,图片的格式为N.png(比如1.png,2.png等)
  34. def get_conf_dir(self):
  35. conf_dirs = [r"你的图片地址"]
  36. for conf_dir in conf_dirs:
  37. if os.path.exists(conf_dir) and os.path.isdir(conf_dir):
  38. self.conf_dir = conf_dir
  39. for root, dirs, files in os.walk(self.conf_dir):
  40. if root in conf_dirs:
  41. for dir in dirs:
  42. for r, _, f in os.walk(os.path.join(root, dir)):
  43. if r == os.path.join(root, dir) and len(f)>0:
  44. try:
  45. f.sort(key=lambda x: int(x.split(sep='.', maxsplit=1)[0]))
  46. except ValueError:
  47. f.sort(key=lambda x: x.split(sep='.', maxsplit=1)[0])
  48. self.dir2img.update({r: f})
  49. return True
  50. QtWidgets.QMessageBox.warning(None, "警告", "没有找到配置文件!请查看使用说明", QtWidgets.QMessageBox.StandardButton.Ok)
  51. return False
  52. def windowinit(self):
  53. # 初始窗口设置大一点以免放入的图片显示不全
  54. self.pet_width = 500
  55. self.pet_height = 500
  56. # 获取桌面桌面大小决定宠物的初始位置为右上角
  57. desktop = QtWidgets.QApplication.desktop()
  58. self.x = desktop.width()-self.pet_width
  59. self.y = 100
  60. self.setGeometry(self.x, self.y, self.pet_width, self.pet_height)
  61. self.setWindowTitle('桌面宠物-by')
  62. self.img_num = 0
  63. # 找到配置文件,失败则退出
  64. self.dir2img = {}
  65. if not self.get_conf_dir():
  66. self.quit()
  67. self.lab = QtWidgets.QLabel(self)
  68. self.current_dir = list(self.dir2img.keys())[0]
  69. self.qpixmap = QtGui.QPixmap(os.path.join(self.current_dir, self.dir2img[self.current_dir][self.img_num]))
  70. self.lab.setPixmap(self.qpixmap)
  71. # 设置窗口为 无边框 | 保持顶部显示
  72. self.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint| QtCore.Qt.WindowType.WindowStaysOnTopHint)
  73. # 设置窗口透明
  74. self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)
  75. # 设置窗口的属性,使其不在任务栏显示
  76. self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.Tool)
  77. self.show()
  78. # 设置系统托盘
  79. def icon_quit(self):
  80. mini_icon = QtWidgets.QSystemTrayIcon(self)
  81. mini_icon.setIcon(QtGui.QIcon(os.path.join(self.current_dir, self.dir2img[self.current_dir][0])))
  82. mini_icon.setToolTip("桌面宠物-by")
  83. # 1 toggle()、triggered()、clicked()区别
  84. # 这三个信号都是按钮点击后发射的信号,区别在于:
  85. # clicked()用于Button发射的信号
  86. # triggered()用于QAction发射的信号,原型:​​void triggered(bool checked = false);​​
  87. # toggle()用于ChekBox,非开即关,原型:​​void toggled(bool);​​
  88. quit_menu = QtWidgets.QAction('退出', self, triggered=self.quit)
  89. tpMenu = QtWidgets.QMenu(self)
  90. changeSubMenu = QtWidgets.QMenu(self)
  91. changeSubMenu.setTitle("切换")
  92. for dir in self.dir2img.keys():
  93. act = QtWidgets.QAction(os.path.basename(dir), self, triggered=partial(self.changeImg, dir))
  94. changeSubMenu.addAction(act)
  95. tpMenu.addMenu(changeSubMenu)
  96. tpMenu.addAction(quit_menu)
  97. mini_icon.setContextMenu(tpMenu)
  98. mini_icon.show()
  99. # 鼠标左键按下的时候获取当前位置
  100. def mousePressEvent(self, QMouseEvent):
  101. if QMouseEvent.button() == QtCore.Qt.MouseButton.LeftButton:
  102. self.pos_first = QMouseEvent.globalPos() - self.pos()
  103. QMouseEvent.accept()
  104. self.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.OpenHandCursor))
  105. # 拖动移动
  106. def mouseMoveEvent(self, QMouseEvent):
  107. self.move(QMouseEvent.globalPos() - self.pos_first)
  108. # self.x, self.y = self.pos().x, self.pos().y
  109. QMouseEvent.accept()
  110. def quit(self):
  111. event.set()
  112. self.close()
  113. sys.exit()
  114. def changeImg(self, dir):
  115. self.current_dir = dir
  116. def mypet():
  117. app = QApplication(sys.argv)
  118. pet = Qt_pet()
  119. sys.exit(app.exec_())
  120. if __name__ == '__main__':
  121. t1 = threading.Thread(target=wxchat.resize_wechat_window)
  122. t2 = threading.Thread(target=mypet)
  123. t1.start()
  124. t2.start()

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

  1. import pygetwindow as gw
  2. import pyautogui
  3. import pyperclip
  4. import time
  5. import get_API
  6. from windows_pet import event
  7. def resize_wechat_window(): # 调整窗口大小
  8. window_titles = gw.getAllTitles() # 获取所有打开的窗口
  9. wechat_window = None
  10. for title in window_titles: # 判断是否存在标题包含“微信”的窗口
  11. if "微信" in title:
  12. wechat_window = gw.getWindowsWithTitle(title)[0]
  13. break
  14. if wechat_window:
  15. wechat_window.restore() # 还原窗口
  16. wechat_window.activate() # 激活窗口显示在前台
  17. wechat_window.resizeTo(700, 500)
  18. autowx()
  19. else:
  20. print("微信窗口未找到")
  21. def autowx():
  22. red = r'you_red.png' # 消息来了的红图标
  23. name = r'you_name.png' # 接收人的图标
  24. while True:
  25. #print(event.is_set())
  26. if event.is_set():
  27. break
  28. else:
  29. location_red = pyautogui.locateCenterOnScreen(red, confidence=0.90)
  30. location_name = pyautogui.locateCenterOnScreen(name, confidence=0.90)
  31. if location_red and location_name:
  32. if location_red[0] - location_name[0] < 50:
  33. pyautogui.click(location_red)
  34. text = find_txt()
  35. else:
  36. time.sleep(1)
  37. def find_txt():
  38. pos3 = r'you_pos3.png' # 聊天窗口
  39. while True:
  40. locations_pos3 = pyautogui.locateAllOnScreen(pos3, confidence=0.98) # 所有坐标
  41. if locations_pos3:
  42. break
  43. else:
  44. print("没有收到窗口消息,1秒后重试")
  45. time.sleep(1)
  46. time.sleep(0.1)
  47. list_text = list(locations_pos3)
  48. if list_text != []:
  49. pos = sorted(list_text, key=lambda x:x[1], reverse=True)[0] # lambda x:x[1]元组的第二个元素从小到大排序的顺 # reverse降序
  50. pyautogui.doubleClick(x = pos[0] + 15 + pos[2] / 2,y = pos[1] + pos[3] / 2)
  51. time.sleep(0.1)
  52. pyautogui.hotkey('ctrl', 'c')
  53. time.sleep(0.1)
  54. text = pyperclip.paste()
  55. get_API.getchat(text)
  56. def givechat(text):
  57. pos1 = r'you_pos1.png' # 笑脸图标
  58. send = r'you_send.png' # 发送图标
  59. while True:
  60. location_pos1 = pyautogui.locateCenterOnScreen(pos1, confidence=0.90)
  61. location_send = pyautogui.locateCenterOnScreen(send, confidence=0.90)
  62. if location_pos1 and location_send:
  63. break
  64. else:
  65. print("没有收到gpt消息,1秒后重试")
  66. time.sleep(1)
  67. pyautogui.click(location_pos1[0], location_pos1[1]+30)
  68. pyperclip.copy(text)
  69. pyautogui.hotkey('ctrl', 'v')
  70. time.sleep(0.1)
  71. pyautogui.click(location_send)
  72. #if __name__ == '__main__':
  73. #resize_wechat_window()

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

  1. from openai import OpenAI
  2. import httpx
  3. import wxchat
  4. def getchat(access):
  5. client = OpenAI(
  6. base_url="https://oneapi.xty.app/v1",
  7. api_key="you_API",
  8. http_client=httpx.Client(
  9. base_url="https://oneapi.xty.app/v1",
  10. follow_redirects=True,
  11. ),
  12. )
  13. completion = client.chat.completions.create(
  14. model="gpt-3.5-turbo",
  15. temperature=0.99,
  16. max_tokens=2048,
  17. messages=[{"role": "system",
  18. "content": "you_初始化文本"},
  19. {"role": "user", "content": access}]
  20. )
  21. response = completion.choices[0].message.content
  22. wxchat.givechat(response)

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/699942
推荐阅读
相关标签
  

闽ICP备14008679号