В моем приложении PySide6 я создаю QLabel и отображаю внутри него файл .GIF.
Это предполагает сначала создание объекта QMovie (который принимает относительный путь к файлу .GIF из текущего каталога), а затем использование метода QLabel.setMovie(QMovie) для отображения файл .GIF внутри этикетки. Наконец, метод QMovie.start() запускает воспроизведение .GIF.
После этого я хочу иметь возможность удалить файл .GIF. Я читал о двух функциях Python для удаления файлов: os.remove() и pathlib.Path.unlink() .
Обе эти функции работают как желательно при отсутствии кода PySide6. Я могу удалить файл .GIF со своего компьютера без каких-либо ошибок PermissionError.
Ошибка PermissionError появляется, когда я пытаюсь вызвать любую из этих функций после вызова QMovie .start() для «воспроизведения» моего файла .GIF внутри моего приложения PySide6. Вот полный оператор PermissionError:
Код: Выделить всё
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'test_gif_question_mark.gif'
Ошибка PermissionError не появляется, если я не вызываю QMovie.start() т.е. я могу удалить файл .GIF после создания объекта QMovie и даже после вызова QLabel.setMovie(QMovie) .
Очевидно, что мое приложение PySide6 открывает и считывает данные из файла .GIF, чтобы отобразить и «воспроизвести» связанную с ним анимацию. Что для меня неочевидно, так это то, как «закрыть» файл .GIF, чтобы процесс python.exe прекратил «использовать» файл .GIF, давая мне возможность удалить его.
Вот набор действий, которые я пытался «закрыть» файл .GIF:
- Вызов QMovie.stop() .
- Вызов QLabel.clear() .
- Удаление объекта QMovie с помощью del.
- Удаление QLabel объект с del .
- Закрытие QApplication .
Удаление QApplication с помощью del . - Удаление Экземпляр QMainWindow с использованием del — это единственный экземпляр в моих переменных после всего вышеперечисленного.
Мне кажется например, QMovie.stop() не делает то, что я хочу - я хочу, чтобы он «отпустил» и «закрыл» файл .GIF, чтобы процесс python.exe был больше не использую его, и я могу попросить Windows удалить файл.
Если вы знаете, как я могу заставить python.exe прекратить использование файла .GIF или любые другие решения, буду очень благодарен за вашу помощь.
Полный воспроизводимый код:
Код: Выделить всё
import sys
import os
from pathlib import Path
from PySide6.QtWidgets import QMainWindow, QVBoxLayout, QWidget, QApplication, QPushButton, QLabel, QHBoxLayout
from PySide6.QtGui import QMovie
# Description: This script builds a small QApplication GUI with buttons that stimulate various steps in the process
# of using, displaying, stopping using, and finally trying to delete a .gif file.
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# Specify the path to the gif file from the current directory:
self.path_to_gif = 'test_gif_question_mark.gif'
# Create an instance of the QLabel class:
self.my_label = QLabel()
# Placeholder for the QMovie object:
self.my_QMovie = None
# Create a button to make the QMovie object:
my_button_create_qmovie = QPushButton()
my_button_create_qmovie.setText('Create QMovie')
my_button_create_qmovie.clicked.connect(self.clicked_create_button)
# Create a button to display the QMovie object in the QLabel:
my_button_display_qmovie = QPushButton()
my_button_display_qmovie.setText('Display QMovie')
my_button_display_qmovie.clicked.connect(self.clicked_display_button)
# Create a button to try to stop using the gif:
my_button_stop_using_gif = QPushButton()
my_button_stop_using_gif.setText('Try to stop using gif file')
my_button_stop_using_gif.clicked.connect(self.clicked_stop_button)
# Create a button to try to delete the gif:
my_button_delete_gif = QPushButton()
my_button_delete_gif.setText('Delete gif file')
my_button_delete_gif.clicked.connect(self.clicked_delete_button)
# Place the buttons in a horizontal layout:
layout_h_1 = QHBoxLayout()
layout_h_1.addWidget(my_button_create_qmovie)
layout_h_1.addWidget(my_button_display_qmovie)
layout_h_2 = QHBoxLayout()
layout_h_2.addWidget(my_button_stop_using_gif)
layout_h_2.addWidget(my_button_delete_gif)
# Assign the horizontal layouts to empty widgets:
widget_h_1 = QWidget()
widget_h_1.setLayout(layout_h_1)
widget_h_2 = QWidget()
widget_h_2.setLayout(layout_h_2)
# Place the label & buttons in a vertical layout:
layout_v = QVBoxLayout()
layout_v.addWidget(self.my_label)
layout_v.addWidget(widget_h_1)
layout_v.addWidget(widget_h_2)
# Create a placeholder widget to hold the layout.
widget = QWidget()
widget.setLayout(layout_v)
# Set the central widget of the main window:
self.setCentralWidget(widget)
def clicked_create_button(self):
# Create a QMovie to display:
self.my_QMovie = QMovie(self.path_to_gif)
print('\nCreated QMovie object using path to .gif file')
def clicked_display_button(self):
# Display the gif inside the label:
self.my_label.setMovie(self.my_QMovie)
# Start the movie playing:
self.my_QMovie.start()
print('\nDisplayed and started QMovie')
def clicked_delete_button(self):
# Use os.remove to try to delete the gif file:
# os.remove(self.path_to_gif)
# Use pathlib.unlink to try to delete the gif file:
path_gif = Path(self.path_to_gif)
path_gif.unlink()
def clicked_stop_button(self):
# Try different things to get python to stop using the .gif file:
# Try 'stopping' the QMovie object:
self.my_QMovie.stop()
# Try clearing the QLabel:
self.my_label.clear()
# Try deleting the QMovie object:
del self.my_QMovie
# Try deleting the QLabel:
del self.my_label
# Run the QApplication:
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()
print('app finished')
# Try deleting the QApplication after it has finished:
del app
# Try deleting the MainWindow:
del w
# Try deleting the gif file even after the QApplication has closed:
os.remove('test_gif_question_mark.gif')
test_gif_question_mark.gif
Подробнее здесь: https://stackoverflow.com/questions/786 ... ously-star