Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Dauerschleifen -> Tastaturabfragen -> ich bin zu blöd

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
derampcsitzt



Anmeldungsdatum: 25.12.2020
Beiträge: 14

BeitragVerfasst am: 28.11.2021, 18:04    Titel: Dauerschleifen -> Tastaturabfragen -> ich bin zu blöd Antworten mit Zitat

Hoi!

Ich habe ja schon einige QBasic Programme hinter mir und lese immer was ich brauche. Aber ich komme immer bei größeren Projekten an den Punkt dass ich meine Dauerschleifen nicht mit einer INKEY&-Abfrage beendet bekomme.

Standardmässig geht's ja so:

Code:
Do while taste$ <> "z"
     taste$ = inkey$
----Hauptprogramm Anfang----
case select taste$
       case "u"
               call sub ...
       case "t"
               call sub ...
.
.
.
.
----Hauptprogramm Ende----
end select

loop




Jetzt habe ich grade ein Programm in dem ich mit vielen For..next und Do...loop Schleifen arbeite, da wird dann aus dem Hauptprogramm eine Sub aufgerufen welche ebenfalls eine Schleife beinhaltet in der wiederum eine weitere Sub mit Schleife aufgerufen wird. Der Nutzer soll dann mit Tastendruck zurück ins Hauptmenü.
(Ich gebe Signale über die LPT-Schnittstelle an eine 3-stellige 7-Segmentanzeige aus welche Multiplext wird und ständig aktualisiert werden muss )

Bin jedes mal am probieren bis ich die Tastenabfrage zuverlässig in die Schleifen rein bekomme aber jetzt soweit dass ich bei einigen nicht weiter komme bei den Schleifen die schnell in einer Dauerschleife ablaufen...
Macht man am besten "Do while...." oder eher "Loop until"....usw....

Is mir echt peinlich die Frag, hab jetzt so tollen Mist hinbekommen bei der Anzeige mit Laufschrift usw...

Servus
Markus
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 28.11.2021, 18:09    Titel: Antworten mit Zitat

Hallo!

Wird denn in den SUBs vielleicht irgendwo der Tastaturpuffer geleert, indem INKEY$ ausgelesen wird?
Oder wird vielleicht bspw. mit INPUT eine Tastatureingabe eingefordert, während der die INKEY-Abfrage aus der Hauptschleife natürlich nicht reagieren kann?

Viele Grüße!
Sebastian
_________________

Der Markt regelt das! | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
derampcsitzt



Anmeldungsdatum: 25.12.2020
Beiträge: 14

BeitragVerfasst am: 28.11.2021, 19:50    Titel: Antworten mit Zitat

Neee, hatte paar falsche Namen eingegeben. Aber mein Problem ist nach wie vor dass ich an manchen Stellen zwar aus der Schleife raus komme aber dafür lange die entsprechende Taste drücken muss. Alles etwas chaotisch im Moment, mir ist nicht ganz klar wann ich wo die Schleifen richtig setzen muss.

