2013-10-02 20 views
8

Làm cách nào để có thể kết nối phương thức/khe trăn với tín hiệu QML? Có vẻ như QtObject.connect() được sử dụng để làm việc trong PyQt4 nhưng nó là no longer available in PyQt5.PyQt5 Tín hiệu QML cho Khe cắm Python?

#Sample QML File (stack.qml) 

import QtQuick 2.0 

Rectangle { 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      // relay this to python 
     } 
    } 
} 

-

#Sample Python File 
from PyQt5.QtCore import QUrl 
from PyQt5.QtGui import QGuiApplication 
from PyQt5.QtQuick import QQuickView 

if __name__ == '__main__': 
    import os 
    import sys 

    app = QGuiApplication(sys.argv) 

    view = QQuickView() 
    view.setWidth(500) 
    view.setHeight(500) 
    view.setTitle('Hello PyQt') 
    view.setResizeMode(QQuickView.SizeRootObjectToView) 
    view.setSource(QUrl.fromLocalFile(os.path.join(os.path.dirname(__file__),'stack.qml'))) 

    def on_qml_mouse_clicked(mouse_event): 
     print 'mouse clicked' 

    view.show() 
    qml_rectangle = view.rootObject() 

    # this technique doesn't work ############################# 
    qml_rectangle.mousePressEvent.connect(on_qml_mouse_clicked) 

    sys.exit(app.exec_()) 

Một số ví dụ pyQT vượt qua một đối tượng vào bối cảnh QML qua "setContextProperty" và sau đó chuyển tiếp QML sự kiện để khe về đối tượng đó nhưng cách tiếp cận mà dường như vòng xoay. Có cách nào tốt hơn?

Trả lời

13

qml_rectangle.mousePressEvent không phải là tín hiệu, đó là trình xử lý sự kiện được gọi trên sự kiện chuột, vì vậy bạn không thể kết nối với nó. Bạn chỉ có thể thay thế nó bằng chức năng xử lý của bạn (qml_rectangle.mousePressEvent = on_qml_mouse_clicked), nhưng đó không phải là cách làm việc rất hiệu quả với Qt.

Cách tốt hơn là để xác định một tín hiệu trong tập tin QML của bạn và phát ra nó từ onClicked xử lý của hình chữ nhật:

import QtQuick 2.0 

Rectangle { 
    signal clicked() 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      parent.clicked() // emit the parent's signal 
     } 
    } 
} 

Sau đó, bạn chỉ có thể kết nối đến nó từ mã python của bạn:

... 
def on_qml_mouse_clicked(): 
    print('mouse clicked') 

qml_rectangle.clicked.connect(on_qml_mouse_clicked) 
... 
+0

hoạt động tuyệt vời! cảm ơn bạn! – berg

1

Tôi khuyên bạn nên phân loại phụ QQuickView và đặt thuộc tính trên ngữ cảnh gốc gốc, ví dụ: MainWindow. Bây giờ tất cả các bạn cần làm là thêm chức năng trong lớp đó với đồ trang trí như @pyqtSlot ('QString'), và sau đó bạn có thể thiết lập xử lý sự kiện với onClicked: MainWindow.FunctionName (Arguments_According_To_Decoration)

Sau đó, bạn main.py sẽ trông như thế

#!/bin/env python3 
# -*- coding: utf-8 -*- 
from PyQt5.QtCore import pyqtSlot 
from PyQt5.QtCore import QUrl 
from PyQt5.QtQuick import QQuickView 
from PyQt5.QtWidgets import QApplication 
import sys 

class MainWindow(QQuickView): 
    def __init__(self): 
     super().__init__() 
     self.setSource(QUrl('sample.qml')) 
     self.rootContext().setContextProperty("MainWindow", self) 
     self.show() 

    @pyqtSlot('QString') 
    def Print(self, value): 
     print(value) 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    w = MainWindow() 
    sys.exit(app.exec_()) 

sample.qml này như vậy

import QtQuick   2.0 
import QtQuick.Controls 2.2 

Rectangle { 
    width: 200; height: 200 

    Button { 
     text: "print Hello World" 
     onClicked: MainWindow.Print('hello world') 
    } 
} 

Bạn có thể tìm thêm thông tin trong các tài liệu

http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html

Các vấn đề liên quan