You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5如何实现赛事结果QWidget窗口在双显示器上同时显示

实现双屏同步显示赛事成绩窗口的解决方案

需求梳理

  • 开发场景:赛事成绩展示应用,通过串口或TCP端口读取解码器捕获的骑手冲线时间,解码后展示个人用时与总排名,骑手冲线间隔不超过30秒
  • 展示要求:成绩通过QMainWindow内嵌的QTableView展示,需要同时在主控端显示器和外接展示屏上完全同步显示,主控端无法直接查看外接屏幕内容

实现思路

原代码仅实例化了一个窗口放在外接屏,要实现双屏同步无需重复编写界面逻辑,只要共用同一份数据源即可保证两边内容完全同步,无需额外做镜像渲染,性能足够满足30秒间隔的刷新需求。

修改后可直接运行的代码

from PyQt5 import QtCore
from PyQt5.QtWidgets import QGridLayout,QWidget, QApplication, QPushButton,QTableView,QMainWindow
from PyQt5.QtCore import QAbstractTableModel, Qt
import sys

# 全局共用的成绩数据模型,所有窗口绑定同一个模型保证数据同步刷新
class ResultTableModel(QAbstractTableModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.header = ["排名", "骑手姓名", "用时"]
        self.data_list = []
    
    def rowCount(self, parent):
        return len(self.data_list)
    
    def columnCount(self, parent):
        return len(self.header)
    
    def data(self, index, role):
        if not index.isValid():
            return None
        if role == Qt.DisplayRole:
            return self.data_list[index.row()][index.column()]
        return None
    
    def headerData(self, section, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[section]
        return None
    
    # 新增成绩方法,调用后所有绑定该模型的窗口会自动同步更新
    def add_result(self, rank, name, time):
        self.beginInsertRows(QtCore.QModelIndex(), len(self.data_list), len(self.data_list))
        self.data_list.append([rank, name, time])
        self.endInsertRows()

class ShowResultsWindow(QMainWindow):
    def __init__(self, display_monitor, model, is_fullscreen=False, parent=None):
        super().__init__(parent)
        self.resize(600,600)
        # 移动窗口到指定显示器
        monitor = QApplication.desktop().screenGeometry(display_monitor)
        self.move(monitor.left(), monitor.top())
        if is_fullscreen:
            self.showFullScreen() 
        # 绑定共用的成绩模型
        self.result_model = model
        self.create_GUI()
             
    def create_GUI(self):
        central_widget=QWidget()
        layout=QGridLayout(central_widget)
        self.setCentralWidget(central_widget)
        # 表格视图绑定共用模型
        result_table = QTableView()
        result_table.setModel(self.result_model)
        # 可根据需求调整表格样式、列宽等
        result_table.horizontalHeader().setStretchLastSection(True)
        layout.addWidget(result_table, 0, 0, 1, 2)
        # 测试按钮,模拟新增骑手成绩,实际使用替换为串口/TCP读取逻辑
        pb_add = QPushButton('模拟新增冲线成绩')
        pb_add.clicked.connect(self.add_test_result)
        layout.addWidget(pb_add,1,0)
             
    def add_test_result(self):
        new_rank = len(self.result_model.data_list) + 1
        self.result_model.add_result(new_rank, f"骑手{new_rank}", f"{120 + new_rank * 2.5:.2f}秒")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    screen_count = len(app.screens())
    print('检测到的显示器数量: ', screen_count)
    # 实例化全局唯一的成绩数据模型
    global_result_model = ResultTableModel()
    # 主控端窗口,放在0号显示器,默认不用全屏方便操作
    control_window = ShowResultsWindow(display_monitor=0, model=global_result_model, is_fullscreen=False)
    control_window.show()
    # 存在第二块显示器时启动外接展示窗口,放在1号显示器,全屏展示
    if screen_count >=2:
        display_window = ShowResultsWindow(display_monitor=1, model=global_result_model, is_fullscreen=True)
        display_window.show()
    sys.exit(app.exec_())

方案优势

  1. 两边内容完全同步,共用同一份数据源,只要数据更新两边会同时刷新,无显示延迟
  2. 界面逻辑只需要维护一份,后续修改展示样式、表格规则只需要改一次代码
  3. 外接屏默认全屏展示,主控端窗口可自由调整大小,适配操作和展示两种场景的需求

内容的提问来源于stack exchange,提问作者RBenet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:30:04