Zum Beispiel habe ich das Hauptprogramm als Dauerschleife (bei Inkey$ = ESC wird Programm mit "end" beendet)
In dieser Schleife wird dann die SUB für die Darstellung des Hauptmenüs auf dem Bildschirm aufgerufen, da wiederum wird eine SUB für die Ausgabe einer Laufschrift am LPT-.Port aufgerufen (in welcher wider einige SUB's für die Berechnung dergleichen nötig sind).

In der Laufschrift-SUB läuft aber eine längere Schleife (bis eben der Text durch gewandert ist) und diese schaffe ich nicht ordentlich per Tastendruck zu beenden. Problem weiter ist wohin geht es dann? Zurück ins Hauptmenü wobei diese Laufschrift-SUB ja sofort wieder aufgerufen wird durchgeknallt

Oder anders erklärt: Im Hauptmenü habe ich meine Select-Case abfragen um in die jeweiligen Untermenüs zu kommen - allerdings befindet sich während des Hauptmenüs das Programm meistens in der Schleife vom Laufschrift-SUB wodurch ich nicht mehr auf die Menüabfrage zugreifen kann ->> man kommt nicht in die Untermenüs.

EDIT: JEtzt wo ich meine eigenen Text so durchlese: Ich müsste eigentlich den Inhalt der Laufschrift-SUB einfach mit ins Hauptmenü packen dass das als eine einzige Schleife abläuft Hmmm....
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 28.11.2021, 21:05    Titel: Antworten mit Zitat

Für eine genauere Fehlerdiagnose wäre ein (möglichst kurzes) Programm hilfreich, in dem das Problem auftritt.

Zu den SUBs ein Vorschlag:
Wenn du statt einer SUB eine FUNCTION verwendest, kannst du als Rückgabewert mitgeben, ob in der FUNCTION alles ordungsgemäß abgelaufen ist. Dann kannst du z. B. in der FUNCTION ein Escape-Zeichen abfangen und mit einem Rückgabewert beenden, welche den Abbruch durch Escape symbolisiert - das Hauptprogramm prüft dann diesen Rückgabewert und reagiert entsprechend (z. B. bei Escape durch das Beenden des Programms).

Für die Laufschrift (wenn du sie in eine SUB auslagern willst) wäre es günstiger, sie immer nur ein Zeichen verschieben zu lassen und dann gleich wieder zurückzugeben - in QBasic müsste die Anweisung STATIC ja funktionieren.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 29.11.2021, 20:13    Titel: Antworten mit Zitat

Typischer Fall von "Übersicht verloren". grinsen

In FB könnte man das mit Multithreading lösen. In QB habe ich das früher so gemacht, daß ich alle periodischen Aktionen, in deinem Fall also die Laufschriftausgabe und die Tastaturabfrage, in eine Funktion gepackt habe, die dann im Programm von verschiedenen Stellen aus (möglichst gleichmäßig und periodisch) aufgerufen wurde. So war sichergestellt, daß die Tastatur immer nur an einer Stelle abgefragt wurde und sich nicht mehrere Abfragen gegenseitig blockieren konnten.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 29.11.2021, 23:32    Titel: Antworten mit Zitat

In QBasic gäbe es ja ON TIMER GOSUB, ich kann jetzt allerdings nicht beurteilen, ob es in diesem Fall empfehlenswert ist. Die ganzen GOSUB-Sachen kenne ich nur aus den ganz frühen Anfängen meiner Programmierer-Laufbahn (damals, als QBasic noch neu war ...).
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
SpionAtom



Anmeldungsdatum: 10.01.2005
Beiträge: 338

BeitragVerfasst am: 30.11.2021, 08:29    Titel: Antworten mit Zitat

Wenn in deiner Hauptschleife nichts groß berechnet wird nebenbei, würde ich die Tastatureingabe gar in eine eigene Schleife packen:

Code:
Local taste$ = "", ende = False

While Not ende

   Repeat
      taste$ = Chr(GetKey())
   Until taste$ <> ""
   
   Select taste$
      Case Chr(27): ende = True ;escape beendet
      Case "u": Print "U eingegeben"
      Case "t": Print "T eingegeben"
   End Select
   
Wend
End

(Ist zwar Blitzbasic, aber sollte man trotzdem lesen können)
_________________
Inzwischen gehöre ich auch zu den BlitzBasicern. Also verzeiht mir, wenn mir mal ein LOCATE 100, 100 oder dergleichen rausrutscht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
SpionAtom



Anmeldungsdatum: 10.01.2005
Beiträge: 338

BeitragVerfasst am: 30.11.2021, 10:21    Titel: Antworten mit Zitat

Leute, ich hab mal wieder die Dosbox angeschmissen, und ein wenig gecodet!!!

mit + und - kann man die Geschwindigkeit anpassen
mit Esc beendet man das Programm.

Code:
DECLARE FUNCTION Laufschrift% (text$, zeile%, von%, bis%, position%)
CLS
INPUT "Gib deinen Namen ein: ", name$
IF name$ = "" THEN END

        speed% = 5
        ende% = 0
        CLS
        DO
                'Eingabe
                taste$ = INKEY$
                IF taste$ = CHR$(27) THEN ende% = 1
                IF taste$ = "+" THEN IF speed% < 10 THEN speed% = speed% + 1
                IF taste$ = "-" THEN IF speed% > 1 THEN speed% = speed% - 1
               
                'Ausgabe
                LOCATE 1, 1: PRINT "Geschwindigkeit:"
                LOCATE 1, 18: PRINT speed%; " "

                LOCATE 10, 19: PRINT "*"
                LOCATE 10, 61: PRINT "*"

                IF sz! + (10 - speed%) / 10! < TIMER THEN
                        sz! = TIMER
                        LF1% = Laufschrift%(name$, 10, 20, 60, LF1%)
                END IF
                LOCATE 2, 1: PRINT LF1%; TIMER; sz! + (speed% * 10) / 10!

        LOOP UNTIL ende% = 1
        END

FUNCTION Laufschrift% (text$, zeile%, von%, bis%, position%)

        'unsinnige Eingaben abfangen
        IF text$ = "" THEN RETURN
        IF zeile% < 1 THEN zeile% = 1
        IF zeile% > 25 THEN zeile% = 25
        IF von% < 1 THEN von% = 1
        IF von% > 80 THEN von% = 80
        IF bis% < von% THEN bis% = von%
        IF bis% > 80 THEN bis% = 80
       
        IF position% >= 0 THEN p% = position% ELSE p% = 0
        FOR p% = 1 TO LEN(text$)
                IF von% + position% + p% >= von% AND von% + position% + p% <= bis% THEN
                        LOCATE zeile%, von% + position% + p%
                        PRINT MID$(text$, p%, 1)
                END IF
        NEXT
       
        'Clear
        IF von% + position% + p% <= bis% THEN LOCATE zeile%, von% + position% + p%: PRINT " "

        'Return
        returnValue% = position% - 1
        IF returnValue% < -LEN(text$) - 1 THEN returnValue% = bis% - von%
        Laufschrift% = returnValue%

END FUNCTION




_________________
Inzwischen gehöre ich auch zu den BlitzBasicern. Also verzeiht mir, wenn mir mal ein LOCATE 100, 100 oder dergleichen rausrutscht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 30.11.2021, 10:41    Titel: Antworten mit Zitat

nemored hat Folgendes geschrieben:
In QBasic gäbe es ja ON TIMER GOSUB, ich kann jetzt allerdings nicht beurteilen, ob es in diesem Fall empfehlenswert ist.

Eher nicht. Das Zeitintervall lässt sich nur in Sekundenschritten einstellen, Minimum ist 1 Sekunde. Damit dürfte ein vernünftiges Arbeiten kaum möglich sein.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
SpionAtom



Anmeldungsdatum: 10.01.2005
Beiträge: 338

BeitragVerfasst am: 30.11.2021, 14:15    Titel: Antworten mit Zitat

in meinem Beispielprogramm benutze ich TIMER, um wenigstens auf Zehntel-Sekunden zu kommen.

Die Idee bei mir ist, dass ich keine Pausen einbaue. Denn es sind die Pausen, die die Eingaben zum stocken bringen.
Vielmehr nutze ich dem TIMER Befehl, und bei jedem Main-Loop-Durchlauf zu schauen, ob es Zeit für ein Update der Laufschrift ist.

So erreiche ich, dass die Main-Loop so schnell durchläuft wie es geht, die Eingabe also stets abgefragt wird, aber trotzdem die Laufschrift ausgebremst wird.
_________________
Inzwischen gehöre ich auch zu den BlitzBasicern. Also verzeiht mir, wenn mir mal ein LOCATE 100, 100 oder dergleichen rausrutscht.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2507
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 30.11.2021, 21:58    Titel: Antworten mit Zitat

Ein Stichwort muss auch genannt werden: Multitasking! Heisst: So eine INKEY-Schleife sollte noch um SLEEP ergänzt werden, sodass, wenn das Programm auf einen Tastendruck wartet, nicht unnötig CPU zieht.

Sonst ist der Akku am Notebook entsprechend schnell leer, wenn darauf das FB-Programm im Batteriebetrieb gestartet wird.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 30.11.2021, 22:58    Titel: Antworten mit Zitat

@dreael: Es ist ein QB - Programm, nicht FB. In FB wäre das Timingproblem ganz einfach mit einem gesonderten Thread zu lösen.

@derampcsitzt: Auf welchem Betriebssystenm läuft dein Programm? Das Ansteuern der LPT - Schnittstelle ist seit XP ja nicht mehr ganz so einfach.

Gruß
grindstone

EDIT: Ich bin da gerade über einen Thread im internationalen Forum gestolpert. Vielleicht ist Multitasking ja doch eine Option.
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz