Seite 1 von 1

Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 08:46
von tschorsch
Hallo zusammen.

Vielleicht kann mir jemand helfen - bin total neu im Programmieren. Vor laaaaaaanger Zeit habe ich mal C gemacht, aber wohl alles vergessen.

Im Moment versuche ich einen Countdown zu schreiben.

Ausgabe nicht
30
29
28
27
...usw.

sondern 30, dann 29, dann 28 aber immer die Zahl vorher löschen. Wollte dies mit print(t, end="\r") machen, aber das funktioniert nicht.

Dann soll eine Ansage bei 25, 20, 15, ....usw kommen. Dies habe ich mit "if" Statments versucht - geht nicht......

# import the time module
import time

# pip install pyttsx3 pypiwin32 - text to speech
import pyttsx3

# import of winsound module
import winsound

# One time initialization
engine: object = pyttsx3.init()

# Set properties _before_ you add things to say
engine.setProperty('rate', 150) # Speed percent (can go over 100)
engine.setProperty('volume', 0.9) # Volume 0-1

engine.say("Model launched")

# define the countdown func.
def countdown(t):
while t:
time.sleep(1)
print(t)
if (t=25):
engine.say("25")
if (t=20):
engine.say("20")
if (t=15):
engine.say("15")
if (t=10):
engine.say("10")
if (t=5):
engine.say("5")
t -= 1

frequency = 2500 # Set Frequency To 2500 Hertz
duration = 1000 # Set Duration To 1000 ms == 1 second
winsound.Beep(frequency, duration)


# time in seconds
t = 30

# function call
countdown(int(t))

Kann mir da jemand helfen??

Viiiielen Dank!
Georg

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 08:48
von tschorsch

Code: Alles auswählen

# import the time module
import time

# pip install pyttsx3 pypiwin32 - text to speech
import pyttsx3

# import of winsound module
import winsound

# One time initialization
engine: object = pyttsx3.init()

# Set properties _before_ you add things to say
engine.setProperty('rate', 150)    # Speed percent (can go over 100)
engine.setProperty('volume', 0.9)  # Volume 0-1

engine.say("Model launched")

# define the countdown func.
def countdown(t):
    while t:
        time.sleep(1)
        print(t)
        if (t=25):
            engine.say("25")
        if (t=20):
            engine.say("20")
        if (t=15):
            engine.say("15")
        if (t=10):
            engine.say("10")
        if (t=5):
            engine.say("5")
        t -= 1

    frequency = 2500  # Set Frequency To 2500 Hertz
    duration = 1000  # Set Duration To 1000 ms == 1 second
    winsound.Beep(frequency, duration)


# time in seconds
t = 30

# function call
countdown(int(t))

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:03
von Jankie

Code: Alles auswählen

import time


def countdown(start):
    for number in range(start,0, -1):
        print(number, end = '\r')
        if number in range(0, start, 5):
            engine.say(number)
        time.sleep(1)
    

countdown(30)
Habe leider nicht das pyttsx3 Modul, also konnte nicht testen und den Rest der dafür erforderlich ist müsstest du ergänzen.


Anmerkungen:

Vergleiche macht man mit einem doppel Gleich ==, die Klammern beim IF können weg, IF ist keine Funktion. Da aber bei jeder Bedingung das gleiche passieren soll, nur mit einer anderen Zahl als Ausgabe würde ich hier Testen ob der Wert in einer Liste ist, welche die Schritte beinhaltet, dann musst du nicht so viele IFs schreiben.
Statt in einer While Schleife runter zu Zählen, würde ich über eine Liste iterieren, die die Zahlen in abfolgender Reihenfolge beinhaltet und mmer das aktuelle Element ausgeben (mit range())
Die Umwandlung der Variable t in einen Integer beim Funktionsauftruf ist überflüssig. t ist bereits ein Integer.

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:29
von tschorsch
Vielen Dank!
Funktioniert soweit...

Code: Alles auswählen

# import the time module
import time

# pip install pyttsx3 pypiwin32 - text to speech
import pyttsx3

# import of winsound module
import winsound

