标题应该改为:python+win32发送QQ消息,全程使用python套个pyqt壳。
其实代码来自: http://blog.csdn.net/suzyu12345/article/details/52934328
只是说明几个问题
1.在64位windows系统中不可用
虽然可获取窗体句柄,但无法使用SendMessage 发送消息
2.QQ必须处于Windows的活动状态
QQ必须处于桌面的活动状态
3.发送的消息必须临时保存在剪贴板
通过剪贴板在发送出去
win32gui.SendMessage(win, 770) 770发送来自剪贴板的内容
代码如下:
# -*- coding: utf-8 -*- from PyQt5.QtWidgets import * from PyQt5 import QtGui, QtCore import sys import win32gui import win32con import win32clipboard import time class MainWidgetUI(QDialog): def __init__(self, parent=None): super(MainWidgetUI, self).__init__(parent) self.setWindowIcon(QtGui.QIcon("favicon.ico")) self.setWindowTitle('python 模拟发送QQ消息') self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) # 在最前端 self.mainLayout = QVBoxLayout() # 水平布局 # top发送类型group布局 self.topgroupBox = QGroupBox("发送类型") self.topLayout = QHBoxLayout(self.topgroupBox) self.radiobtn1 = QRadioButton('搜索发送') self.radiobtn2 = QRadioButton('直接发送') self.topLayout.addWidget(self.radiobtn1) self.topLayout.addWidget(self.radiobtn2) # lineEdit self.lineEdit = QLineEdit() self.lineEdit.setPlaceholderText('填写QQ聊天title --(昵称)') self.text = QTextEdit() self.text.setPlaceholderText("QQ发送的内容") # 发送按钮 self.sendbtnLayout = QHBoxLayout() # 垂直布局 self.searchBtn = QPushButton(QtGui.QIcon("favicon.ico"), '发送1') self.searchBtn2 = QPushButton(QtGui.QIcon("favicon.ico"), '发送2') self.sendbtnLayout.addWidget(self.searchBtn2) self.sendbtnLayout.addWidget(self.searchBtn) # mainLayout 布局 self.mainLayout.addWidget( self.topgroupBox) # 也可以self.mainLayout.addLayout(self.topLayout) self.topLayout = QHBoxLayout() (不继承topgroupBox) self.mainLayout.addWidget(self.lineEdit) self.mainLayout.addWidget(self.text) self.mainLayout.addLayout(self.sendbtnLayout) self.setLayout(self.mainLayout) # 得到焦点 self.lineEdit.setFocus() # 添加事件 self.searchBtn.clicked.connect(self.clickBtn) # 点击按钮 self.searchBtn2.clicked.connect(self.clickBtn) # 初始发送类型 self.radio = False def clickBtn(self): if self.validate(): # params 验证通过 sendq = SendQQMessages() res = sendq._sending(self.radio, self.lineEdit.text(), self.text.toPlainText()) if res: self.text.setFocus() # 获取焦点 self.text.selectAll() # 全选 QMessageBox.warning(self, u'错误提示!', "发送成功", QMessageBox.Yes) else: QMessageBox.information(self, u'错误提示!', "发送失败", QMessageBox.Yes) # 清空剪贴板 sendq.EmptyClipboard() def validate(self): ''' 检测 input数据 ''' if (self.radiobtn1.isChecked() == False and self.radiobtn2.isChecked() == False): QMessageBox.warning(self, u'错误提示!', "选择发送类型", QMessageBox.Yes) return False elif self.radiobtn1.isChecked(): self.radio = 1 elif self.radiobtn2.isChecked(): self.radio = 2 if self.lineEdit.text() == '': QMessageBox.warning(self, u'错误提示!', "填写QQ昵称", QMessageBox.Yes) return False if self.text.toPlainText() == '': QMessageBox.warning(self, u'错误提示!', "填写发送内容", QMessageBox.Yes) return False return True class SendQQMessages(object): def _sending(self, stype, nickname, msg): ''' 发送QQ消息 :param type: 发送类型 :param nickname: QQ昵称 :param msg: messages :return: bool ''' if stype == 1: return self.multi_S(nickname, msg) elif stype == 2: return self.simple_S(nickname, msg) def multi_S(self, nickname, msg): '''搜索QQ发送消息''' qqObjstring = win32gui.FindWindow(None, "QQ") # qq 窗体句柄 # 打开QQ好友nickname窗体 self.setTexts(nickname) win32gui.SendMessage(qqObjstring, 770) win32gui.SendMessage(qqObjstring, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) win32gui.SendMessage(qqObjstring, win32con.WM_KEYUP, win32con.VK_RETURN, 0) # 获取QQ好友窗口句柄 time.sleep(0.1) # sleep0.1秒,让给QQ弹出聊天窗口的时间 win = win32gui.FindWindow(None, nickname) self.setTexts(msg) # 设置msg T = win32gui.SendMessage(win, 770) E = win32gui.SendMessage(win, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) win32gui.SendMessage(win, win32con.WM_KEYUP, win32con.VK_RETURN, 0) if win and T == 0 and E == 0: return True else: return False def simple_S(self, nickname, msg): """ 直接发送qq消息 nickname:qq消息接收人 msg:需要发送的消息 """ # 将消息写到剪贴板 self.setTexts(msg) # 获取qq窗口句柄 win = win32gui.FindWindow(None, nickname) # 剪贴板消息到QQ窗体 # SendMessage消息的常量值,770 剪贴板值 http://blog.csdn.net/exiaoyin/article/details/51881481 T = win32gui.SendMessage(win, 770) # 模拟按下回车键 E = win32gui.SendMessage(win, win32con.WM_KEYDOWN, win32con.VK_RETURN, 0) win32gui.SendMessage(win, win32con.WM_KEYUP, win32con.VK_RETURN, 0) if win and T == 0 and E == 0: return True else: return False def setTexts(self, aString): """设置剪贴板""" win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.SetClipboardData(win32con.CF_UNICODETEXT, aString) win32clipboard.CloseClipboard() def EmptyClipboard(self): ''' 清空剪切板''' win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() if __name__ == "__main__": app = QApplication(sys.argv) main_widget = MainWidgetUI() main_widget.show() sys.exit(app.exec_())
截图: