Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/25: Рейтинг темы: голосов - 25, средняя оценка - 4.56
0 / 0 / 1
Регистрация: 12.01.2021
Сообщений: 27
PyQt5

Остановка потока QThread

02.04.2021, 09:48. Показов 6293. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
у меня есть окно QWidget которая запускает Qthread для вывода поток с камеры. Как сделать чтобы при закрытии окна QThread останавливалась
основной класс
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class CameraScreen(QWidget):
    def __init__(self, parent):
        super(CameraScreen, self).__init__()
 
        self.initUI()
 
        self.parent = parent
 
        self.stream = cameraStream.CameraStream(self)
        self.stream.changePixmap.connect(self.showStream)
        self.stream.start()
 
    def initUI(self):
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 15)
 
        self.image_lbl = QLabel("CAMERA STREAM")
        self.image_lbl.setFixedSize(900, 650)
 
        self.screen_btn = QPushButton("Сделать снимок")
        self.screen_btn.clicked.connect(self.ss)
 
        main_layout.addWidget(self.image_lbl, 4, alignment=Qt.AlignHCenter)
 
        main_layout.addWidget(self.screen_btn, 1, alignment=Qt.AlignHCenter)
 
        self.setGeometry(600, 300, 640, 560)
        self.setWindowTitle("PhotkaemRoju")
        self.setLayout(main_layout)
        self.show()
 
    def showStream(self, img):
        self.image_lbl.setPixmap(QPixmap(img).scaled(self.image_lbl.size()))
класс для чтения потока с камеры
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class CameraStream(QThread):
    changePixmap = pyqtSignal(QImage)
 
    def __init__(self, parent, *args, **kwargs):
        super().__init__()
 
        self.parent = parent
 
        self.flag = True
 
    def run(self):
        cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
 
        while True:
            ret, source_img = cap.read()
 
            if ret:
                #img = cv2.cvtColor(source_img, cv2.COLOR_BGR2RGB)
                #height, width, channel = img.shape
                #step = channel * width
                #qImg = QImage(img.data, width, height, step, QImage.Format_RGB888)
                crope_img = source_img[100:500, 300:900]
                img = cv2.cvtColor(crope_img, cv2.COLOR_BGR2RGB)
                height, width, channel = img.shape
                step = channel * width
                qImg = QImage(img.data, width, height, step, QImage.Format_RGB888)
                self.changePixmap.emit(qImg)
 
            cv2.waitKey(1)
Добавлено через 26 минут
пока что переделал след. образом и вроде работает
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class CameraScreen(QWidget):
    def __init__(self, parent):
        super(CameraScreen, self).__init__()
 
        self.initUI()
 
        self.parent = parent
        self.thread = None
        self.startStream()
 
        #self.stream = cameraStream.CameraStream(self)
        #self.stream.changePixmap.connect(self.showStream)
        #self.stream.start()
 
    def initUI(self):
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 15)
 
        self.image_lbl = QLabel("CAMERA STREAM")
        self.image_lbl.setFixedSize(900, 650)
 
        self.screen_btn = QPushButton("Сделать снимок")
        self.screen_btn.clicked.connect(self.ss)
        self.screen_btn.setFont(QFont("Times", 16))
        self.screen_btn.setFixedSize(200, 60)
        self.screen_btn.setStyleSheet("background-color: #6298C8")
 
        main_layout.addWidget(self.image_lbl, 4, alignment=Qt.AlignHCenter)
 
        main_layout.addWidget(self.screen_btn, 1, alignment=Qt.AlignHCenter)
 
        self.setGeometry(600, 300, 640, 560)
        self.setWindowTitle("PhotkaemRoju")
        self.setWindowIcon(QIcon("icons//cameratitle.png"))
        self.setLayout(main_layout)
        self.setStyleSheet("background-color: #C3FC94")
        self.move(QApplication.desktop().screen().rect().center() - self.rect().center())
        self.show()
 
    def startStream(self):
        if self.thread is None:
            self.thread = cameraStream.CameraStream(self)
            self.thread.changePixmap.connect(self.showStream)
            self.thread.start()
        else:
            self.thread.terminate()
            self.thread = None
 
    def showStream(self, img):
        self.image_lbl.setPixmap(QPixmap(img).scaled(self.image_lbl.size()))
 
    def ss(self):
        self.startStream()
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.04.2021, 09:48
Ответы с готовыми решениями:

Приостановка и возобновление потока QThread из др. потока
Всем доброго дня, недавно столкнулся с такой проблемой, что не могу найти информацию как удобно останавливать / возобновлять поток по...

