You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
7.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
群组详情窗口 - 显示群组信息和成员管理(优化版)
支持:查看成员、邀请好友、退出群组
"""
from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QListWidget, QListWidgetItem, QPushButton,
QTextEdit, QScrollArea, QMessageBox, QInputDialog, QFrame
)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QFont, QColor
from datetime import datetime
class GroupMemberItem(QListWidgetItem):
def __init__(self, member_info):
super().__init__()
self.member_info = member_info
self.refresh()
def refresh(self):
nick = self.member_info.get('nickname') or self.member_info.get('username', '')
user = self.member_info.get('username', '')
online = self.member_info.get('is_online', False)
dot = "" if online else ""
is_creator = self.member_info.get('is_creator', False)
crown = " 👑" if is_creator else ""
role = "群主" if is_creator else "成员"
self.setText(f"{nick} ({user}){dot}{crown}{role}")
self.setForeground(QColor('#10b981') if online else QColor('#94a3b8'))
self.setData(Qt.UserRole, self.member_info)
class GroupDetailWindow(QWidget):
get_group_members_requested = pyqtSignal(int)
leave_group_requested = pyqtSignal(int)
invite_member_requested = pyqtSignal(int, str)
def __init__(self, group_info, current_user_id, parent=None):
super().__init__(parent)
self.group_info = group_info
self.current_user_id = current_user_id
self.members = []
self._init_ui()
self.get_group_members_requested.emit(self.group_info['id'])
def _init_ui(self):
self.setWindowTitle(f"群组详情 - {self.group_info.get('name', '未知群组')}")
self.setFixedSize(480, 640)
self.setStyleSheet("QWidget { background: white; }")
layout = QVBoxLayout(self)
layout.setSpacing(16)
layout.setContentsMargins(20, 20, 20, 20)
# 群组信息卡片
self._build_group_info_card(layout)
# 成员列表
self._build_members_section(layout)
# 操作按钮
self._build_action_buttons(layout)
def _build_group_info_card(self, parent_layout):
card = QFrame()
card.setStyleSheet("""
QFrame {
background: qlineargradient(x1:0,y1:0,x2:1,y2:0,
stop:0 #6366f1, stop:0.5 #4f46e5, stop:1 #4338ca);
border-radius: 14px;
}
""")
card.setFixedHeight(130)
card_layout = QVBoxLayout(card)
card_layout.setContentsMargins(24, 18, 24, 18)
card_layout.setSpacing(8)
name_label = QLabel(self.group_info.get('name', '未知群组'))
name_label.setStyleSheet("font-size: 20px; font-weight: bold; color: white;")
card_layout.addWidget(name_label)
info_layout = QHBoxLayout()
id_label = QLabel(f"群组ID: {self.group_info.get('id', 'N/A')}")
id_label.setStyleSheet("font-size: 12px; color: rgba(255,255,255,0.85);")
info_layout.addWidget(id_label)
info_layout.addStretch()
self.member_count_label = QLabel("成员: 加载中…")
self.member_count_label.setStyleSheet("font-size: 12px; color: rgba(255,255,255,0.85);")
info_layout.addWidget(self.member_count_label)
card_layout.addLayout(info_layout)
if 'created_at' in self.group_info:
time_label = QLabel(f"创建于: {self.group_info['created_at']}")
time_label.setStyleSheet("font-size: 11px; color: rgba(255,255,255,0.7);")
card_layout.addWidget(time_label)
parent_layout.addWidget(card)
def _build_members_section(self, parent_layout):
title_layout = QHBoxLayout()
title_label = QLabel("群组成员")
title_label.setStyleSheet("font-size: 16px; font-weight: bold; color: #2c3e50;")
title_layout.addWidget(title_label)
title_layout.addStretch()
invite_btn = QPushButton(" 邀请好友")
invite_btn.setStyleSheet("""
QPushButton {
background: #8b5cf6; color: white; border: none;
border-radius: 8px; padding: 7px 14px;
font-size: 12px; font-weight: bold;
}
QPushButton:hover { background: #7c3aed; }
""")
invite_btn.clicked.connect(self._invite_member)
title_layout.addWidget(invite_btn)
parent_layout.addLayout(title_layout)
self.members_list = QListWidget()
self.members_list.setStyleSheet("""
QListWidget {
border: 1px solid #e0e0e0; border-radius: 10px;
background: #fafbfc; outline: none;
}
QListWidget::item {
padding: 10px 14px; border-bottom: 1px solid #f0f0f0;
font-size: 13px;
}
QListWidget::item:hover { background: #f0f2f5; }
QListWidget::item:selected { background: #eef2ff; color: #2c3e50; }
""")
self.members_list.setMaximumHeight(280)
parent_layout.addWidget(self.members_list)
def _build_action_buttons(self, parent_layout):
parent_layout.addStretch()
btn_layout = QHBoxLayout()
btn_layout.addStretch()
leave_btn = QPushButton("🚪 退出群组")
leave_btn.setStyleSheet("""
QPushButton {
background: #ef4444; color: white; border: none;
border-radius: 10px; padding: 10px 24px;
font-size: 13px; font-weight: bold;
}
QPushButton:hover { background: #dc2626; }
""")
leave_btn.clicked.connect(self._leave_group)
btn_layout.addWidget(leave_btn)
parent_layout.addLayout(btn_layout)
def _invite_member(self):
username, ok = QInputDialog.getText(
self, '邀请好友', '请输入要邀请的用户名:')
if ok and username.strip():
self.invite_member_requested.emit(
self.group_info['id'], username.strip())
def _leave_group(self):
reply = QMessageBox.question(
self, '退出群组',
f'确定要退出群组 "{self.group_info.get("name", "")}" 吗?\n退出后将无法接收群组消息。',
QMessageBox.Yes | QMessageBox.No)
if reply == QMessageBox.Yes:
self.leave_group_requested.emit(self.group_info['id'])
self.close()
def update_members(self, members):
self.members = members
self.members_list.clear()
self.member_count_label.setText(f"成员: {len(members)}")
creator_id = self.group_info.get('creator_id')
# 在线成员排前面
sorted_members = sorted(members, key=lambda m: (not m.get('is_online', False), m.get('username', '')))
for member in sorted_members:
member['is_creator'] = (member.get('id') == creator_id)
item = GroupMemberItem(member)
self.members_list.addItem(item)
def update_member_status(self, user_id, username, is_online):
for i in range(self.members_list.count()):
item = self.members_list.item(i)
if isinstance(item, GroupMemberItem):
if item.member_info.get('id') == user_id:
item.member_info['is_online'] = is_online
item.refresh()
break