Як правильно завершити QThread з програми GUI?

Я спробував використати self.terminate() у класі QThread, а також self.thread.terminate() у класі графічного інтерфейсу. Я також намагався вставити self.wait() в обох випадках. Однак існують два сценарії:

1) Потік взагалі не припиняється, і графічний інтерфейс зависає, очікуючи завершення потоку. Після закінчення потоку графічний інтерфейс розрядиться і все повернеться до нормального.

2) Потік дійсно закінчується, але в той же час вона заморожує всю програму.

Я також намагався використовувати self.thread.exit() . Немає радості

Для подальшого з'ясування, я намагаюся реалізувати кнопку відключення користувача в графічному інтерфейсі, яка припинить виконання потоку в будь-який момент часу.

Заздалегідь спасибі.

EDIT:

Ось метод методу run() :

def run(self):
    if self.create:
        print "calling create f"
        self.emit(SIGNAL("disableCreate(bool)"))
        self.create(self.password, self.email)
        self.stop()            
        self.emit(SIGNAL("finished(bool)"), self.completed)

def stop(self):
     #Tried the following, one by one (and all together too, I was desperate):
     self.terminate()
     self.quit()
     self.exit()
     self.stopped = True
     self.terminated = True
     #Neither works

І ось метод класу графічного інтерфейсу для переривання потоку:

def on_abort_clicked(self):
     self.thread = threadmodule.Thread()
     #Tried the following, also one by one and altogether:
     self.thread.exit()
     self.thread.wait()
     self.thread.quit()
     self.thread.terminate()
     #Again, none work
3
Спасибі, але це не допомагає вирішити проблему.
додано Автор Bo Milanovich, джерело
Ну, це, звичайно, не те, що я шукаю.
додано Автор Bo Milanovich, джерело
Примітка: self.terminate === (self.terminated = true), нічого більше. Для 99% всіх реалізацій.
додано Автор TheHorse, джерело
Існує лише один спосіб безпечно завершити роботу потоку - нехай він закінчує всі завдання. Щоб виконати це, перед виконанням важких завдань потрібно перевірити thread.terminated.
додано Автор TheHorse, джерело

1 Відповіді

З документації Qt для QThread :: закінчення:

Попередження : ця функція небезпечна, і її використання не рекомендується. The   нитка може бути припинена в будь-якій точці її шляху коду. Нитки можуть бути   припинено під час модифікації даних. Немає ніяких шансів для нитки   очистити після себе, розблокувати будь-які утримувані мутези і т. д. Коротко кажучи, скористайтеся   цю функцію, лише якщо це абсолютно необхідно.

Напевно, набагато краще буде переосмислити свою стратегію виконання рішень, щоб ви могли, наприклад, використовуйте QThread :: quit (), щоб сигналізувати потоку чистому завершенню, а не намагатися припинити дію таким способом. Фактично, виклик thread.exit() з потоку повинно робити це залежно від того, як ви реалізували run (). Якщо ви хочете поділитися кодом для методу запуску потоку, який може натякнути, чому він не працює.

5
додано
Привіт спасибі Я додав код у публікацію.
додано Автор Bo Milanovich, джерело
Я теж спробував це. Деяка справа десь працювало (графічний інтерфейс не застиг, але теж не закінчився). Однак найдивніша річ просто відбулася. Я видалив весь код def stop (self) у потоці та код def on_abort_clicked (self) у графічному інтерфейсі користувача та переписав його. Я просто поставив self.terminate() у функцію stop() потоку і зробив self.thread.stop() у класі графічного інтерфейсу. Це працює як чарівність. AFAIK, це перше, що я намагався, і він раніше не працював. Я, мабуть, пропустив щось.
додано Автор Bo Milanovich, джерело
Хмм І я припускаю, що метод self.create() - це трудомісткий метод у потоці? Як правило, що ви хочете робити в ньому, є щось на кшталт , а не self.terminated() {робити повільні частини операцій ..} . На жаль, я не знаю Python добре, але, схоже, є підручник з потоками тут , який може допомогти
додано Автор docsteer, джерело
ІТ КПІ - Python
ІТ КПІ - Python
625 учасників

Канал обговорень про всякі штуки зі світу пайтону. Прохання: 0. мати повагу одне до одного; 1. не матюкатися в сторону людей; 2. не захламляти тред повідомленнями по одному слову;