[Qt] QThread ошибка создания потока.
Здравствуйте. Не так давно пишу на c++, а в частности на Qt. На данный момент реализовываю проложение работающее с потоками. И так суть:...

QThread Передать даные из одного потока в другой
Надо передать данные из одного потока в другой. Использую сигнал и слот, ибо по-другому не умею, но ничего не выходит, слот принимающего...

7
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
02.04.2021, 10:40
ndgog, очень плохо написан код.

У всех виджетов есть метод closeEvent, переопределяешь его, и делаешь все свои дела, перед тем как закрыть окно программы.

Минимальный пример:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import sys
from PySide2 import QtWidgets, QtCore, QtGui
 
 
class Example(QtWidgets.QDialog):
 
    def __init__(self, parent: QtWidgets.QWidget = None):
        QtWidgets.QDialog.__init__(self, parent)
 
        if parent is None:
            self.show()
 
    def closeEvent(self, event: QtGui.QCloseEvent) -> None:
        if QtWidgets.QMessageBox.question(
                self, "Exit", "Are you sure?",
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.No:
            return event.ignore()
        return QtWidgets.QDialog.closeEvent(self, event)
 
 
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = Example()
    sys.exit(app.exec_())
0
0 / 0 / 1
Регистрация: 12.01.2021
Сообщений: 27
02.04.2021, 10:49  [ТС]
Цитата Сообщение от DmFat Посмотреть сообщение
очень плохо написан код
а если конкретнее.
Python
1
2
3
    def closeEvent(self, event: QCloseEvent) -> None:
        self.thread.terminate()
        self.thread = None
0
0 / 0 / 1
Регистрация: 12.01.2021
Сообщений: 27
08.04.2021, 15:05  [ТС]
Цитата Сообщение от ndgog Посмотреть сообщение
пока что переделал след. образом и вроде работает
нифига не работает
0
Модератор
Эксперт Python
 Аватар для Fudthhh
2696 / 1602 / 513
Регистрация: 21.02.2017
Сообщений: 4,210
Записей в блоге: 1
09.04.2021, 07:11
ndgog, что именно не работает?
0
0 / 0 / 1
Регистрация: 12.01.2021
Сообщений: 27
09.04.2021, 07:53  [ТС]
DmFat, поток с камеры все равно не закрывается(при закрытии окна).
0
 Аватар для kapbepucm
1568 / 741 / 321
Регистрация: 02.05.2020
Сообщений: 1,660
09.04.2021, 08:51
Могу ошибаться, но закрытие окна это не всегда close, по дефолту это hide.

Добавлено через 1 минуту
Цитата Сообщение от ndgog Посмотреть сообщение
поток с камеры все равно не закрывается(при закрытии окна)
другими словами- вы уверены, что closeEvent вызывался?
0
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
09.04.2021, 09:53
По моим представлениям, в этом случае нельзя использовать бесконечный цикл внутри потока.
Есть же requestInterruption() и isInterruptionRequestIed().
Python
1
2
3
4
5
6
7
8
    def run(self):
        cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
 
        while True:
            ret, source_img = cap.read()
            ....
заменить на
Python
1
2
3
4
5
6
7
8
    def run(self):
        cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
 
        while not isInterruptionRequested():
            ret, source_img = cap.read()
            ....
и ещё
Python
1
2
    def closeEvent(self, event: QCloseEvent) -> None:
        self.thread.terminate()
заменить на
Python
1
2
    def closeEvent(self, event: QCloseEvent) -> None:
        self.thread.requestInterruption()
terminate() не нужен.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.04.2021, 09:53
Помогаю со студенческими работами здесь

QThread как очищать память при завершении работы потока?
В моей минипрограммке используется класс наследованный от QThread. Этот объект в качестве полей класса имеет динамически создаваемые...

Нужно ли страховаться функцией QThread::wait() при выходе из потока?
Ну вопрос в шапке. Собственно, если у меня ран выглядит так: (exit = false конечно же сначала) void COOL::run() { ...

Остановка потока
Уважаемые программисты, прошу помощи, ибо не нашел логического объяснения своей проблеме. В моей программе создан класс -...

остановка потока
Начал изучать нити. Возник вопрос. Открываю новый потом main, жду 5 секунд и методом - iinterrup останавливаю его, но поток не...

Остановка потока
Делаю игру на java eclipse. Использую потоки. С помощью них создаю изображения на фрейме, которые потом перемещаются... (ну это не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru