Skip to main content

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
Asked
Modified 3 days ago
Viewed 201 times
2
\$\begingroup\$

I know that this program is not very outstanding, but I'm learning Python and decided to publish this code in order to get some advice and parting words and overall evaluation of the program. This is a simple timer with the ability to enter the desired number of minutes, start and reset functions.

As a beginner, it is very important for me to get any feedback from professionals who will accurately point out mistakes and shortcomings. I used the PyQt5 Python library.

from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QFont, QIcon
from PyQt5.QtMultimedia import QSound
from win32api import GetSystemMetrics
import time
import sys

class Window(QWidget):
    def __init__(self, parent = None):
        QtWidgets.QWidget.__init__(self, parent)


        self.setWindowTitle("Таймер")
        self.setGeometry(0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
        self.setMinimumSize(1200, 500)
    

        #кнопка старта
        self.btn_start = QtWidgets.QPushButton(self)
        self.btn_start.setText("Старт")
        self.btn_start.move(50, 50)
        self.btn_start.clicked.connect(self.start_timer)

        #кнопка сброса
        self.btn_reset = QtWidgets.QPushButton(self)
        self.btn_reset.setText("Сброс")
        self.btn_reset.move(50, 300)
        self.btn_reset.clicked.connect(self.reset)

        #место ввода
        self.input_text = QtWidgets.QTextEdit(self)
        self.input_text.setText("15")
        self.input_text.setFont(QFont("Arial", 18))
        self.input_text.move(40, 100)
        self.input_text.setMaximumSize(100, 40)
        self.input_text.setAlignment(Qt.AlignCenter)
        self.input_text.toPlainText()

        #место вывода времени
        self.timer1 = QtWidgets.QLabel(self)
        self.timer1.setAlignment(Qt.AlignCenter)
        self.timer1.move(100, 40)
    

        #галочка звука
        self.audio = QtWidgets.QCheckBox(self)
        self.audio.setText("Включить звук")
        self.audio.move(40, 175)

        self.blink = False

        #таймер, благодаря которому все работает
        self.timer = QTimer(self)                            
        self.timer.timeout.connect(self.showTime)                   
        self.timer.setInterval(1000)
        self.time = 0

    #функция масштабируемости
    def  resizeEvent(self, e) -> None:
        w = e.size().width()
        h = e.size().height()
    
        #размер окна вывода времени
        c = int(GetSystemMetrics(1) - 50)
        self.timer1.resize(w-350, h-200)
    
        #положение окна вывода времени
        self.timer1.move(int(w/10), int(h/11))
    
        #размер шрифта цифр
        p = int(w / 5)
        self.timer1.setFont(QFont("Arial", p))
    
        QtWidgets.QWidget.resizeEvent(self, e)


    #функция кнопки старта
    def start_timer(self):
         text1 = str(self.input_text.toPlainText())

        #перехват ошибки, дабы неправильный ввод(буквы, запятая, пробелы) обнулялся
        try:
            text2 = float(text1)
        except ValueError:
            text2 = 0
            self.input_text.setText("0")
            self.btn_start.setText("Старт")
            self.input_text.setAlignment(Qt.AlignCenter)
        
        
         text3 = float(text2)
         text = text3 * 60

        if self.btn_start.text() == "Старт":
             if not self.time: self.time = text
             self.timer.start()
             self.btn_start.setText("Стоп")
        else:
             self.timer.stop()
             self.btn_start.setText("Старт")


    #ГЛАВНАЯ ФУНКЦИЯ, благодаря ей таймер и работает
      def showTime(self):

            if self.time > 0:
                self.time -= 1
                text1 = self.time

                #превращение в MM:SS
                ty_res = time.gmtime(text1)
                res = time.strftime("%M:%S",ty_res)
                self.timer1.setText(res)

                #делает цифры красными
                if self.time < 61:
                     self.timer1.setStyleSheet("color: #FF0000")
            
                #заставляет цифры мигать
                if self.time < 30:
                    if self.blink == False:
                        self.timer1.hide()
                        self.blink = True
                    else:
                        self.timer1.show()
                        self.blink = False


                if self.time == 0:
                    self.timer1.setText("00:00")
                    self.btn_start.setText("Старт")
                    if self.audio.checkState():
                        QSound.play('C:\\Users\\Users\\user_name\\....\\....\\....wav') #писк при нуле


     #функция кнопки сброса
     def reset(self):
        self.timer.stop()       
        self.btn_start.setText("Старт")
        self.time = 00.00
        self.timer1.setText(str(self.time))
        self.timer1.setStyleSheet("color: #000000")




if __name__ == "__main__":
    app = QApplication(sys.argv) 
    app.setWindowIcon(QtGui.QIcon('C:\\Users\\user_name\\....\\....\\....ico'))

    window = Window()
    window.setWindowIcon(QtGui.QIcon('C:\\Users\\user_name\\....\\....\\....ico'))

    window.show()
    sys.exit(app.exec_())
\$\endgroup\$
2
  • \$\begingroup\$ Don't use widget.move(), and don't hard code sizes, in hardcoding the layout, your program will only look the way you designed at the specific resolution you targeted, and if you resize the window the layout will definitely break and it won't be what you wanted. Instead use layout classes and let the program handle it for you, in this way you don't need to calculate the sizes and the window will always look the way you intended it to look like. \$\endgroup\$
    Ξένη Γήινος
    –  Ξένη Γήινος
    2022-05-16 15:56:54 +00:00
    Commented May 16, 2022 at 15:56
  • \$\begingroup\$ And PyQt5 is severely outdated, it will eventually be shifted out, the latest is PyQt6, PyQt5 has wide spread use but most projects that still use PyQt5 came from way back, they hang on using it because of backward compatibility, PyQt5 is much less robust in features than PyQt6. New projects should use PyQt6. \$\endgroup\$
    Ξένη Γήινος
    –  Ξένη Γήινος
    2022-05-16 16:02:28 +00:00
    Commented May 16, 2022 at 16:02

1 Answer 1

2
\$\begingroup\$

Portability

When I copy the code out of the question and try to run it, I get syntax errors due to indentation. Perhaps your indentation mixes single spaces with tab characters on the same line, and the tabs did not get properly preserved. Review the indentation of your code.

Layout

After I adjusted the indentation to get past the errors, I still see inconsistent indentation. The black program can be used to automatically reformat the code with consistent indentation.

Also, this line:

if not self.time: self.time = text

is typically split into 2:

if not self.time:
    self.time = text

Documentation

The PEP 8 style guide recommends adding docstrings for classes and functions.

I see that your functions have comments above them. You could convert those comments into docstrings:

def start_timer(self):
    """ add description here... """

Since the comments are not in English, I can't assess whether they are useful or not.

Naming

The PEP 8 style guide recommends snake_case for function and variable names. For example, resizeEvent would be resize_event

In the resizeEvent function, the variable named p does not convey any meaning. However, this variable can be eliminated by combining these 2 lines:

p = int(w / 5)
self.timer1.setFont(QFont("Arial", p))

into 1 line:

self.timer1.setFont(QFont("Arial", int(w / 5)))

Tools

You could run code development tools to automatically find some style issues with your code.

ruff identifies QIcon as an unused import which can be deleted.

It also recommends this line:

if self.blink == False:

be changed to:

if not self.blink:
\$\endgroup\$
2
  • 2
    \$\begingroup\$ resizeEvent is a Qt method which is overridden, it cannot be renamed. The override decorator could be useful here though. \$\endgroup\$
    rdesparbes
    –  rdesparbes
    2025-10-17 11:00:27 +00:00
    Commented Oct 17 at 11:00
  • \$\begingroup\$ @rdesparbes: That explains the inconsistency with naming. Thanks. \$\endgroup\$
    toolic
    –  toolic
    2025-10-17 11:13:44 +00:00
    Commented Oct 17 at 11:13

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.