2014-05-08 25 views
6

Đây là lần theo dõi QMetaObject::invokeMethod doesn't find the method. Gọi phương thức không có tham số hoạt động. Nhưng việc mở rộng câu hỏi trước đó cho các phương thức với các tham số mang lại cho tôi trở lại thất bại một lần nữa.QMetaObject :: invokeMethod không tìm thấy phương thức có tham số

Xem ví dụ kịch bản sau đây trong Python:

from PySide import QtCore 

class Example(QtCore.QObject): 
    def __init__(self): 
     super().__init__() 

    @QtCore.Slot() 
    def dup(self): 
     beep('dup-class') 

    @QtCore.Slot(str) 
    def beep(self, text): 
     print(text) 

@QtCore.Slot() 
def dup(self): 
    beep('dup-local') 

@QtCore.Slot(str) 
def beep(text): 
    print(text) 

if __name__ == '__main__': 
    QtCore.QMetaObject.invokeMethod(None, 'dup') 
    QtCore.QMetaObject.invokeMethod(None, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('text', 'beep-local')) 

    print('now some classy trials') 
    t = Example() 
    QtCore.QMetaObject.invokeMethod(t, 'dup') 
    QtCore.QMetaObject.invokeMethod(t, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('text', 'beep-class')) 
    QtCore.QMetaObject.invokeMethod(t, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('self', t), QtCore.QGenericArgument('text', 'beep-class-b')) 

Sản lượng với PySide 1.2.1 và Python 3.3 trên Windows 7 và Ubuntu 14.04 cũng là:

now some classy trials 
dup-class 
QMetaObject::invokeMethod: No such method Example::beep(text) 
QMetaObject::invokeMethod: No such method Example::beep(self,text) 

Điều này có nghĩa rằng invokeMethod gọi đến phương thức cục bộ không thành công. Chỉ có cuộc gọi đến Ví dụ: dup() đưa ra kết quả mong đợi. Hai thử nghiệm để có được Ví dụ: tiếng bíp (str) để làm việc thất bại, mặc dù các thông báo thất bại cho chữ ký phương thức mà thực sự nên tồn tại.

Tôi đã đặt một phiên bản cũ hơn của câu hỏi này trên PySide mailing list nhưng chưa được trả lời.

Câu hỏi: Cách thực hiện QMetaObject::invokeMethod gọi phương thức cục bộ và lớp với tham số trong ràng buộc Qt Python (tốt nhất là ở PySide)?

chỉnh sửa: Nhân tiện: nếu bạn biết điều gì Signal:emit(...) hoặc QtCore.QTimer.singleShot(0, ...) hãy làm theo mui xe, điều đó cũng có thể trợ giúp ở đây. Sau khi tất cả các phương pháp tiếp cận khác nhau có hiệu ứng rất giống nhau.


edit2:

Với 'QString' như tham số đặt tên cho thông điệp cảnh báo biến mất nhưng Python thất bại như một toàn thể với segfaults. Nó có thể là một lỗi thực hiện của PySide. Quy tắc có vẻ là người ta phải đưa ra các kiểu tham số Qt-C++ trong các tham số invokeMethod và các kiểu Python trong các Slots.

from PySide import QtCore 

class Example(QtCore.QObject): 
    def __init__(self): 
     super().__init__() 

    @QtCore.Slot(str) 
    def beep(self, text='default'): 
     print(text) 

if __name__ == '__main__': 
    app = QtCore.QCoreApplication([]) 

    e = Example() 
    QtCore.QMetaObject.invokeMethod(e, 'beep', QtCore.Qt.AutoConnection, QtCore.QGenericArgument('QString', 'beep')) 

    QtCore.QTimer.singleShot(1000, app.quit) 
    app.exec_() 
+3

Bạn có chắc rằng đối số đầu tiên cho 'QGenericArgument' phải là đối số * name * thay vì * loại * của nó không? Trong thực tế, thông báo lỗi nói rằng nó không thể tìm thấy một phương thức với * type * 'Ví dụ :: beep (văn bản)', điều này đúng vì kiểu phải là 'Example :: beep (QString)'. – Bakuriu

+0

Đó là cách Python thông thường để đặt tên cho các tên tham số không phải là các kiểu trong khi tôi chỉ nghĩ cho các tín hiệu Qt cho biết các loại. Tôi đã thử với 'str' thay vì 'text' mà không thay đổi và 'QString' thay vì 'text' với sự thay đổi mà không có cảnh báo nào được in nữa mà cũng không phải là văn bản mong đợi. Nó không giải quyết được vấn đề. – Trilarion

+0

Slots được tìm kiếm theo loại * của họ * để xác định tình trạng quá tải phải. C + + thậm chí không có tên tham số, và PySide chỉ là một wrapper để thư viện Qt ... làm thế nào để bạn nghĩ rằng PySide có thể xử lý các thông số được đặt tên nếu nó chỉ là một wrapper dưới cái gì đó không hỗ trợ họ?Tôi biết rằng nó không giải quyết được vấn đề (và đó là lý do tại sao tôi không đăng nó như là một câu trả lời). Nhân tiện: trên máy của tôi, tôi tiếp tục bị lỗi phân đoạn. Có vẻ như các phương pháp được tìm thấy nhưng có điều gì đó sai khi gọi chúng. – Bakuriu

Trả lời

5

Đối với bất cứ ai vẫn còn quan tâm đến việc này:

Tính đến phiên bản 1.2.4, PySide là lỗi ở chỗ nó không quấn Q_ARGQ_RETURN_ARG macro. Thay vào đó, nó không bao giờ kết thúc tốt đẹp các lớp học QGenericArgumentQGenericReturnArgument, là các lớp trợ giúp nội bộ và không có nghĩa là trực tiếp được instanciated. Như một kết quả của việc này, hãy gọi các khe với các đối số lúc nào cũng dẫn đến lỗi phân đoạn.

Khi so sánh, PyQt làm bọc các macro thay vì các lớp và không gặp phải vấn đề tương tự.

+0

> Kể từ phiên bản 1.2.4, PySide bị lỗi ..... gọi các khe với các đối số luôn thay đổi kết quả trong một lỗi phân đoạn. | Đó là điều tốt để biết. Tôi đã có các tình huống khác, khi hạ cấp từ 1.2.4 xuống 1.2.1 có nghĩa là sự khác biệt giữa một ứng dụng ổn định và bị hỏng. Có bất kỳ bản phát hành mới (bugfix) nào của PySide đang được phát triển không? 1.2.4 là khá cũ cho một bản phát hành mới nhất xem xét các lỗi nó dường như mang theo. – timmwagener

+0

@timmwagener. Qt4 là mã kế thừa bây giờ (hỗ trợ chính thức đã kết thúc năm ngoái), vì vậy tôi sẽ tưởng tượng rằng phần lớn các phát triển trong tương lai sẽ tập trung vào [PySide2] (http://wiki.qt.io/PySide2). – ekhumoro

+0

Tôi nghĩ như vậy ..... thx – timmwagener

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