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_()
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
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
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