• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
qt界面视频监控2二维码识别3语音播报

 

import sys
import cv2
import numpy as np
import pyttsx3
from pyzbar.pyzbar import decode
from PyQt5.QtWidgets import (
    QApplication, QLabel, QVBoxLayout, QWidget, QLineEdit, QPushButton, QListWidget, QHBoxLayout
)
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QTimer, QTime, QDate, QDateTime, Qt
from multiprocessing import Process, Manager, Lock
import time
import threading

# 初始化语音引擎
engine = pyttsx3.init()
engine.setProperty('voice', 'zh')
engine.setProperty('rate', 200)
engine.setProperty('voice', engine.getProperty('voices')[0].id)

# 摄像头进程
def camera_process(share_data, lock):
    cap = cv2.VideoCapture(0)
    while share_data['running']:
        ret, rgb_image = cap.read()
        if ret:
            with lock:
                share_data['frame'] = rgb_image  # 存储 RGB 图像
    cap.release()

# QR 码识别进程
def qr_code_process(share_data, lock):
    #previous_qr_data = ""  # 记录上一个二维码数据,避免重复播报
    while share_data['running']:
        with lock:
            frame = share_data.get('frame', None)
        if frame is not None:
            decoded_objects = decode(frame)
            for obj in decoded_objects:
                qr_data = obj.data.decode('utf-8')
                #if qr_data != previous_qr_data:  # 如果内容有变化才播报
                share_data['qr_data'] = qr_data
                text_to_speech(qr_data)
                #previous_qr_data = qr_data

# 语音播报
def text_to_speech(text):
    engine.say(text)
    engine.runAndWait()
    print('二维码内容播报完毕')

# NumPy 数组转 QImage
def rgbimg_to_qimage(array):
    array = cv2.cvtColor(array, cv2.COLOR_BGR2RGB)
    height, width, channel = array.shape
    bytes_per_line = 3 * width
    q_image = QImage(array.data, width, height, bytes_per_line, QImage.Format_RGB888)
    pixmap = QPixmap.fromImage(q_image)
    return pixmap

class MainWindow(QWidget):
    def __init__(self, share_data, lock):
        super().__init__()
        self.share_data = share_data
        self.lock = lock
        self.init_ui()
        self.start_timer()

        # 线程列表,用于管理每个预约任务的线程和事件
        self.reminder_threads = []
        self.reminder_events = []

    def init_ui(self):
        self.setWindowTitle('QR Code Scanner & Task Scheduler')
        self.setGeometry(200, 200, 700, 600)

        # Video display
        self.video_label = QLabel(self)
        self.qr_label = QLabel('QR Code Content: ', self)

        # Time display
        self.time_label = QLabel(self)
        self.time_label.setAlignment(Qt.AlignCenter)

        # Input fields
        self.time_label_input = QLabel('预约时间:', self)
        self.time_input = QLineEdit(self)
        self.time_input.setPlaceholderText("Enter time (yyyy-MM-dd HH:mm:ss)")
        self.time_input.setText(QDateTime.currentDateTime().toString('yyyy-MM-dd HH:mm:ss'))

        self.content_label_input = QLabel('提示内容:', self)
        self.content_input = QLineEdit(self)
        self.content_input.setPlaceholderText("Enter reminder content")

        # Buttons
        self.add_reminder_button = QPushButton('添加预约任务', self)
        self.add_reminder_button.clicked.connect(self.set_reminder)

        self.delete_button = QPushButton('删除预约任务', self)
        self.delete_button.clicked.connect(self.delete_task)

        # List box
        self.task_list = QListWidget(self)

        # Layout setup
        layout = QVBoxLayout()
        layout.addWidget(self.video_label)
        layout.addWidget(self.qr_label)
        layout.addWidget(self.time_label)
        
        layout.addWidget(self.time_label_input)
        layout.addWidget(self.time_input)

        layout.addWidget(self.content_label_input)
        layout.addWidget(self.content_input)

        layout.addWidget(self.add_reminder_button)
        layout.addWidget(self.task_list)
        layout.addWidget(self.delete_button)

        self.setLayout(layout)

    def start_timer(self):
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_frame)
        self.timer.start(50)

        # Time update timer
        self.time_update_timer = QTimer(self)
        self.time_update_timer.timeout.connect(self.update_time)
        self.time_update_timer.start(1000)

    def update_frame(self):
        with self.lock:
            frame = self.share_data.get('frame', None)
            if frame is not None:
                pixmap = rgbimg_to_qimage(frame)
                self.video_label.setPixmap(pixmap)
            qr_data = self.share_data.get('qr_data', '')
            if qr_data:
                self.qr_label.setText(f'QR Code Content: {qr_data}')

    def update_time(self):
        current_time = QDateTime.currentDateTime().toString('yyyy-MM-dd HH:mm:ss')
        self.time_label.setText(f'Current Time: {current_time}')

    def set_reminder(self):
        reminder_time = self.time_input.text()
        reminder_content = self.content_input.text()

        if reminder_time and reminder_content:
            reminder_item = f"At {reminder_time} - {reminder_content}"
            self.task_list.addItem(reminder_item)

            # Create an event to control the thread
            stop_event = threading.Event()
            # Create a new reminder thread
            reminder_thread = threading.Thread(target=self.trigger_reminder, args=(reminder_time, reminder_content, stop_event))
            reminder_thread.daemon = True
            self.reminder_threads.append(reminder_thread)
            self.reminder_events.append(stop_event)

            reminder_thread.start()

    def trigger_reminder(self, reminder_time, reminder_content, stop_event):
        while self.share_data['running'] and not stop_event.is_set():
            current_time = QDateTime.currentDateTime().toString('yyyy-MM-dd HH:mm:ss')
            if current_time == reminder_time:
                text_to_speech(reminder_content)
                print(f"Reminder triggered: {reminder_content}")
                break
            time.sleep(1)

    def delete_task(self):
        selected_item = self.task_list.currentRow()
        if selected_item >= 0:
            item_text = self.task_list.item(selected_item).text()

            # Remove from task list widget
            self.task_list.takeItem(selected_item)

            # Stop the corresponding reminder thread
            if 0 <= selected_item < len(self.reminder_threads):
                stop_event = self.reminder_events[selected_item]
                stop_event.set()  # Stop the thread by setting the event

                # Optionally join the thread to ensure it has finished
                self.reminder_threads[selected_item].join()

                # Remove the thread and event from the list
                self.reminder_threads[selected_item] = None
                self.reminder_events[selected_item] = None

    def closeEvent(self, event):
        """ 关闭窗口时修改 share_data['running'] = False """
        self.share_data['running'] = False
        event.accept()

if __name__ == '__main__':
    manager = Manager()
    share_data = manager.dict()
    lock = manager.Lock()

    # 初始化共享数据
    share_data['frame'] = None  # 图像数据
    share_data['qr_data'] = ''  # 二维码识别结果
    share_data['running'] = True  # 线程运行标志位

    # 启动摄像头进程
    p1 = Process(target=camera_process, args=(share_data, lock))
    p1.daemon = True
    p1.start()

    # 启动 QR 码识别进程
    p2 = Process(target=qr_code_process, args=(share_data, lock))
    p2.daemon = True
    p2.start()

    app = QApplication(sys.argv)
    window = MainWindow(share_data, lock)
    window.show()

    try:
        sys.exit(app.exec_())
    finally:
        share_data['running'] = False
        p1.join()
        p2.join()

  

 

posted on 2025-03-31 17:23  MKT-porter  阅读(15)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3