CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

For discussions about programming, and for programming questions and advice


Moderator: Forum moderators

Post Reply
ozboomer
Posts: 106
Joined: Sun Dec 20, 2020 12:49 am
Location: Blackburn, Australia
Has thanked: 16 times
Been thanked: 17 times

CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by ozboomer »

Hi, again...

The NEXT chapter of hours of study and experimenting and getting nowhere... Heck.

I have a checkbox... and it's bound to the variable, CB_STATE. A label is bound to a different variable. LABEL_TEXT.

As the state of the checkbox is toggled, I want the text in LABEL_TEXT to change, which I'm also trying to reflect in the label widget's text... but it's not doing anything (although I can detect the change of state, but the "changed" signal doesn't seem to be issued/recognized).

I've tried using "signals", I've tried examining truth values, I've tried different ways of specifying the variables associated with each widget... I'm not sure if "refresh" and "update" need to be called on something... but nothing seems to be working as I'd expect.

Again, I'd appreciate any suggestions on the following code... as the 'manual' and 'examples' are all just a blur now, as I've been buried in them far too long...

Once more, it's Fossapup64 9.5... and gtkdialog v0.8.4.

Thanks a heap.

Code: Select all

#!/bin/bash

LABEL_TEXT="{Start}"

export GUI="
<window resizable=\"true\""> 
   <vbox>
      <checkbox space-expand=\"true\" space-fill=\"true\" xalign=\"0\">
         <label>/mnt/sdb1</label>
         <default>true</default>
         <variable>CB_STATE</variable>
         <action>if true echo checkbox is TRUE</action>
         <action>if true CB_STATE=\"TRUE\"</action>
         <action>if false echo checkbox is FALSE</action>
         <action>if false CB_STATE=\"FALSE\"</action>
         <action>echo CB_STATE=$CB_STATE</action>
         <action>echo LABEL_TEXT=$LABEL_TEXT</action>
      </checkbox>

      <text>
         <label>$LABEL_TEXT</label>
         <variable>LABEL_TEXT</variable>
         
      </text>
      
   </vbox>

</window>
"

gtkdialog3 --program=GUI --center

exit 0

Daily Use Puppies: F96-CE (migrating), Xenial64 7.5, Slacko 6.3.2... Proud Puppy enthusiast since 2004
C, Perl, cmd/DCL/bash... for sysadmin, CLI tools... under DOS, Windoze, VMS, Linux... on PC, VAX... for 45+ years... :roll:

HerrBert
Posts: 365
Joined: Mon Jul 13, 2020 6:14 pm
Location: Germany, NRW
Has thanked: 19 times
Been thanked: 135 times

Re: CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by HerrBert »

Quick and dirty:

Code: Select all

#!/bin/bash

export GUI="
<window resizable=\"true\"> 
   <vbox>
      <checkbox space-expand=\"true\" space-fill=\"true\" xalign=\"0\">
         <label>/mnt/sdb1</label>
         <default>true</default>
         <variable>CB_STATE</variable>
         <action>if true echo checkbox is TRUE</action>
         <action>if false echo checkbox is FALSE</action>
         <action>echo CB_STATE=\$CB_STATE</action>
         <action>refresh:LABEL_TEXT</action>
      </checkbox>

      <text>
         <variable>LABEL_TEXT</variable>
         <input>[[ \$CB_STATE = false ]] && echo {Stop} || echo {Start}</input>
      </text>
      
   </vbox>

</window>
"

gtkdialog3 --program=GUI --center

exit 0

[edit] removed some unnecessary code - kept echoing for debugging. Copy 'n paste was always a bad idea ;)

ozboomer
Posts: 106
Joined: Sun Dec 20, 2020 12:49 am
Location: Blackburn, Australia
Has thanked: 16 times
Been thanked: 17 times

Re: CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by ozboomer »

Thanks for your suggestion, @HerrBert, as it's helped a lot.

I've progressed a little during this past 5+ hours (I am sooo slow)... but some points of note first...

  • I changed the 'GUI' variable/XML string definition to the 'single quote' format; it simplifies some of the double-quote escaping required and seems to be the more common way of doing these things ( for example, see https://github.com/oshazard/gtkdialog/b ... x_advanced )

  • I changed the truth state of the test just because I like 'true' (or more common/frequent) before 'false' (trivial).

  • I included a particular form of "ok" and "cancel" buttons as otherwise, the variables used in the dialog don't seem to be available after the 'gtkdialog' call.

  • I also changed the actual call to 'gtkdialog' so that it returns its defined variables in another variable so I can use those values later.

  • There seems to be some sort of bug in how the (text) label value is returned in its variable, as it always adds a space (0x20) to whatever's contained in the variable bound to the text widget. (I verified this using hexdump -C on the output and it's definitely a space).