# One time initialization
engine: object = pyttsx3.init()

# Set properties _before_ you add things to say
engine.setProperty('rate', 150)    # Speed percent (can go over 100)
engine.setProperty('volume', 0.9)  # Volume 0-1

engine = pyttsx3.init()
engine.say("Model launched")
engine.runAndWait()

# define the countdown func.
def countdown(start):
    for number in range(start,0, -1):
        print(number)
        time.sleep(1)
        if number in (1,2,3,4,5,10,15,20,25):
            engine.say(number)

    frequency = 2500  # Set Frequency To 2500 Hertz
    duration = 1000  # Set Duration To 1000 ms == 1 second
    winsound.Beep(frequency, duration)


# time in seconds
t = 30

# function call
countdown(int(t))
Das die Ansage gemacht wird, muss ich aber nach engine.say(number) noch engine.runAndWait() einfügen, aber dann verzögert sich alles.

Hast du eine Idee, wie ich dies vermeiden kann?

So erfolgt die Ansage, aber verspätet....

Code: Alles auswählen

# import the time module
import time

# pip install pyttsx3 pypiwin32 - text to speech
import pyttsx3

# import of winsound module
import winsound

# One time initialization
engine: object = pyttsx3.init()

# Set properties _before_ you add things to say
engine.setProperty('rate', 150)    # Speed percent (can go over 100)
engine.setProperty('volume', 0.9)  # Volume 0-1

engine = pyttsx3.init()
engine.say("Model launched")
engine.runAndWait()

# define the countdown func.
def countdown(start):
    for number in range(start,0, -1):
        print(number)
        time.sleep(1)
        if number in (1,2,3,4,5,10,15,20,25):
            engine.say(number)
            engine.runAndWait()
    frequency = 2500  # Set Frequency To 2500 Hertz
    duration = 1000  # Set Duration To 1000 ms == 1 second
    winsound.Beep(frequency, duration)


# time in seconds
t = 30

# function call
countdown(int(t))

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:37
von sparrow
@tschorsch: Überleg mal, was dein Programm macht. Und dann macht mal selbst nach, was dein Programm macht.
Und dann überleg mal, wenn du einen Countdown runterzählen würdest, wie du das machen würdest.

Und dann schau dir mal an, was time.monotonic macht. Das ist aber keine Zauberei. Du musst schon dein Vorgehen einmal komplett ändern.

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:50
von tschorsch
Danke sparrow!

Müsste wohl zwei Threads/Funktionen haben. Eine macht den Countdown und wenn t=25 (oder 20, usw) ist, wird dies in eine andere Funktion übergeben/aufgerufen.

Könnte das hinhauen?

Georg

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:51
von tschorsch
btw:
print(number, end = '\r')
funktioniert leider nicht. Wird immer noch untereinander ausgegeben.

:?

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:54
von __blackjack__
@tschorsch: Das ``=`` bei den ``if``-Bedingungen führt zu einem `SyntaxError`. *Den* hättest Du ja mal selbst beheben können oder zumindest erwähnen sollen das es *daran* scheitert. Denn das kommt ja nicht mal am Compiler vorbei.

Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist.

Installationsanleitungen von Modulen gehören da auch nicht rein. Dafür hat man entweder eine Textdatei die sich an Menschen richtet, oder eine die sich an Werkzeuge wie `pip` richtet (`requirements.txt`).

Welches Werkzeug nimmst Du denn um Typannotationen zu prüfen? Falls die Antwort „Häh?“ oder „Keines.“ sein sollte, dann lass das mit den Typannotationen bleiben, denn dann nützt das nichts, weil man nicht weiss ob die überhaupt korrekt sind. Das ``engine: object`` ist jedenfalls *falsch*, denn `object` hat weder eine `setProperty()`- noch eine `say()`-Methode. `mypy` meldet da an den entsprechenden Stellen ``error: "object" has no attribute "setProperty"`` und ``error: "object" has no attribute "say"``.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Das bedeutet dann auch, dass die `countdown()`-Funktion `engine` als Argument übergeben bekommen muss.

