gpt4 book ai didi

python - PyQt 中程序退出后不会关闭

转载 作者:行者123 更新时间:2023-12-01 00:40:39 26 4
gpt4 key购买 nike

所以,最近我尝试使用 PyQt5、pygame 和 mutagen 制作一个音频播放器。该程序运行得很好。但是,当我正在播放歌曲并尝试退出程序时,程序停止响应而歌曲继续播放。但当歌曲不播放时,这种情况就不会发生,此时就可以正常工作了。

这是代码:

from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow, QSlider
from PyQt5.QtGui import QColor
from PyQt5.QtCore import Qt
import sys
import pygame as pg
from mutagen.mp3 import MP3
import os
import threading

pg.init()

#33206

class window(QMainWindow):
def __init__(self):
super(window, self).__init__()
self.setGeometry(425, 65, 400, 190)
self.setWindowIcon(QtGui.QIcon("icon"))
self.setWindowTitle("MultiMedia Player")

# MenuBar
file = QtWidgets.QAction("&Open Mp3", self)
file.setShortcut("Ctrl + O")
file.triggered.connect(self.open_mp3)

# Quit
quit = QtWidgets.QAction("&Quit", self)
quit.setShortcut("Q")
quit.triggered.connect(self.close_app)

# Add Items

items = QtWidgets.QAction("&Add Items", self)
items.setShortcut("Ctrl + P")

mainmenu = self.menuBar()
filemenu = mainmenu.addMenu("&Open")
filemenu.addAction(file)
add_items = mainmenu.addMenu("&Add Items")
add_items.addAction(items)
filemenu.addAction(quit)

self.flag = 0

self.home()

def home(self):

# colors
black = (13, 13, 13)
light_black = (36, 36, 36)

# Pause Button
self.pause_btn = QtWidgets.QPushButton(self)
self.pause_btn.setText("Pause")
self.pause_btn.setShortcut("p")
self.pause_btn.move(0, 120)
self.pause_btn.clicked.connect(self.pause)

# Play Button
self.play_btn = QtWidgets.QPushButton(self)
self.play_btn.setText("Play")
self.play_btn.setShortcut("Space")
self.play_btn.move(150, 120)
self.play_btn.clicked.connect(self.play)

# Stop Button
self.stop_btn = QtWidgets.QPushButton(self)
self.stop_btn.setText("Stop")
self.stop_btn.setShortcut("s")
self.stop_btn.move(300, 120)

self.stop_btn.clicked.connect(self.stop)
# color for the window

color = QColor(70, 70, 70)

# Volume_Up Button
self.vup_btn = QtWidgets.QPushButton(self)
self.vup_btn.setText("V(+)")
self.vup_btn.setShortcut("+")
self.vup_btn.move(300, 160)
self.vup_btn.clicked.connect(self.volume_up)


# Volume_Down Button
self.vdown_btn = QtWidgets.QPushButton(self)
self.vdown_btn.setText("V(-)")
self.vdown_btn.setShortcut("-")
self.vdown_btn.move(0, 160)
self.vdown_btn.clicked.connect(self.volume_down)


# Seek Slider

self.slider = QSlider(Qt.Horizontal, self)
self.slider.setGeometry(20, 75, 350, 20)

# Volume Slider

self.v_slider = QSlider(Qt.Horizontal, self)
self.v_slider.setGeometry(120, 165, 160, 20)
self.v_slider.setMinimum(0)
self.v_slider.setMaximum(100)
self.v_slider.setValue(70)
self.volume_value = self.v_slider.value()
self.v_slider.valueChanged.connect(self.slider_value_changed)
print(self.v_slider.value() / 100)



def msg(self, title, message):
msg1 = QtWidgets.QMessageBox()
msg1.setWindowIcon(QtGui.QIcon("icon"))
msg1.setWindowTitle(title)
msg1.setText(message)
msg1.setStandardButtons(QtWidgets.QMessageBox.Ok)
msg1.exec_()


def open_mp3(self):
name = QtWidgets.QFileDialog.getOpenFileName(self)