The next thing that I can't get anywhere with is how the updating of the text label via a function call can be done. This will let me manipulate some variables when the checkbox is toggled and update the text label accordingly.

Heck! this stuff is complicated. :? It further reinforces to me how valuable good, complete & accessible documentation with examples can be...

Code: Select all

#!/bin/bash

function set_desc () {
   if [[ $CB_STATE = true ]]; then
      echo ENABLED
   else
      echo DISABLED
   fi
}

export GUI='
<window> 
   <vbox>
      <checkbox>
         <label>Include Info</label>
         <default>false</default>
         <variable>CB_STATE</variable>
         <action>refresh:LABEL_TEXT</action>
      </checkbox>

      <text>
         <variable>LABEL_TEXT</variable>
         <input>[[ $CB_STATE = true ]] && echo ENABLED || echo DISABLED</input>
      </text>
      
      <hbox> 
         <button> 
            <input file icon="gtk-media-play"></input> 
            <label>Ok</label> 
         </button> 
         
         <button> 
            <input file icon="gtk-quit"></input> 
            <label>Cancel</label> 
         </button> 
      </hbox>

   </vbox>


</window>
'

VAR_LIST=`gtkdialog3 --program=GUI --center`
echo VAR_LIST: $VAR_LIST

exit 0

Daily Use Puppies: F96-CE (migrating), Xenial64 7.5, Slacko 6.3.2... Proud Puppy enthusiast since 2004
C, Perl, cmd/DCL/bash... for sysadmin, CLI tools... under DOS, Windoze, VMS, Linux... on PC, VAX... for 45+ years... :roll:

HerrBert
Posts: 365
Joined: Mon Jul 13, 2020 6:14 pm
Location: Germany, NRW
Has thanked: 19 times
Been thanked: 135 times

Re: CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by HerrBert »

ozboomer wrote: Fri Sep 01, 2023 9:10 am

...

  • There seems to be some sort of bug in how the (text) label value is returned in its variable, as it always adds a space (0x20) to whatever's contained in the variable bound to the text widget. (I verified this using hexdump -C on the output and it's definitely a space).

The next thing that I can't get anywhere with is how the updating of the text label via a function call can be done. This will let me manipulate some variables when the checkbox is toggled and update the text label accordingly.

echo adds a newline to the string which results in a space at the end.
Try echo -n STRING to remove trailing space.

A variable or function needs to be exported to become available to a running gtkdialog program.
If you define a function for bash (which is the case here) you normally don't use the keyword function and empty parentheses ()

Code: Select all

#!/bin/bash

func_set_desc() {
   if [[ $CB_STATE = true ]]; then
      echo -n CHECKED
   else
      echo -n UNCHECKED
   fi
}
export -f func_set_desc

export GUI='
<window> 
   <vbox>
      <checkbox>
         <label>Include Info</label>
         <default>false</default>
         <variable>CB_STATE</variable>
         <action>refresh:LABEL_TEXT</action>
         <action>refresh:FUNC_TEXT</action>
      </checkbox>

      <text>
         <variable>LABEL_TEXT</variable>
         <input>[[ $CB_STATE = true ]] && echo -n ENABLED || echo -n DISABLED</input>
      </text>
      
      <text>
         <variable>FUNC_TEXT</variable>
         <input>func_set_desc</input>
      </text>
      
      <hbox> 
         <button> 
            <input file icon="gtk-media-play"></input> 
            <label>Ok</label> 
         </button> 
         
         <button> 
            <input file icon="gtk-quit"></input> 
            <label>Cancel</label> 
         </button> 
      </hbox>

   </vbox>

</window>
'

VAR_LIST=`gtkdialog3 --program=GUI --center`
echo VAR_LIST: $VAR_LIST

exit 0
User avatar
MochiMoppel
Posts: 1298
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 22 times
Been thanked: 480 times

Re: CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by MochiMoppel »

ozboomer wrote: Fri Sep 01, 2023 9:10 am

There seems to be some sort of bug in how the (text) label value is returned in its variable, as it always adds a space (0x20) to whatever's contained in the variable bound to the text widget. (I verified this using hexdump -C on the output and it's definitely a space).