Das die ``while``-Schleife eine ``for``-Schleife sein sollte wurde ja schon von Jankie erwähnt. Ich persönlich verwende da dann lieber `reversed()` mit einem `range()`, das aufsteigend ist. Dann muss man weniger über die Grenzwerte nachdenken beim schreiben und beim lesen.

Neben dem Wagenrücklauf-Steuerzeichen ("\r") muss man noch dafür sorgen, das die Ausgabe auch tatsächlich passiert und nicht nur in einem Ausgabepuffer landet. Wenn auch "\r" untereinander ausgegeben wird, dann führst Du das wahrscheinlich nicht in einem Konsolenfenster aus.

Mit einem `range()`-Objekt testen ob `t` gesprochen werden soll ist eine Möglichkeit. Testen der Eigenschaften von `t` — teilbar durch 5 und nicht der Startwert — eine Andere.

Ebenfalls ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import time
import winsound

import pyttsx3



def countdown(engine, duration):
    for i in reversed(range(1, duration + 1)):
        time.sleep(1)
        print(i, end="\r", flush=True)
        if i % 5 == 0 and i != duration:
            engine.say(str(i))

    winsound.Beep(2500, 1000)


def main():
    engine = pyttsx3.init()
    engine.setProperty("rate", 150)
    engine.setProperty("volume", 0.9)

    engine.say("Model launched")
    
    countdown(engine, 30)


if __name__ == "__main__":
    main()

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 09:57
von Sirius3
@tschorsch: nein, keine Threads. Das würde nur die Synchronisation schwierig machen.
Wie würdest Du einen Countdown ansagen, wenn Du eine Stopuhr hättest?

Zum Zeileende-Problem: wo und wie führst Du das Programm aus?

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 10:11
von mp1337
tschorsch hat geschrieben: Dienstag 22. September 2020, 09:51 btw:
print(number, end = '\r')
funktioniert leider nicht. Wird immer noch untereinander ausgegeben.

:?
Probier das Mal so:

Code: Alles auswählen

import time
import sys

ar = [1,29,7,5,8,3,6]


