Good all the time of day. Tell me, please, how to implement the execution of a specific function in a separate thread, so that the GUI does not hang. I give an example of a script in which there are only three buttons and a single-line text editor field.

The idea of ​​the script is such that it is necessary to specify the path to a specific folder by clicking on the browse button (or manually register it in the editor field), in which new files appear with some periodicity. After the path is defined, it is necessary to click on the start button of monitoring this folder in order to rename it at the moment of detection of a new file in the folder.

After clicking on the file rename button, the GUI hangs, but the script continues to work, when new files appear in the selected folder, they are renamed.

It is necessary that the GUI does not freeze and when you click on the rename button, this function is stopped.

I know, you can implement this through QThread, tried to use it, it turned out that the path to the folder should be written to the script initially.

I attach the script itself before QThread is added to it.

# -*- coding: utf-8 -*- import sys import os from datetime import datetime import time from PyQt5.QtCore import QObject, QThread from PyQt5.QtWidgets import QLineEdit, QApplication, QWidget, QPushButton, QToolTip, QMessageBox, QDesktopWidget, QFileDialog from PyQt5.QtGui import QIcon filename = 'log.txt' class renamerus_widget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.btn_view = QPushButton('ΠžΠ±Π·ΠΎΡ€', self) self.btn_view.setToolTip('Π’Ρ‹Π±Π΅Ρ€ΠΈ ΠΏΠ°ΠΏΠΊΡƒ') self.btn_view.clicked.connect(self.show_dialog) self.btn_view.resize(50, 25) self.btn_view.move(10, 60) self.btn_start = QPushButton('Запуск!', self) self.btn_start.setToolTip('Активация ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° ΠΏΠ°ΠΏΠΊΠΈ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π½Π΅ΠΉ') self.btn_start.clicked.connect(self.start_rename) self.btn_start.resize(70, 25) self.btn_start.move(78, 60) self.btn_stop = QPushButton('Π₯ΠΎΡ€ΠΎΡˆ..', self) self.btn_stop.setToolTip('ΠŸΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° ΠΏΠ°ΠΏΠΊΠΈ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Π½Π΅ΠΉ') self.btn_stop.setDisabled(True) self.btn_stop.clicked.connect(self.stop_rename) self.btn_stop.resize(70, 25) self.btn_stop.move(150, 60) self.line_directory = QLineEdit(self) self.line_directory.resize(210, 25) self.line_directory.move(10, 30) self.setFixedSize(230, 90) self.center() self.setWindowTitle('Renamerus') self.setWindowIcon(QIcon('ΠΏΡƒΡ‚ΡŒ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ ΠΈΠΊΠΎΠ½ΠΊΠΈ')) self.show() def center(self): sizeWindow = self.frameGeometry() locationWindow = QDesktopWidget().availableGeometry().center() sizeWindow.moveCenter(locationWindow) self.move(sizeWindow.topLeft()) def close_event(self, event): question_exit = QMessageBox.question(self,'Π—Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ','На этом всС?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if question_exit == QMessageBox.Yes: event.accept() else: event.ignore() def show_dialog(self): open_direct = QFileDialog.getExistingDirectory(self, 'Π’Ρ‹Π±ΠΈΡ€Π°ΠΉ','C://', QFileDialog.DontUseNativeDialog) self.line_directory.setText(open_direct) def start_rename(self, event): self.btn_start.setDisabled(True) self.btn_stop.setEnabled(True) if len(self.line_directory.text()) != 0: try: while True: list_files = os.listdir(self.line_directory.text()) if len(list_files) != 0: for i in range(len(list_files)): a = list_files[i] if a[2] != '.': now = datetime.now() now_date = datetime.strftime(datetime.now(), "%d.%m.%Y %H.%M.%S") try: new_name = os.rename(self.line_directory.text() + '//' + list_files[i], self.line_directory.text() + '//' + str(now_date) + a[-4:]) except PermissionError: time.sleep(5) new_name = os.rename(self.line_directory.text() + '//' + list_files[i], self.line_directory.text() + '//' + str(now_date) + a[-4:]) with open(filename, 'a') as logfile: logfile.write('Π€Π°ΠΉΠ» "' + a + '" ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ Π² ' + '"' + str(now_date) + a[-4:] + '"\n') time.sleep(1) else: time.sleep(10) except FileNotFoundError: QMessageBox.information(self, 'ΠŸΠ°ΠΏΠΊΡƒ Π½Π΅ нашСл', 'Найди Ρ‚ΠΎ, Π½Π΅ зная Ρ‡Ρ‚ΠΎ?!', QMessageBox.Ok) else: QMessageBox.information(self, 'Папка Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π°', 'Π£ΠΊΠ°ΠΆΠΈ ΠΏΠ°ΠΏΠΊΡƒ! ', QMessageBox.Ok) def stop_rename(self): #Π’ΡƒΡ‚ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ функция, которая останавливаСт дСйствиС start_rename if __name__ == '__main__': app = QApplication([]) ex = renamerus_widget() sys.exit(app.exec_()) 

1 answer 1

  1. As already suggested, it is better to use specialized tools to monitor the file system. For Qt, this is QFileSystemWatcher
  2. A thread can be initialized at startup, or communicate with it through inter-thread interaction mechanisms. As in python, so in Qt there are corresponding mechanisms. For example, in Qt you can communicate through standard signals.