Files
LTE_manager/incoming_call.py

233 lines
8.3 KiB
Python

import sys
from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QSize
from PyQt5.QtGui import QPixmap, QIcon
import winsound
import threading
import time
import os
class IncomingCallDialog(QDialog):
# 定义信号
answer_signal = pyqtSignal()
reject_signal = pyqtSignal()
def __init__(self, phone_number, caller_name=None, parent=None):
super().__init__(parent)
self.phone_number = phone_number
self.caller_name = caller_name or "未知联系人"
self.display_name = caller_name or phone_number
self.init_ui()
self.setAttribute(Qt.WA_DeleteOnClose, True)
# 初始化时间计时器
self.start_time = time.time()
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_time)
self.timer.start(500) # 每500毫秒更新一次
# 15秒后自动关闭对话框(如果未接听),模拟未接来电
self.auto_close_timer = QTimer(self)
self.auto_close_timer.timeout.connect(self.auto_reject)
self.auto_close_timer.setSingleShot(True)
self.auto_close_timer.start(15000) # 15秒后自动关闭
# 设置窗口标志
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
# 记录对话框状态
self.answer_clicked = False
self.reject_clicked = False
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 来电对话框已创建: {self.display_name}")
def init_ui(self):
self.setWindowTitle("来电")
self.setStyleSheet("""
QDialog {
background-color: #F5F5F5;
border: 1px solid #CCCCCC;
border-radius: 10px;
}
QLabel {
color: #333333;
font-size: 14px;
}
QPushButton {
border-radius: 20px;
font-size: 14px;
font-weight: bold;
padding: 10px;
}
QPushButton#answer {
background-color: #4CAF50;
color: white;
}
QPushButton#answer:hover {
background-color: #45a049;
}
QPushButton#reject {
background-color: #f44336;
color: white;
}
QPushButton#reject:hover {
background-color: #d32f2f;
}
""")
# 主布局
layout = QVBoxLayout(self)
# 联系人头像
avatar_label = QLabel()
avatar_path = os.path.join("assets", "user.png") # 默认头像
if os.path.exists(avatar_path):
pixmap = QPixmap(avatar_path)
avatar_label.setPixmap(pixmap.scaled(80, 80, Qt.KeepAspectRatio, Qt.SmoothTransformation))
avatar_label.setAlignment(Qt.AlignCenter)
layout.addWidget(avatar_label)
# 显示标题(来电)
title_label = QLabel("来电")
title_label.setAlignment(Qt.AlignCenter)
title_label.setStyleSheet("font-size: 18px; font-weight: bold; color: #333333;")
layout.addWidget(title_label)
# 显示来电号码或联系人名称
self.name_label = QLabel(self.display_name)
self.name_label.setAlignment(Qt.AlignCenter)
self.name_label.setStyleSheet("font-size: 16px; font-weight: bold; margin-bottom: 10px;")
layout.addWidget(self.name_label)
# 显示号码(如果有联系人名称)
if self.caller_name:
number_label = QLabel(self.phone_number)
number_label.setAlignment(Qt.AlignCenter)
number_label.setStyleSheet("font-size: 12px; color: #555555;")
layout.addWidget(number_label)
# 显示振铃时间
self.time_label = QLabel("正在响铃...")
self.time_label.setAlignment(Qt.AlignCenter)
self.time_label.setStyleSheet("font-size: 12px; color: #555555; margin-top: 5px;")
layout.addWidget(self.time_label)
# 按钮布局
button_layout = QHBoxLayout()
# 接听按钮
self.answer_button = QPushButton()
self.answer_button.setIcon(QIcon(os.path.join("assets", "answer.png")))
self.answer_button.setIconSize(QSize(30, 30))
self.answer_button.setObjectName("answer")
self.answer_button.setFixedSize(60, 60)
self.answer_button.clicked.connect(self.accept_call)
button_layout.addWidget(self.answer_button)
# 拒绝按钮
self.reject_button = QPushButton()
self.reject_button.setIcon(QIcon(os.path.join("assets", "hangup.png")))
self.reject_button.setIconSize(QSize(30, 30))
self.reject_button.setObjectName("reject")
self.reject_button.setFixedSize(60, 60)
self.reject_button.clicked.connect(self.reject_call)
button_layout.addWidget(self.reject_button)
layout.addLayout(button_layout)
self.setLayout(layout)
self.setFixedSize(300, 350)
# 将对话框移到屏幕中央
screen_geometry = self.screen().availableGeometry()
x = (screen_geometry.width() - self.width()) // 2
y = (screen_geometry.height() - self.height()) // 2
self.move(x, y)
def update_time(self):
"""更新来电持续时间"""
elapsed = int(time.time() - self.start_time)
minutes, seconds = divmod(elapsed, 60)
self.time_label.setText(f"已振铃 {minutes:02d}:{seconds:02d}")
def accept_call(self):
"""处理接听按钮点击"""
if self.answer_clicked: # 防止重复点击
return
self.answer_clicked = True
self.auto_close_timer.stop() # 停止自动拒绝计时器
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 用户点击接听按钮: {self.display_name}")
# 发送接听信号
self.answer_signal.emit()
self.timer.stop()
self.accept() # 关闭对话框
def reject_call(self):
"""处理拒绝按钮点击"""
if self.reject_clicked: # 防止重复点击
return
self.reject_clicked = True
self.auto_close_timer.stop() # 停止自动拒绝计时器
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 用户点击拒绝按钮: {self.display_name}")
# 发送拒绝信号
self.reject_signal.emit()
self.timer.stop()
self.reject() # 关闭对话框
def auto_reject(self):
"""自动拒绝来电(未接听超时)"""
if not self.answer_clicked and not self.reject_clicked:
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 来电自动拒绝(超时): {self.display_name}")
self.reject_clicked = True
# 发送拒绝信号
self.reject_signal.emit()
self.timer.stop()
self.reject() # 关闭对话框
def closeEvent(self, event):
"""处理对话框关闭事件"""
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 来电对话框关闭: {self.display_name}")
self.timer.stop()
self.auto_close_timer.stop()
# 如果是通过"X"按钮关闭的,没有点击任何按钮,则视为拒绝
if not self.answer_clicked and not self.reject_clicked:
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - 窗口被直接关闭,视为拒绝")
self.reject_signal.emit()
super().closeEvent(event)
def show_incoming_call(caller_number):
"""显示来电对话框并返回用户选择(True表示接听,False表示拒绝)"""
app = QApplication.instance()
if not app:
app = QApplication(sys.argv)
# 确保没有遗留的来电对话框
for widget in QApplication.topLevelWidgets():
if isinstance(widget, IncomingCallDialog):
print(f"发现正在显示的来电对话框,关闭它: {widget.display_name}")
widget.close()
widget.deleteLater()
# 创建并显示新的来电对话框
dialog = IncomingCallDialog(caller_number)
result = dialog.exec_()
# 记录用户选择
user_choice = dialog.answer_clicked
# 确保对话框被释放
dialog.deleteLater()
return user_choice
if __name__ == "__main__":
# 测试来电对话框
result = show_incoming_call("+8613800138000")
print(f"用户选择了{'接听' if result else '拒绝'}来电")