Anonymous
Таймер не запускается автоматически в Python
Сообщение
Anonymous » 09 янв 2025, 20:53
Я создаю приложение для тренировки/запоминания гитарных грифов, используя PySide6. В приложении есть функция «Автоматический режим» (флажок), которая использует QTimer для отображения новых «вопросов» через регулярные промежутки времени (которые можно выбрать в меню настроек).
Однако, когда я устанавливаю флажок «Автоматический режим», вопросы не запускаются автоматически, пока я вручную не нажму кнопку «Новый вопрос». Что может быть причиной этого и как это исправить?
Вот код:
Код: Выделить всё
from PySide6.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget, QGraphicsOpacityEffect, QHBoxLayout, QSlider, QCheckBox, QDialog
from PySide6.QtCore import QTimer, Qt, QPropertyAnimation, QEasingCurve, Signal
from PySide6.QtGui import QFont
import pyttsx3
import random
string_tunings = [64, 59, 55, 50, 45, 40]
frets = list(range(0, 22))
note_names = {
'C': 'C',
'C#': 'C sharp',
'D': 'D',
'D#': 'D sharp',
'E': 'E',
'F': 'F',
'F#': 'F sharp',
'G': 'G',
'G#': 'G sharp',
'A': 'A',
'A#': 'A sharp',
'B': 'B',
}
def get_note_name(string, fret):
midi_note = string_tunings[string - 1] + fret
note = list(note_names.keys())[midi_note % 12]
return note_names[note]
class SettingsDialog(QDialog):
interval_changed = Signal(int)
def __init__(self, current_interval, parent=None):
super().__init__(parent)
self.setWindowTitle("Settings")
self.setFixedSize(300, 150)
layout = QVBoxLayout()
self.slider = QSlider(Qt.Horizontal)
self.slider.setMinimum(1)
self.slider.setMaximum(10)
self.slider.setValue(current_interval)
self.slider.setTickPosition(QSlider.TicksBelow)
self.slider.setTickInterval(1)
self.label = QLabel(f"Interval: {self.slider.value()} seconds")
self.label.setFont(QFont("Helvetica", 12))
self.label.setAlignment(Qt.AlignCenter)
self.slider.valueChanged.connect(self.update_label)
layout.addWidget(self.label)
layout.addWidget(self.slider)
save_button = QPushButton("Save")
save_button.clicked.connect(self.save_settings)
layout.addWidget(save_button)
self.setLayout(layout)
def update_label(self, value):
self.label.setText(f"Interval: {value} seconds")
def save_settings(self):
self.interval_changed.emit(self.slider.value())
self.accept()
class GuitarPracticeApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Guitar Fretboard Practice")
self.setFixedSize(400, 300)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.current_interval = 2
self.auto_mode = False
self.engine = pyttsx3.init()
self.engine.setProperty('rate', 150)
self.engine.setProperty('volume', 1.0)
self.header_label = QLabel("Learn the Guitar Fretboard")
self.header_label.setFont(QFont("Helvetica", 16, QFont.Bold))
self.header_label.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.header_label)
self.question_label = QLabel("")
self.question_label.setFont(QFont("Helvetica", 14))
self.question_label.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.question_label)
self.opacity_effect = QGraphicsOpacityEffect()
self.question_label.setGraphicsEffect(self.opacity_effect)
button_layout = QHBoxLayout()
self.new_question_button = QPushButton("New Question")
self.new_question_button.setFont(QFont("Helvetica", 12))
self.new_question_button.clicked.connect(self.show_new_question)
button_layout.addWidget(self.new_question_button)
self.auto_mode_checkbox = QCheckBox("Auto Mode")
self.auto_mode_checkbox.stateChanged.connect(self.toggle_auto_mode)
button_layout.addWidget(self.auto_mode_checkbox)
self.settings_button = QPushButton("⚙ Settings")
self.settings_button.clicked.connect(self.open_settings)
button_layout.addWidget(self.settings_button)
self.layout.addLayout(button_layout)
self.quit_button = QPushButton("Quit")
self.quit_button.setFont(QFont("Helvetica", 12))
self.quit_button.clicked.connect(self.close_application)
self.layout.addWidget(self.quit_button)
self.footer_label = QLabel("Made by wat1er")
font = QFont("Helvetica", 10)
font.setItalic(True)
self.footer_label.setFont(font)
self.footer_label.setAlignment(Qt.AlignCenter)
self.layout.addWidget(self.footer_label)
self.animation = QPropertyAnimation(self.opacity_effect, b"opacity")
self.animation.setDuration(1000)
self.animation.setEasingCurve(QEasingCurve.OutCubic)
self.timer = QTimer()
self.timer.timeout.connect(self.show_new_question)
self.show_new_question()
def show_new_question(self):
string, fret, note = self.generate_question()
message = f"String: {string}, Fret: {fret}\n(Note: {note})"
self.question_label.setText(message)
self.animate_text()
self.engine.say(message)
self.engine.runAndWait()
def animate_text(self):
self.animation.setStartValue(0)
self.animation.setEndValue(1)
self.animation.start()
def generate_question(self):
random_string = random.choice(range(1, 7))
random_fret = random.choice(frets)
note = get_note_name(random_string, random_fret)
return random_string, random_fret, note
def toggle_auto_mode(self, state):
self.auto_mode = state == Qt.Checked
if self.auto_mode:
self.show_new_question()
self.timer.start(self.current_interval * 1000)
else:
self.timer.stop()
def open_settings(self):
dialog = SettingsDialog(self.current_interval, self)
dialog.interval_changed.connect(self.update_interval)
dialog.exec()
def update_interval(self, interval):
self.current_interval = interval
if self.auto_mode:
self.timer.stop()
self.timer.start(self.current_interval * 1000)
def close_application(self):
self.engine.stop()
self.close()
if __name__ == "__main__":
app = QApplication([])
window = GuitarPracticeApp()
window.show()
app.exec()
Я также загрузил его в Pastebin:
https://pastebin.com/4mmnK16p
Подробнее здесь:
https://stackoverflow.com/questions/793 ... -in-python
1736445195
Anonymous
Я создаю приложение для тренировки/запоминания гитарных грифов, используя PySide6. В приложении есть функция «Автоматический режим» (флажок), которая использует QTimer для отображения новых «вопросов» через регулярные промежутки времени (которые можно выбрать в меню настроек). Однако, когда я устанавливаю флажок «Автоматический режим», вопросы не запускаются автоматически, пока я вручную не нажму кнопку «Новый вопрос». Что может быть причиной этого и как это исправить? Вот код: [code]from PySide6.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget, QGraphicsOpacityEffect, QHBoxLayout, QSlider, QCheckBox, QDialog from PySide6.QtCore import QTimer, Qt, QPropertyAnimation, QEasingCurve, Signal from PySide6.QtGui import QFont import pyttsx3 import random string_tunings = [64, 59, 55, 50, 45, 40] frets = list(range(0, 22)) note_names = { 'C': 'C', 'C#': 'C sharp', 'D': 'D', 'D#': 'D sharp', 'E': 'E', 'F': 'F', 'F#': 'F sharp', 'G': 'G', 'G#': 'G sharp', 'A': 'A', 'A#': 'A sharp', 'B': 'B', } def get_note_name(string, fret): midi_note = string_tunings[string - 1] + fret note = list(note_names.keys())[midi_note % 12] return note_names[note] class SettingsDialog(QDialog): interval_changed = Signal(int) def __init__(self, current_interval, parent=None): super().__init__(parent) self.setWindowTitle("Settings") self.setFixedSize(300, 150) layout = QVBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.setMinimum(1) self.slider.setMaximum(10) self.slider.setValue(current_interval) self.slider.setTickPosition(QSlider.TicksBelow) self.slider.setTickInterval(1) self.label = QLabel(f"Interval: {self.slider.value()} seconds") self.label.setFont(QFont("Helvetica", 12)) self.label.setAlignment(Qt.AlignCenter) self.slider.valueChanged.connect(self.update_label) layout.addWidget(self.label) layout.addWidget(self.slider) save_button = QPushButton("Save") save_button.clicked.connect(self.save_settings) layout.addWidget(save_button) self.setLayout(layout) def update_label(self, value): self.label.setText(f"Interval: {value} seconds") def save_settings(self): self.interval_changed.emit(self.slider.value()) self.accept() class GuitarPracticeApp(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Guitar Fretboard Practice") self.setFixedSize(400, 300) self.layout = QVBoxLayout() self.setLayout(self.layout) self.current_interval = 2 self.auto_mode = False self.engine = pyttsx3.init() self.engine.setProperty('rate', 150) self.engine.setProperty('volume', 1.0) self.header_label = QLabel("Learn the Guitar Fretboard") self.header_label.setFont(QFont("Helvetica", 16, QFont.Bold)) self.header_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.header_label) self.question_label = QLabel("") self.question_label.setFont(QFont("Helvetica", 14)) self.question_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.question_label) self.opacity_effect = QGraphicsOpacityEffect() self.question_label.setGraphicsEffect(self.opacity_effect) button_layout = QHBoxLayout() self.new_question_button = QPushButton("New Question") self.new_question_button.setFont(QFont("Helvetica", 12)) self.new_question_button.clicked.connect(self.show_new_question) button_layout.addWidget(self.new_question_button) self.auto_mode_checkbox = QCheckBox("Auto Mode") self.auto_mode_checkbox.stateChanged.connect(self.toggle_auto_mode) button_layout.addWidget(self.auto_mode_checkbox) self.settings_button = QPushButton("⚙ Settings") self.settings_button.clicked.connect(self.open_settings) button_layout.addWidget(self.settings_button) self.layout.addLayout(button_layout) self.quit_button = QPushButton("Quit") self.quit_button.setFont(QFont("Helvetica", 12)) self.quit_button.clicked.connect(self.close_application) self.layout.addWidget(self.quit_button) self.footer_label = QLabel("Made by wat1er") font = QFont("Helvetica", 10) font.setItalic(True) self.footer_label.setFont(font) self.footer_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.footer_label) self.animation = QPropertyAnimation(self.opacity_effect, b"opacity") self.animation.setDuration(1000) self.animation.setEasingCurve(QEasingCurve.OutCubic) self.timer = QTimer() self.timer.timeout.connect(self.show_new_question) self.show_new_question() def show_new_question(self): string, fret, note = self.generate_question() message = f"String: {string}, Fret: {fret}\n(Note: {note})" self.question_label.setText(message) self.animate_text() self.engine.say(message) self.engine.runAndWait() def animate_text(self): self.animation.setStartValue(0) self.animation.setEndValue(1) self.animation.start() def generate_question(self): random_string = random.choice(range(1, 7)) random_fret = random.choice(frets) note = get_note_name(random_string, random_fret) return random_string, random_fret, note def toggle_auto_mode(self, state): self.auto_mode = state == Qt.Checked if self.auto_mode: self.show_new_question() self.timer.start(self.current_interval * 1000) else: self.timer.stop() def open_settings(self): dialog = SettingsDialog(self.current_interval, self) dialog.interval_changed.connect(self.update_interval) dialog.exec() def update_interval(self, interval): self.current_interval = interval if self.auto_mode: self.timer.stop() self.timer.start(self.current_interval * 1000) def close_application(self): self.engine.stop() self.close() if __name__ == "__main__": app = QApplication([]) window = GuitarPracticeApp() window.show() app.exec() [/code] Я также загрузил его в Pastebin: https://pastebin.com/4mmnK16p Подробнее здесь: [url]https://stackoverflow.com/questions/79343565/a-timer-not-starting-automatically-in-python[/url]