format = os.path.splitext(name[0])
if format[1] == ".mp3":
self.audio = MP3(name[0])
self.duration = self.audio.info.length//1
self.min = int(self.duration // 60)
self.sec = int(self.duration % 60)

self.total_time = str(self.min) + ":" + str(self.sec)
print(self.total_time)

self.slider.setMaximum(self.duration)
self.slider.setMinimum(0)
time = []
time.append(self.total_time)
self.label = QtWidgets.QLabel(self)
self.label.setText(self.total_time)
self.label.setFont(QtGui.QFont("Arial", 9))
self.label.adjustSize()
self.label.move(373, 77)

song = name[0]
pg.mixer.music.load(song)
pg.mixer.music.play(1)
pg.mixer.music.set_volume(self.v_slider.value()/100)

self.label = QtWidgets.QLabel(self)
self.label.setText(song)
self.label.setFont(QtGui.QFont("Arial", 15))
self.label.adjustSize()
self.label.move(0, 36)
self.label.show()
threading_1 = threading.Thread(target=self.cur_time).start()

else:
self.msg("Invalid Format", "Choose A .Mp3 File Only!")

volume_level = pg.mixer.music.get_volume()
print(volume_level)

def cur_time(self):

true = 1
while true == 1:
if self.flag == 0:
self.m_time = pg.mixer.music.get_pos()
self.mm_time = self.m_time * 0.001
self.s_time = self.mm_time // 1
self.slider.setValue(self.s_time)
print(self.s_time)
self.slider.sliderMoved.connect(self.seek_changed)
if self.s_time == -1:
self.slider.setValue(0)
true = 2

if self.flag == 1:
print(self.s_time)

def seek_changed(self):
print(self.slider.value())
pg.mixer.music.set_pos(self.slider.value())

def slider_value_changed(self):
self.volume_value = self.v_slider.value()
pg.mixer.music.set_volume(self.v_slider.value()/100)

def volume_up(self):
self.volume_value = self.volume_value + 10
self.v_slider.setValue(self.volume_value)

if self.volume_value >= 100:
self.volume_value = 100


pg.mixer.music.set_volume(self.v_slider.value() / 100)
print(self.v_slider.value() / 100)


def volume_down(self):
self.volume_value = self.volume_value - 10
self.v_slider.setValue(self.volume_value)

if self.volume_value <= 0:
self.volume_value = 0
pg.mixer.music.set_volume(self.v_slider.value() / 100)
print(self.v_slider.value() / 100)


def pause(self):
pg.mixer.music.pause()
self.flag = 1

def stop(self):
pg.mixer.music.stop()
self.flag = -1

def play(self):

pg.mixer.music.unpause()
self.flag = 0


def close_app(self):
choice = QtWidgets.QMessageBox.question(
self, "QUIT", "You Sure You Wanna Quit?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
if choice == QtWidgets.QMessageBox.Yes:
sys.exit()
else:
pass




def items(self):
layout = QtWidgets.QVBoxLayout(self)
song_name = QtWidgets.QFileDialog.getOpenFileName(self)

widget = QtWidgets.QListWidget()
widget.setAlternatingRowColors(True)
widget.setDragDropMode(
QtWidgets.QAbstractItemView.InternalMove)

widget.addItems([str(i) for i in range(1, 6)])
layout.addWidget(widget)


if __name__ == '__main__':
app = QApplication(sys.argv)
win = window()
win.show()
sys.exit(app.exec_())

提前致谢。

最佳答案

主要问题是 threading.Thread 仍在运行,因此当 QtApplication“关闭”时,程序仍然处于事件状态。

您确实应该避免使用 while 循环来检查当前位置,因为它会在每次循环循环时调用该值的请求,从而消耗大量不必要的 CPU 资源。
另外,每次循环时,您都会将 sliderMoved 信号连接到eek_changed,这是不好

改用 QTimer,它将更新光标位置而不会使进程重载:

    # create a timer in the window __init__
self.cursor_updater = QtCore.QTimer(interval=100, timeout=self.cur_time)

#...
def cur_time(self):
# ignore the update if the user is seeking
if self.slider.isSliderDown():
return
self.slider.setValue(pg.mixer.music.get_pos() * .001)

然后,您只需在每次音乐开始(或取消暂停)时启动计时器,并在停止或暂停时停止计时器。


也就是说,您的代码还存在其他问题。

  1. pygame 和 Qt 运行它们自己的事件循环,因此您无法通过 sys.exit() 轻松且优雅地退出,也无法通过它们自己的 quit( ) 函数,因为它们中的一个或两个可能只是卡在自己的循环中而无法实际退出,从而保持进程运行(循环几乎不执行任何操作)并消耗大量资源。我不是使用 pygame PyQt 的专家,但据我所知,您可以调用 os._exit(0) 来代替。
  2. 应该注意窗口closeEvent(),因为如果用户只是关闭窗口而不退出,则不会出现任何确认对话框,并且上述退出过程也不会执行打电话。
  3. pygame.mixer.music.get_pos() “仅代表音乐播放了多长时间;它不考虑任何起始位置偏移”。因此,每当您使用 set_pos() 时,您都需要跟踪位置并相应地计算实际值。
  4. 您确实应该考虑使用布局,或者确保窗口大小是固定的,否则用户将能够将其大小调整为小于界面的大小。

关于python - PyQt 中程序退出后不会关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57373404/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com