for i in range(len(ar)-1):
    sys.stdout.write("\r" + str(i)) 
    sys.stdout.flush()
    time.sleep(5)
    

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 10:28
von __blackjack__
Mit Thread (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import time
import winsound
from queue import Queue
from threading import Thread

import pyttsx3


def process_speaking(engine, queue):
    while True:
        engine.say(queue.get())
        engine.runAndWait()


def countdown(duration, say_callback):
    for i in reversed(range(1, duration + 1)):
        time.sleep(1)
        print(i, end="\r", flush=True)
        if i % 5 == 0 and i != duration:
            say_callback(str(i))

    winsound.Beep(2500, 1000)


def main():
    engine = pyttsx3.init()
    engine.setProperty("rate", 150)
    engine.setProperty("volume", 0.9)

    engine.say("Model launched")
    engine.runAndWait()
    
    queue = Queue()
    Thread(target=process_speaking, args=[engine, queue], daemon=True).start()
    countdown(30, queue.put)


if __name__ == "__main__":
    main()

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 12:15
von aaronlyy
tschorsch hat geschrieben: Dienstag 22. September 2020, 09:51 btw:
print(number, end = '\r')
funktioniert leider nicht. Wird immer noch untereinander ausgegeben.

:?
den screen kannst du hiermit clearen

Code: Alles auswählen

import os
os.system("cls") # clear on unix
also könntest du das so machen:

Code: Alles auswählen

import os
import time

for i in range(10, 0, -1):
	print(i)
	time.sleep(1)
	os.system("cls")

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 12:45
von tschorsch
Wow! Danke vielmals...das muss ich zuerst mal verdauen.

Funktioniert soweit.....

Es gibt immer noch eine Verzögerung bei 25, 20, usw, obwohl es ein einem Thread läuft
Alles wird untereinander geschrieben. Das Programm wird/soll mit einem Button (Qt Design) gestartet und die Ausgabe erfolgt in einem Feld
Ich kann nich nachvollziehen, woher das "Fertig" kommt. Dies sehe ich nirgends als einen String :?:
import os
geht nicht resp. ist grau

Ich verwende Python 3.8 auf Win 10 mit PyCharm

Danke Danke, Georg

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 13:26
von __blackjack__
@tschorsch: Was heisst ”Verzögerungen” denn genau? Wenn die Sprachausgabe länger als 5 Sekunden braucht, dann staut sich das natürlich, da hilft dann nur schneller sprechen lassen. Ansonsten schläft `time.sleep()` *ungefähr* die angegebene Zeit. Kann auch ein bisschen mehr oder ein bisschen weniger sein. Und bei einer GUI darfst Du `time.sleep()` in Rückrufen von der GUI gar nicht für so etwas verwenden, denn das blockiert dann ja die GUI für die 30 Sekunden bevor die die Kontrolle wieder bekommt und was an der Darstellung ändern kann und wieder auf Ergeignisse reagieren kann. In einer GUI ist das dann ja noch einmal etwas ganz anderes.

Wie kommt denn die `print()`-Ausgabe in ein Textfeld? Und natürlich funktioniert dort dann das mit dem "\r" nicht. Das ist ein Steuerzeichen, dass von einem Terminal(emulator) als Wagenrücklauf, also Position für das nächste auszugebende Zeichen wieder an den Zeilenanfang setzen, interpretiert wird. Wenn das, wo auch immer es ausgegeben wird, nicht so interpretiert wird, funktioniert es nicht. Du hast ein Konsolenprogramm gezeigt und kein GUI-Programm. Und in der Konsole ausgeführt, funktioniert das mit dem "\r" und einem „flush” der Ausgabe.

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 14:09
von mp1337
tschorsch hat geschrieben: Dienstag 22. September 2020, 12:45 Wow! Danke vielmals...das muss ich zuerst mal verdauen.

Funktioniert soweit.....

Es gibt immer noch eine Verzögerung bei 25, 20, usw, obwohl es ein einem Thread läuft
Alles wird untereinander geschrieben. Das Programm wird/soll mit einem Button (Qt Design) gestartet und die Ausgabe erfolgt in einem Feld
Ich kann nich nachvollziehen, woher das "Fertig" kommt. Dies sehe ich nirgends als einen String :?:
import os
geht nicht resp. ist grau

Ich verwende Python 3.8 auf Win 10 mit PyCharm

Danke Danke, Georg
Das muss aber funktionieren. os gehört zu der standard Python Library.

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 16:23
von tschorsch
Vielen Dank!

Was ich eigentlich machel will ist folgendes (und bitte sagen, sollte dies zu kompliziert sein...): Ich habe im Qt Designer ein Gui gebastelt mit ein paar Buttons und Felder.

Wenn ich den Button "B_Start" drücke, soll der Countdown starten und die Ausgabe soll im Feld "label_4".

Ist das machbar oder bin ich total auf dem Holzweg?

Code: Alles auswählen

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(500, 300)
        MainWindow.setMinimumSize(QtCore.QSize(500, 300))
        MainWindow.setMaximumSize(QtCore.QSize(500, 300))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(20, 150, 431, 90))
        font = QtGui.QFont()
        font.setPointSize(7)
        self.layoutWidget.setFont(font)
        self.layoutWidget.setObjectName("layoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.label_4 = QtWidgets.QLabel(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.label_4.setFont(font)
        self.label_4.setObjectName("label_4")
        self.gridLayout.addWidget(self.label_4, 0, 0, 1, 1)
        self.Out_CountD = QtWidgets.QLineEdit(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.Out_CountD.setFont(font)
        self.Out_CountD.setReadOnly(True)
        self.Out_CountD.setObjectName("Out_CountD")
        self.gridLayout.addWidget(self.Out_CountD, 0, 1, 1, 1)
        self.label_8 = QtWidgets.QLabel(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.label_8.setFont(font)
        self.label_8.setObjectName("label_8")
        self.gridLayout.addWidget(self.label_8, 0, 2, 1, 1)
        self.Out_Time_Total = QtWidgets.QLineEdit(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.Out_Time_Total.setFont(font)
        self.Out_Time_Total.setReadOnly(True)
        self.Out_Time_Total.setObjectName("Out_Time_Total")
        self.gridLayout.addWidget(self.Out_Time_Total, 0, 3, 1, 1)
        self.label_5 = QtWidgets.QLabel(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1)
        self.Out_Count_A = QtWidgets.QLineEdit(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.Out_Count_A.setFont(font)
        self.Out_Count_A.setReadOnly(True)
        self.Out_Count_A.setObjectName("Out_Count_A")
        self.gridLayout.addWidget(self.Out_Count_A, 1, 1, 1, 1)
        self.label_6 = QtWidgets.QLabel(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.label_6.setFont(font)
        self.label_6.setObjectName("label_6")
        self.gridLayout.addWidget(self.label_6, 2, 0, 1, 1)
        self.Out_Count_B = QtWidgets.QLineEdit(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.Out_Count_B.setFont(font)
        self.Out_Count_B.setReadOnly(True)
        self.Out_Count_B.setObjectName("Out_Count_B")
        self.gridLayout.addWidget(self.Out_Count_B, 2, 1, 1, 1)
        self.label_7 = QtWidgets.QLabel(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.label_7.setFont(font)
        self.label_7.setObjectName("label_7")
        self.gridLayout.addWidget(self.label_7, 3, 0, 1, 1)
        self.Out_Count_L = QtWidgets.QLineEdit(self.layoutWidget)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.Out_Count_L.setFont(font)
        self.Out_Count_L.setReadOnly(True)
        self.Out_Count_L.setObjectName("Out_Count_L")
        self.gridLayout.addWidget(self.Out_Count_L, 3, 1, 1, 1)
        self.layoutWidget1 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget1.setGeometry(QtCore.QRect(20, 10, 431, 21))
        font = QtGui.QFont()
        font.setPointSize(7)
        self.layoutWidget1.setFont(font)
        self.layoutWidget1.setObjectName("layoutWidget1")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget1)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.HotSpotIP = QtWidgets.QLabel(self.layoutWidget1)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.HotSpotIP.setFont(font)
        self.HotSpotIP.setObjectName("HotSpotIP")
        self.horizontalLayout.addWidget(self.HotSpotIP)
        self.HotSpotIPInput = QtWidgets.QLineEdit(self.layoutWidget1)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.HotSpotIPInput.setFont(font)
        self.HotSpotIPInput.setReadOnly(True)
        self.HotSpotIPInput.setObjectName("HotSpotIPInput")
        self.horizontalLayout.addWidget(self.HotSpotIPInput)
        self.BaseAIP = QtWidgets.QLabel(self.layoutWidget1)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.BaseAIP.setFont(font)
        self.BaseAIP.setObjectName("BaseAIP")
        self.horizontalLayout.addWidget(self.BaseAIP)
        self.BaseAIPInput = QtWidgets.QLineEdit(self.layoutWidget1)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.BaseAIPInput.setFont(font)
        self.BaseAIPInput.setReadOnly(True)
        self.BaseAIPInput.setObjectName("BaseAIPInput")
        self.horizontalLayout.addWidget(self.BaseAIPInput)
        self.BaseBIP = QtWidgets.QLabel(self.layoutWidget1)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.BaseBIP.setFont(font)
        self.BaseBIP.setObjectName("BaseBIP")
        self.horizontalLayout.addWidget(self.BaseBIP)
        self.BaseBIPInput = QtWidgets.QLineEdit(self.layoutWidget1)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.BaseBIPInput.setFont(font)
        self.BaseBIPInput.setReadOnly(True)
        self.BaseBIPInput.setObjectName("BaseBIPInput")
        self.horizontalLayout.addWidget(self.BaseBIPInput)
        self.layoutWidget2 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget2.setGeometry(QtCore.QRect(20, 60, 431, 19))
        font = QtGui.QFont()
        font.setPointSize(7)
        self.layoutWidget2.setFont(font)
        self.layoutWidget2.setObjectName("layoutWidget2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.layoutWidget2)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.B_Connect = QtWidgets.QPushButton(self.layoutWidget2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.B_Connect.sizePolicy().hasHeightForWidth())
        self.B_Connect.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.B_Connect.setFont(font)
        self.B_Connect.setObjectName("B_Connect")
        self.horizontalLayout_2.addWidget(self.B_Connect)
        self.B_Start = QtWidgets.QPushButton(self.layoutWidget2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.B_Start.sizePolicy().hasHeightForWidth())
        self.B_Start.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.B_Start.setFont(font)
        self.B_Start.setObjectName("B_Start")
        self.horizontalLayout_2.addWidget(self.B_Start)
        self.B_Reset = QtWidgets.QPushButton(self.layoutWidget2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.B_Reset.sizePolicy().hasHeightForWidth())
        self.B_Reset.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.B_Reset.setFont(font)
        self.B_Reset.setObjectName("B_Reset")
        self.horizontalLayout_2.addWidget(self.B_Reset)
        self.B_ListPilots = QtWidgets.QPushButton(self.layoutWidget2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.B_ListPilots.sizePolicy().hasHeightForWidth())
        self.B_ListPilots.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.B_ListPilots.setFont(font)
        self.B_ListPilots.setObjectName("B_ListPilots")
        self.horizontalLayout_2.addWidget(self.B_ListPilots)
        self.B_ListRounds = QtWidgets.QPushButton(self.layoutWidget2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.B_ListRounds.sizePolicy().hasHeightForWidth())
        self.B_ListRounds.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.B_ListRounds.setFont(font)
        self.B_ListRounds.setObjectName("B_ListRounds")
        self.horizontalLayout_2.addWidget(self.B_ListRounds)
        self.layoutWidget3 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget3.setGeometry(QtCore.QRect(20, 100, 431, 21))
        font = QtGui.QFont()
        font.setPointSize(7)
        self.layoutWidget3.setFont(font)
        self.layoutWidget3.setObjectName("layoutWidget3")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.layoutWidget3)
        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.radioButton = QtWidgets.QRadioButton(self.layoutWidget3)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.radioButton.setFont(font)
        self.radioButton.setObjectName("radioButton")
        self.horizontalLayout_3.addWidget(self.radioButton)
        self.radioButton_2 = QtWidgets.QRadioButton(self.layoutWidget3)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.radioButton_2.setFont(font)
        self.radioButton_2.setObjectName("radioButton_2")
        self.horizontalLayout_3.addWidget(self.radioButton_2)
        self.radioButton_3 = QtWidgets.QRadioButton(self.layoutWidget3)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.radioButton_3.setFont(font)
        self.radioButton_3.setObjectName("radioButton_3")
        self.horizontalLayout_3.addWidget(self.radioButton_3)
        self.pushButton_5 = QtWidgets.QPushButton(self.layoutWidget3)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.pushButton_5.setFont(font)
        self.pushButton_5.setObjectName("pushButton_5")
        self.horizontalLayout_3.addWidget(self.pushButton_5)
        self.lineEdit_9 = QtWidgets.QLineEdit(self.layoutWidget3)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.lineEdit_9.setFont(font)
        self.lineEdit_9.setReadOnly(True)
        self.lineEdit_9.setObjectName("lineEdit_9")
        self.horizontalLayout_3.addWidget(self.lineEdit_9)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 500, 18))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_4.setText(_translate("MainWindow", "Countdown:"))
        self.label_8.setText(_translate("MainWindow", "Race Time: "))
        self.label_5.setText(_translate("MainWindow", "Base A:"))
        self.label_6.setText(_translate("MainWindow", "Base B:"))
        self.label_7.setText(_translate("MainWindow", "Lap:"))
        self.HotSpotIP.setText(_translate("MainWindow", "Centre Box IP:"))
        self.BaseAIP.setText(_translate("MainWindow", "Base A IP:"))
        self.BaseBIP.setText(_translate("MainWindow", "Base B IP:"))
        self.B_Connect.setText(_translate("MainWindow", "Connect"))
        self.B_Start.setText(_translate("MainWindow", "Start"))
        self.B_Reset.setText(_translate("MainWindow", "Reset"))
        self.B_ListPilots.setText(_translate("MainWindow", "List Pilots"))
        self.B_ListRounds.setText(_translate("MainWindow", "List Rounds"))
        self.radioButton.setText(_translate("MainWindow", "Single"))
        self.radioButton_2.setText(_translate("MainWindow", "Continous"))
        self.radioButton_3.setText(_translate("MainWindow", "Beeper"))
        self.pushButton_5.setText(_translate("MainWindow", "Pilot"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
Vielen Dank!
Georg

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 17:18
von mp1337
Ich würde Dir raten die Datei als .ui zu speichern und in deiner PyQt5 Anwendung zu laden (Übersicht halber).

https://github.com/MP1337/PGEN_Simple_P ... master/src

Kannst in meiner Qt Anwendung schauen wie das funktioniert. Ich habe dort auch Textfeld welches ich befülle. lineStrongness.

Re: Countdown mit Ansage

Verfasst: Dienstag 22. September 2020, 19:36
von __blackjack__
@tschorsch: Das ist natürlich machbar, funktioniert aber komplett anders als ein Konsolenprogramm mit einer ``while``-Schleife und `time.sleep()`. Weil GUI-Programmierung anders funktioniert. Die ist ereignisbasiert. Das heisst man erstellt die GUI und verbindet Ereignisse mit Rückruffunktionen/-methoden die aufgerufen werden wenn das Ereignis eintritt. Ereignisse können das klicken auf Schaltflächen sein, aber auch das eine gewisse Zeit verstrichen ist — beispielsweise eine Sekunde. Wenn man alles soweit vorbereitet hat, ruft man die GUI-Hauptschleife auf und *die* steuert den weiteren Programmablauf und verträgt sich nicht mit lang laufenden Schleifen in Deinem Code. Die registrierten Rückrufe dürfen nur *kurz* etwas tun und dann die Kontrolle wieder an die GUI-Hauptschleife zurückgeben.

Wenn man bei Qt mit Theads arbeiten will, sollte man auch schauen ob es sinnvoll ist `QThread` statt dem `threading`-Modul zu verwenden. Dort kann man dann beispielsweise mit dem Signal/Slot-Prinzip von Qt statt mit eigenen Queues kommunizieren.

Das ``while``/`sleep()` kann man mit in Qt mit einem `QTimer` und einer Methode die *einen* Durchlauf der ``while``-Schleife darstellt, umsetzen.

Re: Countdown mit Ansage

Verfasst: Montag 28. September 2020, 11:11
von __blackjack__
Hier mal ein einfacher Countdown in Qt ohne Sprachausgabe:

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import (
    QApplication,
    QLabel,
    QPushButton,
    QVBoxLayout,
    QWidget,
)


class Countdown:
    def __init__(self):
        self._counter_value = None

        self.ui = QWidget()
        self.ui.setWindowTitle("Countdown")
        layout = QVBoxLayout()

        self.countdown_label = QLabel(alignment=Qt.AlignCenter)
        font = self.countdown_label.font()
        font.setPointSize(font.pointSize() * 3)
        font.setBold(True)
        self.countdown_label.setFont(font)
        
        layout.addWidget(self.countdown_label)

        self.start_countdown_button = QPushButton(
            "Starte Countdown", clicked=self.start
        )
        layout.addWidget(self.start_countdown_button)

        self.ui.setLayout(layout)

        self.counter_value = 0
        self.timer = QTimer(timeout=self.step)

    @property
    def counter_value(self):
        return self._counter_value

    @counter_value.setter
    def counter_value(self, value):
        self._counter_value = value
        self.countdown_label.setText(str(self.counter_value))

    def start(self):
        self.start_countdown_button.setEnabled(False)
        self.counter_value = 30
        self.timer.start(1000)

    def step(self):
        if self.counter_value > 0:
            self.counter_value -= 1
        else:
            self.timer.stop()
            self.start_countdown_button.setEnabled(True)


def main():
    app = QApplication(sys.argv)
    countdown = Countdown()
    countdown.ui.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()