2011-03-01 3 views
10

Dlaczego nie Ctrl + C pracuje nad złamaniem programu w języku Python, który używa PyQt? Chcę go debugować i pobrać ślad stosu iz jakiegoś powodu jest to trudniejsze niż w C++!Ctrl-C nie działa z PyQt

+0

Z jakiego systemu operacyjnego korzystasz? –

+4

Powinieneś używać Google ;-) [Twój problem został wyjaśniony za pomocą rozwiązania] (http://www.mail-archive.com/[email protected]/msg13757.html) – user225312

+0

@A A - Nice!Myślałem, że jest to sytuacja Ctrl + C versus Ctrl + D. –

Odpowiedz

19

CTRL + C powoduje wysłanie sygnału do procesu. Python przechwytuje sygnał i ustawia zmienną globalną, np. CTRL_C_PRESSED = True. Następnie za każdym razem, gdy interpreter Pythona wykona nowy kod operacyjny, zobaczy on zestaw zmiennych i podniesie klawiaturę KeybordInterrupt o wartości .

Oznacza to, że CTRL + C działa tylko wtedy, gdy interpreter Pythona obraca się. Jeśli interpreter wykonuje moduł rozszerzenia zapisany w C, to wykonuje długo działającą operację, CTRL + C nie przerywa go, chyba że jawnie "współpracuje" z Pythonem. Np: time.sleep() jest teoretycznie operacją blokowania , ale implementacja tej funkcji "współpracuje" z interpreterem Python , aby działał CTRL + C.

To wszystko według projektu: CTRL + C oznacza , aby wykonać "czyste przerwanie"; dlatego zostaje zamieniony w wyjątek przez Python (tak, że czyści się wykonywane podczas rozwijania stosu), a jego obsługa przez moduły rozszerzeń jest sortowana z "opt-in". Jeśli chcesz całkowicie przerwać proces, nie dając mu szansy na oczyszczenie, możesz użyć CTRL +.

Kiedy Python wywołuje QApplication :: exec() (C++ funkcja), Qt nie znasz jak "współpracować" z Pythona na Ctrl + C, a to dlatego, że nie pracy. Nie wydaje mi się, żeby był dobry sposób, aby "sprawić, żeby działało"; możesz zobaczyć , jeśli możesz obsłużyć go przez globalny filtr zdarzeń . - Giovanni Bajo

Dodanie tego do głównego programu rozwiązało problem.

import signal 

signal.signal(signal.SIGINT, signal.SIG_DFL) 

Nie jestem pewien, co to ma wspólnego z wyjaśnieniem.

+1

Nie mam pojęcia, co to robi, ale działa idealnie! EDYCJA: Przeczytaj trochę o tym [tutaj] (https://docs.python.org/3/library/signal.html), więc mówi, że SIGINT (= Ctrl + C) powinien wykonać domyślną akcję (= zakończyć) . – z3ntu

2

zgadzam się z Neilem G, i dodać to:

Jeśli nie nie rozmowę QApplication.exec_(), aby uruchomić pętlę zdarzeń, a zamiast wykonywać swój program w interaktywnym Pythona skorupach (przy użyciu Pythona -i), a następnie pyqt będzie automatycznie przetwarzał zdarzenia, gdy tylko interaktywny monit czeka, a Ctrl-C powinien ponownie działać zgodnie z oczekiwaniami. Wynika to z tego, że pętla zdarzeń Qt będzie dzielić czas z interpreteriem Pythona, zamiast działać wyłącznie, umożliwiając interpreterowi złapanie tych przerwań.