Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
derampcsitzt
Anmeldungsdatum: 25.12.2020 Beiträge: 14
|
Verfasst am: 28.11.2021, 19:04 Titel: Dauerschleifen -> Tastaturabfragen -> ich bin zu blöd |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Sebastian Administrator
![](images/avatars/563932275488e4d20c5ee9.jpg)
Anmeldungsdatum: 10.09.2004 Beiträge: 5969 Wohnort: Deutschland
|
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
derampcsitzt
Anmeldungsdatum: 25.12.2020 Beiträge: 14
|
Verfasst am: 28.11.2021, 20:50 Titel: |
|
|
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
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....](images/smiles/icon_hm.gif) |
|
Nach oben |
|
![](templates/subSilver/images/spacer.gif) |
nemored
![](images/avatars/18585278245ddb8b9d8710.png)
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 28.11.2021, 22:05 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 29.11.2021, 21:13 Titel: |
|
|
Typischer Fall von "Übersicht verloren".
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 |
|
![](templates/subSilver/images/spacer.gif) |
nemored
![](images/avatars/18585278245ddb8b9d8710.png)
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 30.11.2021, 00:32 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
SpionAtom
Anmeldungsdatum: 10.01.2005 Beiträge: 338
|
Verfasst am: 30.11.2021, 09:29 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
SpionAtom
Anmeldungsdatum: 10.01.2005 Beiträge: 338
|
Verfasst am: 30.11.2021, 11:21 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 30.11.2021, 11:41 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
SpionAtom
Anmeldungsdatum: 10.01.2005 Beiträge: 338
|
Verfasst am: 30.11.2021, 15:15 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
dreael Administrator
![](images/avatars/112279543641421ec80e8e2.gif)
Anmeldungsdatum: 10.09.2004 Beiträge: 2507 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 30.11.2021, 22:58 Titel: |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 30.11.2021, 23:58 Titel: |
|
|
@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 |
|
![](templates/subSilver/images/spacer.gif) |
|