No, it's definitely a linefeed (0x0A)
gtkdialog returns your LABEL_TEXT variable with a linefeed. As HerrBert mentioned you can prevent this with echo -n
The space you are seeing in your output stems from your command echo VAR_LIST: $VAR_LIST. If you don't enclose $VAR_LIST with double quotations the echo command will remove leading and trailing whitespaces and turn all remaining whitespaces (i.e. spaces, linefeeds (!), tabs) into single spaces. To preserve whitespaces you should use echo VAR_LIST: "$VAR_LIST" or better echo "VAR_LIST: $VAR_LIST"

ozboomer
Posts: 106
Joined: Sun Dec 20, 2020 12:49 am
Location: Blackburn, Australia
Has thanked: 16 times
Been thanked: 17 times

Re: CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by ozboomer »

The next episode...

Granted, I'm not super flash with shell scripts... but this is doing my head in.

Regarding the attached script, a number of things puzzle me :? :

  • When the dialog is displayed, the radio buttons are in the 'required' state as they are forced that way in the code (default=true/false)... but the text shown (the 'DISK_TEXT' variable) is the 'passthrough' value in its 'input' function. This says to me that the function calls specified in the dialog definition are all called once on gtkdialog startup. Otherwise, the text should've been 'start', the last value (the exported) DISK_TEXT was assigned before the gtkdialog call.

  • As each radio button is selected, the 'dupdate' function is updating DISK_TEXT Ok, as it's being displayed 'as expected' in the dialog... except that the 3rd radiobutton (OP3 variable) has been coded to illustrate that the 'disks' array is unknown, even though it's been exported from the mainline. I've tried different 'forms' of quoting the array element... but even writing every element to a file shows that the array is empty inside the 'dupdate' function.

  • Aditionally, the DISK_TEXT variable that is being manipulated in gtkdialog is clearly different from the exported variable in the mainline (and perhaps partly explains why the 'disks' array is unknown); the DISK_TEXT variable that is returned to the mainline environment by the call to gtkdialog is only a string (that you can capture) and is not the DISK_TEXT variable in the mainline, as its value before and after the gtkdialog call is unchanged.

Thanks again for any light that can be shed on all of this...

Code: Select all

#!/bin/sh
# rb2.sh - radiobuttons doing the updating
#

export disks=("sda1" "sdb2" "sdd3") # 'export' should make it known when gtkdialog runs...?
export DISK_TEXT=""

dupdate () {
   if [[ $OP1 = true ]]; then
#      DISK_TEXT="${disks[0]}"
      DISK_TEXT="1"
      
   elif [[ $OP2 = true ]]; then
#      DISK_TEXT="${disks[1]}"
      DISK_TEXT="2"
   
   elif [[ $OP3 = true ]]; then  # Why is disks() unknown?
      if [[ "${disks[2]}" -eq "" ]]; then
         DISK_TEXT="disks() unknown"
      else  
         DISK_TEXT="${disks[2]}"  
      fi
#      DISK_TEXT="3"

   else
      DISK_TEXT="none"
      
   fi

   echo -n "$DISK_TEXT"

}
export -f dupdate

# ----

DISK_TEXT="start"  # Won't be used in the initial dialog..
                   # ..as the 'function' on a widget is always..
                   # ..run on gtkdialog start... Is it?

export MAIN_DIALOG='
<window width-request="220" title="More Puzzles"> 
   <vbox>
      <radiobutton>
         <variable>OP1</variable>
         <default>true</default>
         <label>'"${disks[0]}"'</label>
         <action>refresh:DISK_TEXT</action>
      </radiobutton>
           
      <radiobutton>
         <variable>OP2</variable>
         <default>false</default>
         <label>'"${disks[1]}"'</label>
         <action>refresh:DISK_TEXT</action>
      </radiobutton>
           
      <radiobutton>
         <variable>OP3</variable>
         <default>false</default>
         <label>'"${disks[2]}"'</label>
         <action>refresh:DISK_TEXT</action>
      </radiobutton>
   
      <hseparator></hseparator>
   
      <text>
         <variable>DISK_TEXT</variable>
         <input>dupdate</input>
      </text>

      <hseparator></hseparator>

      <button> 
         <label>Ok</label> 
         <action function="exit">Exit</action>
      </button> 
   
   </vbox>
   
</window>
'

echo "--- PRE DIALOG ---"
echo "DISK_TEXT = '$DISK_TEXT' prior to dialog entry"
gtkdialog --program=MAIN_DIALOG --geometry=+200+200
echo "--- POST DIALOG ---"

echo "DISK_TEXT = '$DISK_TEXT' on dialog exit"

exit 0

Daily Use Puppies: F96-CE (migrating), Xenial64 7.5, Slacko 6.3.2... Proud Puppy enthusiast since 2004
C, Perl, cmd/DCL/bash... for sysadmin, CLI tools... under DOS, Windoze, VMS, Linux... on PC, VAX... for 45+ years... :roll:

