import { ref, onMounted } from 'vue' declare global { interface Window { QWebChannel?: typeof QWebChannel qt?: { webChannelTransport?: any } } const QWebChannel: { new(transport: any, ready: (channel: any) => void): void } } interface PythonEvent { type: string data: any } const pyjs = ref(null) const isReady = ref(false) // Хранилище обработчиков событий const pythonEventHandlers = new Map void>>() function receiveFromPython(eventType: string, data: any) { console.warn("🟢 Event from Python:", eventType, data) const handlers = pythonEventHandlers.get(eventType) || [] handlers.forEach(handler => handler(data)) } export function usePythonBridge() { function setupQWebChannel() { if (window.QWebChannel && window.qt && window.qt.webChannelTransport) { new window.QWebChannel(window.qt.webChannelTransport, function (channel) { isReady.value = true pyjs.value = channel.objects.pyjs // Получаем доступ к эмиттеру событий const eventEmitter = channel.objects.pyjs_events // Подписываемся на событие один раз if (eventEmitter && eventEmitter.onEvent) { eventEmitter.onEvent.connect(receiveFromPython) } }) } else { console.error('Qt WebChannel недоступен') } } async function sendCommandToPython( command: string, data: Record = {} ): Promise { return new Promise((resolve, reject) => { if (!isReady.value) { reject(new Error('Мост еще не готов')) return } if (!pyjs.value || !pyjs.value.callFromJS) { reject(new Error('Python недоступен')) return } pyjs.value.callFromJS(command, JSON.stringify(data), (result: string) => { try { resolve(JSON.parse(result)) } catch (e) { reject(e) } }) }) } // Регистрация обработчика событий по типу function onPythonEvent(eventType: string, handler: (data: any) => void) { if (!pythonEventHandlers.has(eventType)) { pythonEventHandlers.set(eventType, []) } pythonEventHandlers.get(eventType)?.push(handler) } // Отписка от события function offPythonEvent(eventType: string, handler: (data: any) => void) { const handlers = pythonEventHandlers.get(eventType) if (handlers) { const index = handlers.indexOf(handler) if (index > -1) { handlers.splice(index, 1) } } } const checkBridge = () => { if (window.QWebChannel && window.qt?.webChannelTransport) { setupQWebChannel() } if (pyjs.value) { console.warn('✅ pyjs готов') } else { setTimeout(checkBridge, 500) } } onMounted(() => { checkBridge() }) return { isReady, sendCommandToPython, onPythonEvent, offPythonEvent, } }