mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-22 10:52:18 +08:00
聊天统计
This commit is contained in:
parent
78eb89aa38
commit
3cf9d5b475
304
TEST.py
304
TEST.py
@ -1,45 +1,263 @@
|
||||
class img_viewed(QWidget):
|
||||
from pyecharts import options as opts
|
||||
from pyecharts.charts import WordCloud
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(img_viewed, self).__init__(parent)
|
||||
self.parent = parent
|
||||
self.width = 960
|
||||
self.height = 500
|
||||
words = [
|
||||
("花鸟市场", 1446),
|
||||
("汽车", 928),
|
||||
("视频", 906),
|
||||
("电视", 825),
|
||||
("Lover Boy 88", 514),
|
||||
("动漫", 486),
|
||||
("音乐", 53),
|
||||
("直播", 163),
|
||||
("广播电台", 86),
|
||||
("戏曲曲艺", 17),
|
||||
("演出票务", 6),
|
||||
("给陌生的你听", 1),
|
||||
("资讯", 1437),
|
||||
("商业财经", 422),
|
||||
("娱乐八卦", 353),
|
||||
("军事", 331),
|
||||
("科技资讯", 313),
|
||||
("社会时政", 307),
|
||||
("时尚", 43),
|
||||
("网络奇闻", 15),
|
||||
("旅游出行", 438),
|
||||
("景点类型", 957),
|
||||
("国内游", 927),
|
||||
("远途出行方式", 908),
|
||||
("酒店", 693),
|
||||
("关注景点", 611),
|
||||
("旅游网站偏好", 512),
|
||||
("出国游", 382),
|
||||
("交通票务", 312),
|
||||
("旅游方式", 187),
|
||||
("旅游主题", 163),
|
||||
("港澳台", 104),
|
||||
("本地周边游", 3),
|
||||
("小卖家", 1331),
|
||||
("全日制学校", 941),
|
||||
("基础教育科目", 585),
|
||||
("考试培训", 473),
|
||||
("语言学习", 358),
|
||||
("留学", 246),
|
||||
("K12课程培训", 207),
|
||||
("艺术培训", 194),
|
||||
("技能培训", 104),
|
||||
("IT培训", 87),
|
||||
("高等教育专业", 63),
|
||||
("家教", 48),
|
||||
("体育培训", 23),
|
||||
("职场培训", 5),
|
||||
("金融财经", 1328),
|
||||
("银行", 765),
|
||||
("股票", 452),
|
||||
("保险", 415),
|
||||
("贷款", 253),
|
||||
("基金", 211),
|
||||
("信用卡", 180),
|
||||
("外汇", 138),
|
||||
("P2P", 116),
|
||||
("贵金属", 98),
|
||||
("债券", 93),
|
||||
("网络理财", 92),
|
||||
("信托", 90),
|
||||
("征信", 76),
|
||||
("期货", 76),
|
||||
("公积金", 40),
|
||||
("银行理财", 36),
|
||||
("银行业务", 30),
|
||||
("典当", 7),
|
||||
("海外置业", 1),
|
||||
("汽车", 1309),
|
||||
("汽车档次", 965),
|
||||
("汽车品牌", 900),
|
||||
("汽车车型", 727),
|
||||
("购车阶段", 461),
|
||||
("二手车", 309),
|
||||
("汽车美容", 260),
|
||||
("新能源汽车", 173),
|
||||
("汽车维修", 155),
|
||||
("租车服务", 136),
|
||||
("车展", 121),
|
||||
("违章查询", 76),
|
||||
("汽车改装", 62),
|
||||
("汽车用品", 37),
|
||||
("路况查询", 32),
|
||||
("汽车保险", 28),
|
||||
("陪驾代驾", 4),
|
||||
("网络购物", 1275),
|
||||
("做我的猫", 1088),
|
||||
("只想要你知道", 907),
|
||||
("团购", 837),
|
||||
("比价", 201),
|
||||
("海淘", 195),
|
||||
("移动APP购物", 179),
|
||||
("支付方式", 119),
|
||||
("代购", 43),
|
||||
("体育健身", 1234),
|
||||
("体育赛事项目", 802),
|
||||
("运动项目", 405),
|
||||
("体育类赛事", 337),
|
||||
("健身项目", 199),
|
||||
("健身房健身", 78),
|
||||
("运动健身", 77),
|
||||
("家庭健身", 36),
|
||||
("健身器械", 29),
|
||||
("办公室健身", 3),
|
||||
("商务服务", 1201),
|
||||
("法律咨询", 508),
|
||||
("化工材料", 147),
|
||||
("广告服务", 125),
|
||||
("会计审计", 115),
|
||||
("人员招聘", 101),
|
||||
("印刷打印", 66),
|
||||
("知识产权", 32),
|
||||
("翻译", 22),
|
||||
("安全安保", 9),
|
||||
("公关服务", 8),
|
||||
("商旅服务", 2),
|
||||
("展会服务", 2),
|
||||
("特许经营", 1),
|
||||
("休闲爱好", 1169),
|
||||
("收藏", 412),
|
||||
("摄影", 393),
|
||||
("温泉", 230),
|
||||
("博彩彩票", 211),
|
||||
("美术", 207),
|
||||
("书法", 139),
|
||||
("DIY手工", 75),
|
||||
("舞蹈", 23),
|
||||
("钓鱼", 21),
|
||||
("棋牌桌游", 17),
|
||||
("KTV", 6),
|
||||
("密室", 5),
|
||||
("采摘", 4),
|
||||
("电玩", 1),
|
||||
("真人CS", 1),
|
||||
("轰趴", 1),
|
||||
("家电数码", 1111),
|
||||
("手机", 885),
|
||||
("电脑", 543),
|
||||
("大家电", 321),
|
||||
("家电关注品牌", 253),
|
||||
("网络设备", 162),
|
||||
("摄影器材", 149),
|
||||
("影音设备", 133),
|
||||
("办公数码设备", 113),
|
||||
("生活电器", 67),
|
||||
("厨房电器", 54),
|
||||
("智能设备", 45),
|
||||
("个人护理电器", 22),
|
||||
("服饰鞋包", 1047),
|
||||
("服装", 566),
|
||||
("饰品", 289),
|
||||
("鞋", 184),
|
||||
("箱包", 168),
|
||||
("奢侈品", 137),
|
||||
("母婴亲子", 1041),
|
||||
("孕婴保健", 505),
|
||||
("母婴社区", 299),
|
||||
("早教", 103),
|
||||
("奶粉辅食", 66),
|
||||
("童车童床", 41),
|
||||
("关注品牌", 271),
|
||||
("宝宝玩乐", 30),
|
||||
("母婴护理服务", 25),
|
||||
("纸尿裤湿巾", 16),
|
||||
("妈妈用品", 15),
|
||||
("宝宝起名", 12),
|
||||
("童装童鞋", 9),
|
||||
("胎教", 8),
|
||||
("宝宝安全", 1),
|
||||
("宝宝洗护用品", 1),
|
||||
("软件应用", 1018),
|
||||
("系统工具", 896),
|
||||
("理财购物", 440),
|
||||
("生活实用", 365),
|
||||
("影音图像", 256),
|
||||
("社交通讯", 214),
|
||||
("手机美化", 39),
|
||||
("办公学习", 28),
|
||||
("应用市场", 23),
|
||||
("母婴育儿", 14),
|
||||
("游戏", 946),
|
||||
("手机游戏", 565),
|
||||
("PC游戏", 353),
|
||||
("网页游戏", 254),
|
||||
("游戏机", 188),
|
||||
("模拟辅助", 166),
|
||||
("个护美容", 942),
|
||||
("护肤品", 177),
|
||||
("彩妆", 133),
|
||||
("美发", 80),
|
||||
("香水", 50),
|
||||
("个人护理", 46),
|
||||
("美甲", 26),
|
||||
("SPA美体", 21),
|
||||
("花鸟萌宠", 914),
|
||||
("绿植花卉", 311),
|
||||
("狗", 257),
|
||||
("其他宠物", 131),
|
||||
("水族", 125),
|
||||
("猫", 122),
|
||||
("动物", 81),
|
||||
("鸟", 67),
|
||||
("宠物用品", 41),
|
||||
("宠物服务", 26),
|
||||
("书籍阅读", 913),
|
||||
("网络小说", 483),
|
||||
("关注书籍", 128),
|
||||
("文学", 105),
|
||||
("报刊杂志", 77),
|
||||
("人文社科", 22),
|
||||
("建材家居", 907),
|
||||
("装修建材", 644),
|
||||
("家具", 273),
|
||||
("家居风格", 187),
|
||||
("家居家装关注品牌", 140),
|
||||
("家纺", 107),
|
||||
("厨具", 47),
|
||||
("灯具", 43),
|
||||
("家居饰品", 29),
|
||||
("家居日常用品", 10),
|
||||
("生活服务", 883),
|
||||
("物流配送", 536),
|
||||
("家政服务", 108),
|
||||
("摄影服务", 49),
|
||||
("搬家服务", 38),
|
||||
("物业维修", 37),
|
||||
("婚庆服务", 24),
|
||||
("二手回收", 24),
|
||||
("鲜花配送", 3),
|
||||
("维修服务", 3),
|
||||
("殡葬服务", 1),
|
||||
("求职创业", 874),
|
||||
("创业", 363),
|
||||
("目标职位", 162),
|
||||
("目标行业", 50),
|
||||
("兼职", 21),
|
||||
("期望年薪", 20),
|
||||
("实习", 16),
|
||||
("雇主类型", 10),
|
||||
("星座运势", 789),
|
||||
("星座", 316),
|
||||
("算命", 303),
|
||||
("解梦", 196),
|
||||
("风水", 93),
|
||||
("面相分析", 47),
|
||||
("手相", 32),
|
||||
("公益", 90),
|
||||
]
|
||||
|
||||
self.scroll_ares_images = QScrollArea(self)
|
||||
self.scroll_ares_images.setWidgetResizable(True)
|
||||
|
||||
self.scrollAreaWidgetContents = QWidget(self)
|
||||
self.scrollAreaWidgetContents.setObjectName('scrollAreaWidgetContends')
|
||||
|
||||
# 进行网络布局
|
||||
self.gridLayout = QGridLayout(self.scrollAreaWidgetContents)
|
||||
self.scroll_ares_images.setWidget(self.scrollAreaWidgetContents)
|
||||
|
||||
self.scroll_ares_images.setGeometry(20, 50, self.width, self.height)
|
||||
self.vertocal1 = QVBoxLayout()
|
||||
|
||||
# self.meanbar = QMenu(self)
|
||||
# self.meanbar.addMenu('&菜单')
|
||||
# self.openAct = self.meanbar.addAction('&Open',self.open)
|
||||
# self.startAct =self.meanbar.addAction('&start',self.start_img_viewer)
|
||||
self.open_file_pushbutton = QPushButton(self)
|
||||
self.open_file_pushbutton.setGeometry(150, 10, 100, 30)
|
||||
self.open_file_pushbutton.setObjectName('open_pushbutton')
|
||||
self.open_file_pushbutton.setText('打开文件夹...')
|
||||
self.open_file_pushbutton.clicked.connect(self.open)
|
||||
|
||||
self.start_file_pushbutton = QPushButton(self)
|
||||
self.start_file_pushbutton.setGeometry(750, 10, 100, 30)
|
||||
self.start_file_pushbutton.setObjectName('start_pushbutton')
|
||||
self.start_file_pushbutton.setText('开始')
|
||||
self.start_file_pushbutton.clicked.connect(self.start_img_viewer)
|
||||
|
||||
self.vertocal1.addWidget(self.scroll_ares_images)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
windo = img_viewed()
|
||||
windo.show()
|
||||
sys.exit(app.exec_())
|
||||
c = (
|
||||
WordCloud()
|
||||
.add(
|
||||
"",
|
||||
words,
|
||||
word_size_range=[20, 100],
|
||||
textstyle_opts=opts.TextStyleOpts(font_family="cursive"),
|
||||
)
|
||||
.set_global_opts(title_opts=opts.TitleOpts(title="WordCloud-自定义文字样式"))
|
||||
.render("wordcloud_custom_font_style.html")
|
||||
)
|
||||
|
@ -11,12 +11,51 @@ import hashlib
|
||||
import os
|
||||
import sqlite3
|
||||
import time
|
||||
|
||||
import requests
|
||||
|
||||
DB = None
|
||||
cursor = None
|
||||
|
||||
Type = {
|
||||
1: '文本内容',
|
||||
2: '位置信息',
|
||||
3: '图片及视频',
|
||||
34: '语音消息',
|
||||
42: '名片(公众号名片)',
|
||||
43: '图片及视频',
|
||||
47: '表情包',
|
||||
48: '定位信息',
|
||||
49: '小程序链接',
|
||||
10000: '撤回消息提醒',
|
||||
1048625: '照片',
|
||||
16777265: '链接',
|
||||
285212721: '文件',
|
||||
419430449: '微信转账',
|
||||
436207665: '微信红包',
|
||||
469762097: '微信红包',
|
||||
11879048186: '位置共享',
|
||||
}
|
||||
|
||||
Type0 = {
|
||||
'1': '文字',
|
||||
'3': '图片',
|
||||
'43': '视频',
|
||||
'-1879048185': '微信运动排行榜',
|
||||
'5': '',
|
||||
'47': '表情包',
|
||||
'268445456': '撤回的消息',
|
||||
'34': '语音',
|
||||
'419430449': '转账',
|
||||
'50': '语音电话',
|
||||
'100001': '领取红包',
|
||||
'10000': '消息已发出,但被对方拒收了。',
|
||||
'822083633': '回复消息',
|
||||
'922746929': '拍一拍',
|
||||
'1090519089': '发送文件',
|
||||
'318767153': '付款成功',
|
||||
'436207665': '发红包',
|
||||
}
|
||||
|
||||
|
||||
def mkdir(path):
|
||||
path = path.strip()
|
||||
@ -247,6 +286,93 @@ def get_contacts():
|
||||
return result
|
||||
|
||||
|
||||
def send_nums(username):
|
||||
sql = '''
|
||||
select count(*) from message
|
||||
where talker = ? and isSend=1
|
||||
'''
|
||||
cursor.execute(sql, [username])
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
|
||||
def recv_nums(username):
|
||||
sql = '''
|
||||
select count(*) from message
|
||||
where talker = ? and isSend=0
|
||||
'''
|
||||
cursor.execute(sql, [username])
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
|
||||
def get_text(username):
|
||||
sql = '''
|
||||
select content from message
|
||||
where talker=? and type=1
|
||||
'''
|
||||
cursor.execute(sql, [username])
|
||||
result = cursor.fetchall()
|
||||
return ''.join(map(lambda x: x[0], result))
|
||||
|
||||
|
||||
def msg_type_num(username):
|
||||
sql = '''
|
||||
select type,count(*) from message
|
||||
where talker = ?
|
||||
group by type
|
||||
'''
|
||||
cursor.execute(sql, [username])
|
||||
return cursor.fetchall()
|
||||
|
||||
|
||||
def get_msg_start_time(username):
|
||||
sql = '''
|
||||
select createTime from message
|
||||
where talker = ?
|
||||
order by msgId
|
||||
limit 1
|
||||
'''
|
||||
cursor.execute(sql, [username])
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
|
||||
def get_msg_end_time(username):
|
||||
sql = '''
|
||||
select createTime from message
|
||||
where talker = ?
|
||||
order by msgId desc
|
||||
limit 1
|
||||
'''
|
||||
cursor.execute(sql, [username])
|
||||
try:
|
||||
return cursor.fetchone()[0]
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_msg_by_days(username, year='2022'):
|
||||
sql = '''
|
||||
SELECT strftime('%Y-%m-%d',createTime/1000,'unixepoch','localtime') as days,count(msgId)
|
||||
from message
|
||||
where talker = ? and strftime('%Y',createTime/1000,'unixepoch','localtime') = ?
|
||||
group by days
|
||||
'''
|
||||
cursor.execute(sql, [username, year])
|
||||
result = cursor.fetchall()
|
||||
return result
|
||||
|
||||
|
||||
def get_msg_by_month(username, year='2022'):
|
||||
sql = '''
|
||||
SELECT strftime('%Y-%m',createTime/1000,'unixepoch','localtime') as days,count(msgId)
|
||||
from message
|
||||
where talker = ? and strftime('%Y',createTime/1000,'unixepoch','localtime') = ?
|
||||
group by days
|
||||
'''
|
||||
cursor.execute(sql, [username, year])
|
||||
result = cursor.fetchall()
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# rconversation = get_rconversation()
|
||||
# for i in rconversation:
|
||||
@ -256,3 +382,13 @@ if __name__ == '__main__':
|
||||
# print(contact)
|
||||
# [(177325,)] (73546,) (103770,)
|
||||
print(search_send_message(1, 1))
|
||||
print(send_nums('wxid_vqave8lcp49r22'))
|
||||
print(recv_nums('wxid_vqave8lcp49r22'))
|
||||
# for t in get_text('wxid_vqave8lcp49r22'):
|
||||
# print(t)
|
||||
print(msg_type_num('wxid_vqave8lcp49r22'))
|
||||
st = get_msg_start_time('wxid_vqave8lcp49r22')
|
||||
print(st, timestamp2str(st))
|
||||
st = get_msg_end_time('wxid_vqave8lcp49r22')
|
||||
print(st, timestamp2str(st))
|
||||
print(get_msg_by_month('wxid_8piw6sb4hvfm22', year='2022'))
|
||||
|
@ -2,16 +2,12 @@ import os
|
||||
import re
|
||||
import time
|
||||
import docx
|
||||
import pandas as pd
|
||||
import requests
|
||||
import xmltodict
|
||||
from docx import shared
|
||||
from docx.enum.table import WD_ALIGN_VERTICAL
|
||||
from docx.enum.text import WD_COLOR_INDEX, WD_PARAGRAPH_ALIGNMENT
|
||||
from docxcompose.composer import Composer
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from . import data
|
||||
|
||||
|
||||
|
@ -1,428 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@File : mainview.py
|
||||
@Author : Shuaikang Zhou
|
||||
@Time : 2022/12/13 15:07
|
||||
@IDE : Pycharm
|
||||
@Version : Python3.10
|
||||
@comment : ···
|
||||
"""
|
||||
import os.path
|
||||
import socket # 导入socket模块
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from .chatUi import *
|
||||
from ...DataBase import data
|
||||
|
||||
|
||||
class ChatController(QWidget, Ui_Dialog):
|
||||
exitSignal = pyqtSignal()
|
||||
|
||||
# username = ''
|
||||
|
||||
def __init__(self, Me, parent=None):
|
||||
super(ChatController, self).__init__(parent)
|
||||
self.ta_avatar = None
|
||||
self.setupUi(self)
|
||||
self.setWindowTitle('WeChat')
|
||||
self.setWindowIcon(QIcon('./app/data/icon.png'))
|
||||
self.initui()
|
||||
self.Me = Me
|
||||
self.Thread = ChatMsg(self.Me.username, None)
|
||||
self.Thread.isSend_signal.connect(self.showMsg)
|
||||
self.Thread.okSignal.connect(self.setScrollBarPos)
|
||||
self.contacts = {}
|
||||
self.last_btn = None
|
||||
self.chat_flag = True
|
||||
# self.showChat()
|
||||
self.message.verticalScrollBar().valueChanged.connect(self.textbrower_verticalScrollBar)
|
||||
self.show_flag = False
|
||||
self.ta_username = None
|
||||
self.last_pos = 0
|
||||
self.last_msg_time = 0 # 上次信息的时间
|
||||
self.last_talkerId = None
|
||||
self.now_talkerId = None
|
||||
self.showChat()
|
||||
|
||||
def initui(self):
|
||||
self.textEdit = myTextEdit(self.frame)
|
||||
self.textEdit.setGeometry(QtCore.QRect(9, 580, 821, 141))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(15)
|
||||
self.textEdit.setFont(font)
|
||||
self.textEdit.setTabStopWidth(80)
|
||||
self.textEdit.setCursorWidth(1)
|
||||
self.textEdit.setObjectName("textEdit")
|
||||
self.textEdit.sendSignal.connect(self.sendMsg)
|
||||
self.btn_sendMsg = QtWidgets.QPushButton(self.frame)
|
||||
self.btn_sendMsg.setGeometry(QtCore.QRect(680, 670, 121, 51))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("黑体")
|
||||
font.setPointSize(15)
|
||||
font.setBold(False)
|
||||
font.setWeight(50)
|
||||
self.btn_sendMsg.setFont(font)
|
||||
self.btn_sendMsg.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
|
||||
self.btn_sendMsg.setMouseTracking(False)
|
||||
self.btn_sendMsg.setAutoFillBackground(False)
|
||||
self.btn_sendMsg.setStyleSheet("QPushButton {background-color: #f0f0f0;\n"
|
||||
"padding: 10px;\n"
|
||||
"color:rgb(5,180,104);}\n"
|
||||
"QPushButton:hover{background-color: rgb(198,198,198)}\n"
|
||||
)
|
||||
self.btn_sendMsg.setIconSize(QtCore.QSize(40, 40))
|
||||
self.btn_sendMsg.setCheckable(False)
|
||||
self.btn_sendMsg.setAutoDefault(True)
|
||||
self.btn_sendMsg.setObjectName("btn_sendMsg")
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.btn_sendMsg.setText(_translate("Dialog", "发送"))
|
||||
self.btn_sendMsg.setToolTip('按Enter键发送,按Ctrl+Enter键换行')
|
||||
|
||||
def showChat(self):
|
||||
"""
|
||||
显示聊天界面
|
||||
:return:
|
||||
"""
|
||||
print('show')
|
||||
if self.show_flag:
|
||||
return
|
||||
self.show_flag = True
|
||||
rconversations = data.get_rconversation()
|
||||
max_hight = max(len(rconversations) * 80, 680)
|
||||
self.scrollAreaWidgetContents.setGeometry(
|
||||
QtCore.QRect(0, 0, 300, max_hight))
|
||||
for i in range(len(rconversations)):
|
||||
rconversation = rconversations[i]
|
||||
username = rconversation[1]
|
||||
# print('联系人:', i, rconversation)
|
||||
pushButton_2 = Contact(self.scrollAreaWidgetContents, i, rconversation)
|
||||
pushButton_2.setGeometry(QtCore.QRect(0, 80 * i, 300, 80))
|
||||
pushButton_2.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
pushButton_2.clicked.connect(pushButton_2.show_msg)
|
||||
pushButton_2.usernameSingal.connect(self.Chat)
|
||||
self.contacts[username] = pushButton_2
|
||||
|
||||
def Chat(self, talkerId):
|
||||
"""
|
||||
聊天界面 点击联系人头像时候显示聊天数据
|
||||
:param talkerId:
|
||||
:return:
|
||||
"""
|
||||
self.now_talkerId = talkerId
|
||||
# 把当前按钮设置为灰色
|
||||
if self.last_talkerId and self.last_talkerId != talkerId:
|
||||
print('对方账号:', self.last_talkerId)
|
||||
self.contacts[self.last_talkerId].setStyleSheet(
|
||||
"QPushButton {background-color: rgb(253,253,253);}"
|
||||
"QPushButton:hover{background-color: rgb(209,209,209);}\n"
|
||||
)
|
||||
self.last_talkerId = talkerId
|
||||
self.contacts[talkerId].setStyleSheet(
|
||||
"QPushButton {background-color: rgb(198,198,198);}"
|
||||
"QPushButton:hover{background-color: rgb(209,209,209);}\n"
|
||||
)
|
||||
conRemark = data.get_conRemark(talkerId)
|
||||
self.label_remark.setText(conRemark)
|
||||
self.message.clear()
|
||||
self.message.append(talkerId)
|
||||
self.ta_username = talkerId
|
||||
self.ta_avatar = data.get_avator(talkerId)
|
||||
self.textEdit.setFocus()
|
||||
self.Thread.ta_u = talkerId
|
||||
self.Thread.msg_id = 0
|
||||
self.Thread.start()
|
||||
# 创建新的线程用于显示聊天记录
|
||||
|
||||
def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
|
||||
print("closed")
|
||||
self.exitSignal.emit()
|
||||
self.close()
|
||||
|
||||
def textbrower_verticalScrollBar(self, pos):
|
||||
"""
|
||||
滚动条到0之后自动更新聊天记录
|
||||
:param pos:
|
||||
:return:
|
||||
"""
|
||||
# print(pos)
|
||||
if pos > 0:
|
||||
return
|
||||
self.last_pos = self.message.verticalScrollBar().maximum()
|
||||
self.Thread.start()
|
||||
|
||||
def setScrollBarPos(self, pos):
|
||||
"""
|
||||
将滚动条位置设置为上次看到的地方
|
||||
:param pos:
|
||||
:return:
|
||||
"""
|
||||
pos = self.message.verticalScrollBar().maximum() - self.last_pos
|
||||
|
||||
print(pos)
|
||||
self.message.verticalScrollBar().setValue(pos)
|
||||
|
||||
def sendMsg(self, msg):
|
||||
pass
|
||||
|
||||
def check_time(self, msg_time):
|
||||
"""
|
||||
判断两次聊天时间是否大于五分钟
|
||||
超过五分钟就显示时间
|
||||
:param msg_time:
|
||||
:return:
|
||||
"""
|
||||
dt = msg_time - self.last_msg_time
|
||||
# print(msg_time)
|
||||
if dt // 1000 >= 300:
|
||||
s_l = time.localtime(msg_time / 1000)
|
||||
ts = time.strftime("%Y-%m-%d %H:%M", s_l)
|
||||
html = '''
|
||||
<table align="center" style="vertical-align: middle;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>%s</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>''' % (ts)
|
||||
# print(html)
|
||||
self.last_msg_time = msg_time
|
||||
self.message.insertHtml(html)
|
||||
|
||||
def showMsg(self, message):
|
||||
"""
|
||||
显示聊天消息
|
||||
:param message:
|
||||
:return:
|
||||
"""
|
||||
msgId = message[0]
|
||||
# print(msgId, type(msgId))
|
||||
self.message.moveCursor(self.message.textCursor().Start)
|
||||
ta_username = message[7]
|
||||
msgType = str(message[2])
|
||||
isSend = message[4]
|
||||
content = message[8]
|
||||
imgPath = message[9]
|
||||
msg_time = message[6]
|
||||
self.check_time(msg_time)
|
||||
|
||||
if msgType == '1':
|
||||
self.show_text(isSend, content)
|
||||
elif msgType == '3':
|
||||
self.show_img(isSend,imgPath)
|
||||
# self.message.moveCursor(self.message.textCursor().End)
|
||||
|
||||
def show_img(self, isSend, imgPath):
|
||||
'THUMBNAIL_DIRPATH://th_29cd0f0ca87652943be9ede365aabeaa'
|
||||
imgPath = imgPath.split('th_')[1]
|
||||
imgPath = f'./app/data/image2/{imgPath[0:2]}/{imgPath[2:4]}/th_{imgPath}'
|
||||
html = '''
|
||||
<td style="border: 1px #000000 solid"><img align="right" src="%s"/></td>
|
||||
''' % imgPath
|
||||
style = 'vertical-align: top'
|
||||
if isSend:
|
||||
self.right(html,style=style)
|
||||
else:
|
||||
self.left(html,style=style)
|
||||
|
||||
def show_text(self, isSend, content):
|
||||
|
||||
if isSend:
|
||||
html = '''<td>%s :</td>''' % (content)
|
||||
self.right(html)
|
||||
else:
|
||||
html = '''<td>: %s</td>''' % (content)
|
||||
self.left(html)
|
||||
|
||||
def right(self, content,style='vertical-align: middle'):
|
||||
html = '''
|
||||
<div>
|
||||
<table align="right" style="%s;">
|
||||
<tbody>
|
||||
<tr>
|
||||
%s
|
||||
<td style="border: 1px #000000 solid"><img align="right" src="%s" width="45" height="45"/></td>
|
||||
<td width="15"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
''' % (style,content, self.Me.my_avatar)
|
||||
# print('总的HTML')
|
||||
# print(html)
|
||||
self.message.insertHtml(html)
|
||||
|
||||
def left(self, content,style = 'vertical-align: middle'):
|
||||
html = '''
|
||||
<div>
|
||||
<table align="left" style="%s;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="15"></td>
|
||||
<td style="border: 1px #000000 solid"><img align="right" src="%s" width="45" height="45"/></td>
|
||||
%s
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
''' % (style,self.ta_avatar, content)
|
||||
self.message.insertHtml(html)
|
||||
|
||||
def destroy_me(self):
|
||||
"""注销账户"""
|
||||
pass
|
||||
|
||||
|
||||
class Contact(QtWidgets.QPushButton):
|
||||
"""
|
||||
联系人类,继承自pyqt的按钮,里面封装了联系人头像等标签
|
||||
"""
|
||||
usernameSingal = pyqtSignal(str)
|
||||
|
||||
def __init__(self, Ui, id=None, contact=None):
|
||||
super(Contact, self).__init__(Ui)
|
||||
self.layoutWidget = QtWidgets.QWidget(Ui)
|
||||
self.layoutWidget.setObjectName("layoutWidget")
|
||||
self.gridLayout1 = QtWidgets.QGridLayout(self.layoutWidget)
|
||||
self.gridLayout1.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
|
||||
self.gridLayout1.setContentsMargins(10, 10, 10, 10)
|
||||
self.gridLayout1.setSpacing(10)
|
||||
self.gridLayout1.setObjectName("gridLayout1")
|
||||
self.label_time = QtWidgets.QLabel(self.layoutWidget)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.label_time.setFont(font)
|
||||
self.label_time.setLayoutDirection(QtCore.Qt.RightToLeft)
|
||||
self.label_time.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
|
||||
self.label_time.setObjectName("label_time")
|
||||
self.gridLayout1.addWidget(self.label_time, 0, 2, 1, 1)
|
||||
self.label_remark = QtWidgets.QLabel(self.layoutWidget)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Adobe 黑体 Std R")
|
||||
font.setPointSize(10)
|
||||
self.label_remark.setFont(font)
|
||||
self.label_remark.setObjectName("label_remark")
|
||||
self.gridLayout1.addWidget(self.label_remark, 0, 1, 1, 1)
|
||||
self.label_msg = QtWidgets.QLabel(self.layoutWidget)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.label_msg.setFont(font)
|
||||
self.label_msg.setObjectName("label_msg")
|
||||
self.gridLayout1.addWidget(self.label_msg, 1, 1, 1, 2)
|
||||
self.label_avatar = QtWidgets.QLabel(self.layoutWidget)
|
||||
self.label_avatar.setMinimumSize(QtCore.QSize(60, 60))
|
||||
self.label_avatar.setMaximumSize(QtCore.QSize(60, 60))
|
||||
self.label_avatar.setLayoutDirection(QtCore.Qt.RightToLeft)
|
||||
self.label_avatar.setAutoFillBackground(False)
|
||||
self.label_avatar.setStyleSheet("background-color: #ffffff;")
|
||||
self.label_avatar.setInputMethodHints(QtCore.Qt.ImhNone)
|
||||
self.label_avatar.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||
self.label_avatar.setFrameShadow(QtWidgets.QFrame.Plain)
|
||||
self.label_avatar.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
self.label_avatar.setObjectName("label_avatar")
|
||||
self.gridLayout1.addWidget(self.label_avatar, 0, 0, 2, 1)
|
||||
self.gridLayout1.setColumnStretch(0, 1)
|
||||
self.gridLayout1.setColumnStretch(1, 6)
|
||||
self.gridLayout1.setRowStretch(0, 5)
|
||||
self.gridLayout1.setRowStretch(1, 3)
|
||||
self.setLayout(self.gridLayout1)
|
||||
self.setStyleSheet(
|
||||
"QPushButton {background-color: rgb(253,253,253);}"
|
||||
"QPushButton:hover{background-color: rgb(209,209,209);}\n"
|
||||
)
|
||||
self.msgCount = contact[0]
|
||||
self.username = contact[1]
|
||||
self.conversationTime = contact[6]
|
||||
self.msgType = contact[7]
|
||||
self.digest = contact[8]
|
||||
hasTrunc = contact[10]
|
||||
attrflag = contact[11]
|
||||
if hasTrunc == 0:
|
||||
if attrflag == 0:
|
||||
self.digest = '[动画表情]'
|
||||
elif attrflag == 67108864:
|
||||
try:
|
||||
remark = data.get_conRemark(contact[9])
|
||||
msg = self.digest.split(':')[1].strip('\n').strip()
|
||||
self.digest = f'{remark}:{msg}'
|
||||
except Exception as e:
|
||||
# print(self.digest)
|
||||
# print(e)
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
self.show_info(id)
|
||||
|
||||
def show_info(self, id):
|
||||
avatar = data.get_avator(self.username)
|
||||
# print(avatar)
|
||||
remark = data.get_conRemark(self.username)
|
||||
time = datetime.datetime.now().strftime("%m-%d %H:%M")
|
||||
msg = '还没说话'
|
||||
pixmap = QPixmap(avatar).scaled(60, 60) # 按指定路径找到图片
|
||||
self.label_avatar.setPixmap(pixmap) # 在label上显示图片
|
||||
self.label_remark.setText(remark)
|
||||
self.label_msg.setText(self.digest)
|
||||
self.label_time.setText(data.timestamp2str(self.conversationTime)[2:])
|
||||
|
||||
def show_msg(self):
|
||||
self.usernameSingal.emit(self.username)
|
||||
|
||||
|
||||
class ChatMsg(QThread):
|
||||
"""
|
||||
发送信息线程
|
||||
"""
|
||||
isSend_signal = pyqtSignal(tuple)
|
||||
okSignal = pyqtSignal(int)
|
||||
|
||||
def __init__(self, my_u, ta_u, parent=None):
|
||||
super().__init__(parent)
|
||||
self.sec = 2 # 默认1000秒
|
||||
self.my_u = my_u
|
||||
self.ta_u = ta_u
|
||||
self.my_avatar = data.get_avator(my_u)
|
||||
self.msg_id = 0
|
||||
|
||||
def run(self):
|
||||
self.ta_avatar = data.get_avator(self.ta_u)
|
||||
messages = data.get_message(self.ta_u, self.msg_id)
|
||||
# messages.reverse()
|
||||
for message in messages:
|
||||
self.isSend_signal.emit(message)
|
||||
self.msg_id += 1
|
||||
self.okSignal.emit(1)
|
||||
|
||||
|
||||
class myTextEdit(QtWidgets.QTextEdit): # 继承 原本组件
|
||||
sendSignal = pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent):
|
||||
QtWidgets.QTextEdit.__init__(self, parent)
|
||||
self.parent = parent
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.setHtml(_translate("Dialog",
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'SimSun\'; font-size:15pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
QtWidgets.QTextEdit.keyPressEvent(self, event)
|
||||
if event.key() == Qt.Key_Return: # 如果是Enter 按钮
|
||||
modifiers = event.modifiers()
|
||||
if modifiers == Qt.ControlModifier:
|
||||
print('success press ctrl+enter key', self.toPlainText())
|
||||
self.append('\0')
|
||||
return
|
||||
self.sendSignal.emit(self.toPlainText())
|
||||
print('success press enter key', self.toPlainText())
|
||||
|
||||
# if modifiers == (Qt.ControlModifier) and event.key() == Qt.Key_Return:
|
||||
# self.sendSignal.emit(self.toPlainText())
|
||||
# print('success press enter key', self.toPlainText())
|
@ -7,10 +7,7 @@
|
||||
@Version : Python3.10
|
||||
@comment : ···
|
||||
"""
|
||||
import os.path
|
||||
import socket # 导入socket模块
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
|
||||
import xmltodict
|
||||
@ -61,8 +58,6 @@ class ChatController(QWidget, Ui_Dialog):
|
||||
self.message.setOpenExternalLinks(False)
|
||||
# self.message.anchorClicked(self.hyperlink())
|
||||
self.message.anchorClicked.connect(self.hyperlink)
|
||||
with open('./wechat.html', 'r', encoding='utf-8') as f:
|
||||
self.message.setHtml(f.read())
|
||||
self.textEdit = myTextEdit(self.frame)
|
||||
self.textEdit.setGeometry(QtCore.QRect(9, 580, 821, 141))
|
||||
font = QtGui.QFont()
|
||||
|
@ -7,22 +7,14 @@
|
||||
@Version : Python3.10
|
||||
@comment : ···
|
||||
"""
|
||||
import os.path
|
||||
import socket # 导入socket模块
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
|
||||
import xmltodict
|
||||
from PIL import Image
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from .contactUi import *
|
||||
from ...DataBase import data, output
|
||||
from ...ImageBox.ui import MainDemo
|
||||
from .userinfo import userinfoUi
|
||||
|
||||
from .analysis import analysis
|
||||
|
||||
class ContactController(QWidget, Ui_Dialog):
|
||||
exitSignal = pyqtSignal()
|
||||
@ -53,6 +45,7 @@ class ContactController(QWidget, Ui_Dialog):
|
||||
self.userinfo = userinfoUi.Ui_Frame()
|
||||
self.userinfo.setupUi(self.frame)
|
||||
self.userinfo.btn_outbut.clicked.connect(self.output)
|
||||
self.userinfo.btn_analysis.clicked.connect(self.analysis)
|
||||
|
||||
def initui(self):
|
||||
self.qurl = QUrl('baidu.com')
|
||||
@ -127,6 +120,10 @@ class ContactController(QWidget, Ui_Dialog):
|
||||
def output(self):
|
||||
self.outputThread = output.Output(self.Me, self.now_talkerId)
|
||||
self.outputThread.start()
|
||||
def analysis(self):
|
||||
self.analysisView = analysis.AnalysisController(self.now_talkerId)
|
||||
self.analysisView.show()
|
||||
pass
|
||||
|
||||
|
||||
class Contact(QtWidgets.QPushButton):
|
||||
|
@ -69,9 +69,18 @@ class Ui_Frame(object):
|
||||
self.lineEdit.setStyleSheet("background:transparent;border-width:0;border-style:outset")
|
||||
self.lineEdit.setObjectName("lineEdit")
|
||||
self.horizontalLayout.addWidget(self.lineEdit)
|
||||
self.btn_outbut = QtWidgets.QPushButton(Frame)
|
||||
self.btn_outbut.setGeometry(QtCore.QRect(310, 360, 111, 23))
|
||||
self.horizontalLayoutWidget_2 = QtWidgets.QWidget(Frame)
|
||||
self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(210, 350, 431, 80))
|
||||
self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
|
||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.btn_outbut = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
|
||||
self.btn_outbut.setObjectName("btn_outbut")
|
||||
self.horizontalLayout_2.addWidget(self.btn_outbut)
|
||||
self.btn_analysis = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
|
||||
self.btn_analysis.setObjectName("btn_analysis")
|
||||
self.horizontalLayout_2.addWidget(self.btn_analysis)
|
||||
|
||||
self.retranslateUi(Frame)
|
||||
QtCore.QMetaObject.connectSlotsByName(Frame)
|
||||
@ -85,3 +94,4 @@ class Ui_Frame(object):
|
||||
self.label.setText(_translate("Frame", "备注名"))
|
||||
self.lineEdit.setText(_translate("Frame", "曹雨萱"))
|
||||
self.btn_outbut.setText(_translate("Frame", "导出聊天记录"))
|
||||
self.btn_analysis.setText(_translate("Frame", "聊天统计"))
|
||||
|
@ -154,19 +154,32 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="btn_outbut">
|
||||
<widget class="QWidget" name="horizontalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>360</y>
|
||||
<width>111</width>
|
||||
<height>23</height>
|
||||
<x>210</x>
|
||||
<y>350</y>
|
||||
<width>431</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_outbut">
|
||||
<property name="text">
|
||||
<string>导出聊天记录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_analysis">
|
||||
<property name="text">
|
||||
<string>聊天统计</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -7,9 +7,6 @@
|
||||
@Version : Python3.10
|
||||
@comment : ···
|
||||
"""
|
||||
import socket # 导入socket模块
|
||||
import datetime
|
||||
import json
|
||||
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtCore import *
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"username": "root",
|
||||
"password": "123456",
|
||||
"database": "chat_2020303457"
|
||||
}
|
Loading…
Reference in New Issue
Block a user