HerrBert
Posts: 365
Joined: Mon Jul 13, 2020 6:14 pm
Location: Germany, NRW
Has thanked: 19 times
Been thanked: 135 times

Re: CLI gtkdialog: Troubles with Defining Variable(s) with Checkbox State Change

Post by HerrBert »

ozboomer wrote: Thu Sep 07, 2023 11:55 am

...

  • When the dialog is displayed, the radio buttons are in the 'required' state as they are forced that way in the code (default=true/false)... but the text shown (the 'DISK_TEXT' variable) is the 'passthrough' value in its 'input' function. This says to me that the function calls specified in the dialog definition are all called once on gtkdialog startup. Otherwise, the text should've been 'start', the last value (the exported) DISK_TEXT was assigned before the gtkdialog call.

  • As each radio button is selected, the 'dupdate' function is updating DISK_TEXT Ok, as it's being displayed 'as expected' in the dialog... except that the 3rd radiobutton (OP3 variable) has been coded to illustrate that the 'disks' array is unknown, even though it's been exported from the mainline. I've tried different 'forms' of quoting the array element... but even writing every element to a file shows that the array is empty inside the 'dupdate' function.

  • Aditionally, the DISK_TEXT variable that is being manipulated in gtkdialog is clearly different from the exported variable in the mainline (and perhaps partly explains why the 'disks' array is unknown); the DISK_TEXT variable that is returned to the mainline environment by the call to gtkdialog is only a string (that you can capture) and is not the DISK_TEXT variable in the mainline, as its value before and after the gtkdialog call is unchanged.

...

1) add <action signal="map-event">refresh:DISK_TEXT</action> to the window widget (see below)

2) do a internet search for bash export array variable - looks like it is no good idea to try to export an array...

3) gtkdialog runs as subprocess and has access to exported variables from its parent shell. It can overwrite them while running. If the subprocess finished the initial value of the variable will reappear. It is no good practice to overwrite exported variables

Code: Select all

#!/bin/sh
# rb2.sh - radiobuttons doing the updating
#

export disks=("sda1" "sdb2" "sdd3") # 'export' should make it known when gtkdialog runs...?
export DISK_TEXT=""

dupdate () {
   if [[ $OP1 = true ]]; then
#      DISK_TEXT="${disks[0]}"
      DISK_TEXT="1"
      
   elif [[ $OP2 = true ]]; then
#      DISK_TEXT="${disks[1]}"
      DISK_TEXT="2"
   
   elif [[ $OP3 = true ]]; then  # Why is disks() unknown?
      if [[ "${disks[2]}" -eq "" ]]; then
         DISK_TEXT="disks() unknown"
      else  
         DISK_TEXT="${disks[2]}"  
      fi
#      DISK_TEXT="3"

   else
      DISK_TEXT="none"
      
   fi

   echo -n "$DISK_TEXT"

}
export -f dupdate

# ----

DISK_TEXT="start"  # Won't be used in the initial dialog..
                   # ..as the 'function' on a widget is always..
                   # ..run on gtkdialog start... Is it?

export MAIN_DIALOG='
<window width-request="220" title="More Puzzles"> 
   <vbox>
      <radiobutton>
         <variable>OP1</variable>
         <default>true</default>
         <label>'"${disks[0]}"'</label>
         <action>refresh:DISK_TEXT</action>
      </radiobutton>
           
      <radiobutton>
         <variable>OP2</variable>
         <default>false</default>
         <label>'"${disks[1]}"'</label>
         <action>refresh:DISK_TEXT</action>
      </radiobutton>
           
      <radiobutton>
         <variable>OP3</variable>
         <default>false</default>
         <label>'"${disks[2]}"'</label>
         <action>refresh:DISK_TEXT</action>
      </radiobutton>
   
      <hseparator></hseparator>
   
      <text>
         <variable>DISK_TEXT</variable>
         <input>dupdate</input>
      </text>

      <hseparator></hseparator>

      <button> 
         <label>Ok</label> 
         <action function="exit">Exit</action>
      </button> 
   
   </vbox>
   <action signal="map-event">refresh:DISK_TEXT</action>
</window>
'

echo "--- PRE DIALOG ---"
echo "DISK_TEXT = '$DISK_TEXT' prior to dialog entry"
gtkdialog --program=MAIN_DIALOG --geometry=+200+200
echo "--- POST DIALOG ---"

echo "DISK_TEXT = '$DISK_TEXT' on dialog exit"

exit 0
Post Reply

Return to “Programming”