2014-05-08 39 views
6

Jest to kontynuacja QMetaObject::invokeMethod doesn't find the method. Wywołanie metody bez parametrów działa. Ale rozszerzenie poprzedniego pytania na metody z parametrami przywraca mnie do błędu.QMetaObject :: invokeMethod nie znajduje metod o parametrach

patrz poniższy przykład skrypt w Pythonie:

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')) 

Wyjście z PySide 1.2.1 i Python 3.3 w systemie Windows 7 i Ubuntu 14.04, a także jest:

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

Oznacza to, że Wywołanie metody invokeMethod dla metod lokalnych zakończyło się po cichu. Tylko wywołanie metody Example: dup() dało oczekiwany wynik. Dwie próby uzyskania przykładu: beep (str) do pracy nie powiodło się, chociaż komunikaty o błędach podają sygnatury metod, które faktycznie powinny istnieć.

Podałem wcześniejszą wersję tego pytania na PySide mailing list, ale nie było odpowiedzi.

Pytanie: Jak dokonać QMetaObject::invokeMethod wywoływania metody lokalnej i klasy z parametrami w powiązaniach Python Qt (najlepiej w PySide)?

edytuj: Przy okazji: jeśli wiesz, co pod maską robią Signal:emit(...) lub QtCore.QTimer.singleShot(0, ...), to może ci w tym pomóc. W końcu wszystkie te różne podejścia mają bardzo podobne efekty.


Edit2:

Z 'QString' jako parametr wymienić komunikaty ostrzegawcze znikają ale Python nie jako całość naruszenia ochrony pamięci. Może to być błąd implementacyjny PySide. Reguła wydaje się, że trzeba podać typy Qt-C++ parametrów w invokeMethod i typy Pythona w slotach.

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

Czy jesteś pewien, że pierwszym argumentem dla 'QGenericArgument' powinien być argument * nazwa * zamiast jego * typ *? W rzeczywistości komunikat o błędzie mówi, że nie może znaleźć metody z * type * 'Example :: beep (text)', co jest prawdą, ponieważ typ powinien być 'Example :: beep (QString)'. – Bakuriu

+0

Jest to zwykły sposób na Python, aby nazwać nazwy parametrów, nie typy, podczas gdy myślałem, że tylko dla sygnałów Qt wskazuje się typy. Próbowałem z "str" ​​zamiast "text" bez zmian i "QString" zamiast "text" ze zmianą, że żadne ostrzeżenia nie są już drukowane, ale także nie oczekiwanymi tekstami. To nie rozwiązuje problemu. – Trilarion

+0

Sloty są wyszukiwane według ich * typu * w celu określenia właściwego przeciążenia. C++ nawet nie ma nazwanych parametrów, a PySide jest po prostu otoką do biblioteki Qt ... jak myślisz, jak PySide może obsługiwać nazwane parametry, jeśli jest to tylko opakowanie w coś, co ich nie obsługuje?Wiem, że to nie rozwiązuje problemu (i dlatego nie umieściłem go jako odpowiedzi). Przy okazji: na mojej maszynie wciąż pojawiają się błędy segmentacji. Wygląda na to, że metody zostały znalezione, ale coś jest nie tak podczas ich wywoływania. – Bakuriu

Odpowiedz

5

Dla każdego nadal zainteresowany tą:

Począwszy od wersji 1.2.4, PySide buggy jest w tym, że nie zawijać makra Q_ARG i Q_RETURN_ARG. Zamiast tego nierozsądnie owija klasy QGenericArgument i QGenericReturnArgument, które są wewnętrznymi klasami pomocniczymi i nie są przeznaczone bezpośrednio do instancji. W wyniku tego, wywoływanie automatów z argumentami niezmiennie powoduje błąd segmentacji.

Dla porównania, PyQt zawiera owinąć makra zamiast klas i nie cierpi z powodu tych samych problemów.

+0

> Od wersji 1.2.4, PySide jest błędny ..... wywoływanie automatów z argumentami niezmiennie powoduje błąd segmentacji. | Dobrze wiedzieć. Miałem inne sytuacje, w których zmiana z wersji 1.2.4 na 1.2.1 oznaczałaby różnicę między stabilną a zepsutą aplikacją. Czy są jakieś nowe (poprawkowe) wydania PySide w fazie rozwoju? 1.2.4 jest dość stary na najnowszą wersję, zważywszy na błędy, które zdaje się nosić. – timmwagener

+0

@timmwagener. Qt4 jest starszym kodem (oficjalna pomoc zakończyła się w zeszłym roku), więc wyobrażam sobie, że większość przyszłego rozwoju będzie koncentrować się na [PySide2] (http://wiki.qt.io/PySide2). – ekhumoro

+0

W pewnym sensie myślałem tak ..... thx – timmwagener