Fried-rich
Anmeldungsdatum: 2. Mai 2013
Beiträge: 1093
|
Formatierter TextHi, wenn ich yad nutze um irgendetwas einzustellen war es immer so, dass ein Fenster sich auf tut, ich dort einstelle was auch immer eingestellt werden soll und dann OK oder Enter klicken. Die Werte gehen dann an das Skript und selbiges wird ausgeführt. Ich möchte jetzt ein Yad-Fenster dauerhaft offen lassen, dort soll z. B. ein Feld stehen wo ich einen Zahlenwert erhöhen oder senken kann. Im wiki gibt es ein Bsp. --field="Auswahl einer Zahl:NUM" Der wert soll mit jeder Änderung an das Skript über geben werden und das Skript soll ausgeführt werden. Das Fenster soll logischerweise offen bleiben. Ich bin hier erstmal dezent ohne plan wie man das umsetzen könnte. Evtl. mit eine Endlosschleife, die so lange die geänderten Werte die sich aus Änderungen des Feldes ergeben an ein zweites Skript schickt bis ich das Fenster über OK oder Abbrechen schließe?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Ich wüsste nicht, wie man yad dazu bringt Befehle mit Werten aus Feldern im Dialog aufzurufen, ohne den Dialog zu schließen. Einzelne Befehle kann man durchaus an Buttons binden, z.B.
| yad \
--title="Führe Skript aus" \
--form \
--item-separator=, \
--separator=" " \
--field="Auswahl einer Zahl:NUM" \
--button='Skript ausführen:echo "Hallo, Welt!"'
|
Was ginge, wäre eine Endlosschleife, die yad nach dem Beenden erneut startet und den letzten Wert als Vorauswahl ins Feld schreibt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | res=0
ret=0
while [ $ret -eq 0 ]
do
res=$(yad \
--title="Führe Skript aus" \
--form \
--item-separator=, \
--separator=" " \
--field="Auswahl einer Zahl":NUM $res,1..100,1 \
--button=gtk-cancel:1 \
--button='Skript ausführen':0)
ret=$?
[ $ret -eq 0 ] && echo "Wert war $res"
done
|
Wenn es komplexer wird (z.B. weil man will, dass man das Skript durch Drücken der Eingabetaste starten kann, wenn das Feld zur Aufwahl der Zahl den Fokus hat), würde ich dann langsam in Richtung GUI-Framework mit einer Skriptsprache im Hintergrund denken - z.B. mit Python3 und Gtk3 (ein Tutorial gibt es hier, eine ausführliche Beschreibung der Widgets hier: https://developer.gnome.org/pygtk/stable/gtk-class-reference.html - das ganze steckt im Paket python3-gi, zumindest beim Ubuntu Desktop ist das IIRC vorinstalliert) - das ginge z.B. so für die Auswahl einer ganzen Zahl zwischen 0 und 100 - wobei das in Zeile 36 aufgerufene Programm die Eingabe neuer Werte blockiert, bis es beendet wurde (wenn man das nicht will, könnte man mit Threads oder Multiprocessing arbeiten):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 | #!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
import subprocess
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Run a command")
grid = Gtk.Grid()
self.add(grid)
self.label = Gtk.Label(label="Choose a Value [0..100]:")
grid.add(self.label)
self.spinner = Gtk.SpinButton(climb_rate=1, digits=0)
self.spinner.set_increments(1, 10)
self.spinner.set_range(0, 100)
self.spinner.connect("key-press-event", self.on_keyboard_event)
grid.attach(self.spinner, 1, 0, 1, 1)
self.button = Gtk.Button(label="RUN")
self.button.connect("clicked", self.on_button_clicked)
grid.attach_next_to(self.button, self.label, Gtk.PositionType.BOTTOM, 2, 2)
def on_keyboard_event(self, widget, event):
if event.keyval == Gdk.KEY_Return:
self.spinner.update()
self.button.clicked()
def on_button_clicked(self, widget):
subprocess.run(["echo", "current value is", str(self.spinner.get_value_as_int())])
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
|
|
TNTMaster
Anmeldungsdatum: 30. Juli 2009
Beiträge: 851
|
Du könntest den scale Dialog von yad benutzen, den du dann als zusätzliches Fenster öffnest. Der gibt jede Änderung am Regler sofort auf stdout aus. Kleines Beispiel zum Starten im Terminal:
yad --scale --always-print-result --print-partial --step=1 --min-value=0 --max-value=100 --mark=0:0 --mark=100:100
Im Script kannst du yad mit & in den Hintergrund schicken und wie in yad (Abschnitt „Menuedialog“) mithilfe einer Pipe die Ausgabe im Script verwerten.
|
Fried-rich
(Themenstarter)
Anmeldungsdatum: 2. Mai 2013
Beiträge: 1093
|
--scale ist als Auswahlwerkzeug schon recht grob. Mit pipe hab ich einmal was gemacht, aber halt nur in einer Notification, nicht mit einem Fenster. So 100%ig hab ich das damals nicht verstanden. Wäre es möglich mit Pipe bei Verwendung von --field="Auswahl einer Zahl:NUM" das hinzubiegen was mir vorschwebt? @ seahawk1986 Das ist schon etwas komplexer, das guck ich mir mal an.
|
TNTMaster
Anmeldungsdatum: 30. Juli 2009
Beiträge: 851
|
--scale ist als Auswahlwerkzeug schon recht grob.
Kommt darauf an, wie weit min. und max. auseinander liegen. Mit --inc-buttons werden "+" und "-" Buttons eingeblendet, das kommt dem :NUM Feld schon näher. Wäre es möglich mit Pipe bei Verwendung von --field="Auswahl einer Zahl:NUM" das hinzubiegen was mir vorschwebt?
Wenn du yad dazu bringst, den Wert sofort auszugeben, dann ja. Ich wüßte nicht wie. Mit pipe hab ich einmal was gemacht, aber halt nur in einer Notification, nicht mit einem Fenster. So 100%ig hab ich das damals nicht verstanden.
Ich habe ein Beispiel erstellt, das zeigt, wie du den --scale Dialog im Skript verwenden kannst. Da dieser Dialog alle (Zwischen)Werte sofort ausgibt, wenn man den Regler verschiebt(will man i.d.R. nicht), habe ich eine Verzögerung eingebaut. Der Wert wird erst ausgegeben, wenn er mind. 3 Sekunden lang nicht verstellt wurde. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | #!/bin/bash
function yad_scale(){
pipe=$(mktemp -u)
mkfifo $pipe
exec 3<>$pipe
yad --scale --print-partial --inc-buttons --step=1 --min-value=0 --max-value=100 --mark=0:0 --mark=100:100 >&3 &
pid=$!
while ps $pid >/dev/null; do
# Wenn 3 Sekunde lang keine Daten von yad (<&3) kommen,
# wird aktueller Wert ausgegeben,
# falls er sich vom vorherigen unterscheidet
if read -t 3 input <&3; then
wert="$input"
else
if [ -n "$wert" -a "$wert" != "$wert_alt" ]; then
echo "$wert"
wert_alt="$wert"
unset wert
fi
fi
done
exec 3>&-
rm $pipe
}
cat < <(yad_scale)
|
|
TNTMaster
Anmeldungsdatum: 30. Juli 2009
Beiträge: 851
|
Ich habe noch ein wenig mit den Optionen von yad rumprobiert und einen --form Dialog mit 2 Buttons (+ und -) neben einer Textbox mit dem Zahlenwert erstellt. Beim Drücken auf "+" oder "-" wird der Zahlenwert um 1 geändert und auf stdout ausgegeben. Das entspricht wohl eher deinen Vorstellungen. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | #!/bin/bash
function yad_num(){
pipe=$(mktemp -u)
mkfifo $pipe
exec 3<>$pipe
### Werte an yad senden
### Für jede --field Option muß ein Wert gesendet werden
### Reihenfolge beachten, Werte jeweils mit Zeilenumbruch (\n) getrennt!
### z.B.: "echo -%2" ist der Befehl, der beim Drücken
### des "-" Buttons (Feld 4) ausgeführt wird. "%2" wird dabei
### mit dem Inhalt von Feld 2 (Zahlenwert) ersetzt
startwert=0
echo -e "\f\n\n$startwert\n\necho -%2\n\necho +%2" >&3
yad --form --columns=3 --cycle-read --focus-field=2 --button=gtk-cancel \
--field="Auswahl einer Zahl":LBL \
--field= \
--field=:LBL \
--field="-":BTN \
--field=:LBL \
--field="+":BTN <&3 \
| while read wert; do
[[ "$wert" =~ ^[+-]{1,2}[0-9]+$ ]] || continue
zeichen="${wert:0:1}"
zahl="${wert:1}"
wert_neu=$(($zahl $zeichen 1))
echo "$wert_neu"
echo -e "\f\n\n$wert_neu\n\necho -%2\n\necho +%2" >&3
done
exec 3>&-
rm $pipe
}
yad_num
|
|
TNTMaster
Anmeldungsdatum: 30. Juli 2009
Beiträge: 851
|
Hier noch eine leicht abgeänderte Variante meines letzten Skripts mit einem zusätzlichen Button "OK", der den angezeigten Zahlenwert auf stdout ausgibt. Beim Drücken auf "+" oder "-" wird der Wert zwar im yad Dialog geändert, aber nicht ausgegeben.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | #!/bin/bash
function yad_num(){
pipe=$(mktemp -u)
mkfifo $pipe
exec 3<>$pipe
### Werte an yad senden
### Für jede --field Option muß ein Wert gesendet werden
### Reihenfolge beachten, Werte jeweils mit Zeilenumbruch (\n) getrennt!
### z.B.: "echo -%2" ist der Befehl, der beim Drücken
### des "-" Buttons (Feld 4) ausgeführt wird. "%2" wird dabei
### mit dem Inhalt von Feld 2 (Zahlenwert) ersetzt
startwert=0
echo -e "\f\n\n$startwert\n\necho -%2\n\necho +%2\n\necho =%2" >&3
yad --form --columns=4 --cycle-read --focus-field=2 --button=gtk-cancel \
--field="Auswahl einer Zahl":LBL \
--field= \
--field=:LBL \
--field="-":BTN \
--field=:LBL \
--field="+":BTN \
--field=:LBL \
--field="OK":BTN <&3 \
| while read wert; do
[[ "$wert" =~ ^[+-=][+-]{0,1}[0-9]+$ ]] || continue
zeichen="${wert:0:1}"
zahl="${wert:1}"
zahl="${zahl#+}"
if [ "$zeichen" = "=" ]; then
wert_neu="$zahl"
echo "$wert_neu"
else
wert_neu=$(($zahl $zeichen 1))
fi
echo -e "\f\n\n$wert_neu\n\necho -%2\n\necho +%2\n\necho =%2" >&3
done
exec 3>&-
rm $pipe
}
yad_num
|
|
Fried-rich
(Themenstarter)
Anmeldungsdatum: 2. Mai 2013
Beiträge: 1093
|
Ja, das geht so. Soweit ich das korrekt verstehe wird der Wert an stdout des Skriptes übergeben. Kann man dann den Wert gleich wieder an einen Command übergeben, der dann sozusagen "live" mit dem gerade aktuellen Wert ausgeführt wird?
|
TNTMaster
Anmeldungsdatum: 30. Juli 2009
Beiträge: 851
|
Kann man dann den Wert gleich wieder an einen Command übergeben
Ja, indem du in Zeile 32 deinen Befehl schreibst, der Wert ist in der Variable $wert_neu gespeichert. Was ich bisher total übersehen habe: Das läßt sich auch viel einfacher mit dem NUM-Feld selbst verwirklichen, da kann man sich die Pipe und die Rechnerei in Bash sparen. Der eingestellte Wert wird mit Klick auf "Start" an die Funktion cmd übergeben. Als Beispiel habe ich hier Startwert: 5, min. Wert: 2, max. Wert:10, Schrittweite: 1. Wenn du für's NUM-Feld keine Startbedingung festlegst, mußt du ein leeres Argument übergeben: "" (2 Double-Quotes). Dein Befehl kommt in die Funktion cmd (in Zeile 11 statt yad --text= ...) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/bin/bash
function yad_num(){
yad --form --columns=2 --button="Beenden!gtk-cancel":1 \
--field="Auswahl einer Zahl":NUM "5!2..10!1" \
--field="Start":FBTN "bash -c 'cmd %1'"
}
function cmd(){
wert=$1
yad --text="Der Wert ist: $wert"
}
export -f cmd
yad_num
|
|