GtkDialog - tips

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

Re: gtkdialog - tips

#1401 Post by misko_2083 »

slippery60 wrote:I am trying to write a menu system that will execute various cli programs. Many of the programs need a variable like "output directory" or 'out_dir".

So in their frame I include a variable "out_dir". I would like to propagate the answer to any one of the "out_dir" entries to all of them.

I thought that if is use just 1 variable "out_dir". After the first entry, a refresh would fix all of the "out_dir" variables and the user would not have to entry the variable again. But that didn't work.

Can this be done? and how?

Thanks
You have a menu with entries. Every entry uses the variable "out_dir" for something.

Code: Select all

menu
├─cli_1 >/${out_dir}
├─cli_2 >/${out_dir}
└─cli_3 >/${out_dir}
With bash, exported variables get passed on to child processes, not-exported variables do not.

Code: Select all

export out_dir="whatever"
If you export it in the parent shell, "out_dir" will be available in the children shells.

Code: Select all

menu
└─bash
  export out_dir="whatever"
  ├─cli_1 >/${out_dir}
  ├─cli_2 >/${out_dir}
  └─cli_3 >/${out_dir}
Not sure how the menu system looks.
slippery60 wrote: I would like to propagate the answer to any one of the "out_dir" entries to all of them.
Didn't understand that part.
Do you want to set the variable from the cli_1 and use it in cli_2?

Like Mochi-san said, code would tell much more.

slippery60
Posts: 5
Joined: Mon 18 Dec 2017, 20:31
Location: Fairmont, WV

How to set the same variable from multiple input

#1402 Post by slippery60 »

Misko, and Moshi

Thanks for the information I'll try setting a variable.

as an example of what I am doing;

I am making a gui for a number of forensic programs that don't have them.
E.g. dc3dd,
or ewfacquire.

I provide the gui to the user to collect all of the arguments needed for the program then call the program with arguments in the back ground.

The issue I have is that many if not all of the programs need the out put from the process directed to a "output directory"

So for each program I am creating the GUI for, I have a variable like "output_dir"; many times the output directory is the same from program to program. So the variable would be nice to set once and be do with it.

I thought why not just set it once for all the programs to use. I tried that, but my tester, kept by-passing the common "output directory", and the programs put output all over the place.

So, I needed to put in a variable to set the "output_dir" into each programs gui.

So now, what I want to do is allow the user to set the "out_dir" in any program's gui and then update that for all of the other programs.

The variable will be the same for all of the programs but, "set"able by any program. or should I say re-"set"able.

My script is about 1000 lines at this point, you want me to post it?!

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

Re: How to set the same variable from multiple input

#1403 Post by MochiMoppel »

slippery60 wrote:My script is about 1000 lines at this point, you want me to post it?!
Heaven forbid, no :lol:
The idea was to have a simplified example code, functional but shortened to the absolute minimum, just to show and understand your problem.

I'm still not sure if I understand what you are trying to do and where the "menu system" comes into play.
I can only assume that each of your menu items opens a subwindow, containing several widgets to collect from the user all parameters necessary for a cli- program. One of the widgets, probably an entry widget, would hold the name of the output directory.

The easiest way would be to use a temporary file, containing the path of that directory, Your variable "output_dir" would point to this tmp file, would never change and would be available to all of your cli frontends.
Example: Assuming that you run a bash script from which you launch your gtkdialog application, your could set the default output directory at the beginning of the bash script:
export output_dir=/tmp/output_dir.txt
echo "/root/my-applications/out" > $output_dir

In this case "/root/my-applications/out" would be the default output directory for your programs (you may have to create it first if it doesn't exist)

Your cli frontends could read the common output path contained in file $output_dir. If a user changes the path the new path could be written to $output_dir , from which it is available again to all other frontends.

slippery60
Posts: 5
Joined: Mon 18 Dec 2017, 20:31
Location: Fairmont, WV

How to set the same variable from multiple inpu

#1404 Post by slippery60 »

Mochi;

Thanks for the response. I chopped the script from 1000 to about 125.
I would upload the small file but, I'm too new.

I think I am going to try exporting the updated "out_directory"

Thanks.

User avatar
smokey01
Posts: 2813
Joined: Sat 30 Dec 2006, 23:15
Location: South Australia :-(
Contact:

#1405 Post by smokey01 »

Is it possible to display 01-100 in a <spinbutton>?

I can do 1-100 but I need leading zero's from 00 to 09. 10 and up is fine.

It's so I can define minutes from 00 to 59.

Thanks

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#1406 Post by MochiMoppel »

smokey01 wrote:Is it possible to display 01-100 in a <spinbutton>?
I'm afraid not, but why would you "need" to display the figures with leading zeros?
You may have to format the output to fit your requirements, but the display? Also keep in mind that the user can override the displayed value with whatever he likes, so you will have to check the output anyway.

If you are really keen to display leading zeros you may have to resort to a workaround. The following code works for me and hides the entry part of the spinbutton widget and feeds the values to an added entry widget, which can be much better controlled and formatted. You could even set it to editable="false" and thus avoid invalid manual entries (though not a good idea!).

Code: Select all

#!/bin/bash
export MAIN_DIALOG='
<hbox>
	<entry>
		<variable>MIN</variable>
		<input>printf "%02d" $SPIN</input>
	</entry>
	<spinbutton width-request="15" range-min="0" range-max="59">
		<variable>SPIN</variable>
		<action>refresh:MIN</action>
	</spinbutton>
	<button>
		<action condition="command_is_true([[ $MIN =~ ^[0-9]+$ && $MIN -ge 0 && $MIN -le 59 ]] && echo true )">exit:</action>
	</button>
</hbox>'
eval $(gtkdialog)
[[ $MIN ]] && MIN=$(printf "%02d" $((10#$MIN)) )
echo $MIN
The <action> code of the button checks if the entry consists of only numbers and if the numbers are between 0 and 59. If not the button would not close the window
$((10#$MIN)) makes sure that printf interprets $MIN as a base 10 integer. Without it a value of 020 would return octal 16
Attachments
entry_spinbutton_combo.png
(1.78 KiB) Downloaded 433 times

User avatar
misko_2083
Posts: 114
Joined: Tue 08 Nov 2016, 13:42

#1407 Post by misko_2083 »

^^^^
There could be a timer to fix the invalid input.

Now, if it's not a number or less than 0 or greater than 59 it will revert to previous MIN value.

Code: Select all

#!/bin/bash
export MAIN_DIALOG='
<hbox>
   <entry>
      <variable>MIN</variable>
      <input>printf "%02d" $SPIN</input>
   </entry>
   <spinbutton width-request="15" range-min="0" range-max="59">
      <variable>SPIN</variable>
      <action>refresh:MIN</action>
   </spinbutton>
   <button>
      <action condition="command_is_true([[ $MIN =~ ^[0-9]+$ && $MIN -ge 0 && $MIN -le 59 ]] && echo true )">exit:</action>
   </button>
   <timer milliseconds="true" interval="500" visible="false">
      <action condition="command_is_true([[ $MIN != +([0-9]) || $MIN -lt 0 || $MIN -gt 59 ]] && echo true )">refresh:MIN</action>
   </timer>
</hbox>'
eval $(gtkdialog)
[[ $MIN ]] && MIN=$(printf "%02d" $((10#$MIN)) )
echo $MIN
What can possibly be further improved is
- when more then 2 digits are entered to trim back to 2 [ ${#MIN} -gt 2 ]
now it's possible to enter 000000, 0000000057, 010,
- when the MIN is set manualy the spin button to continue increasing the number
if a number is entered manualy and the spin button is clicked it will continue from the previous SPIN value

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

Re: GtkDialog - tips

#1408 Post by MochiMoppel »

@zigbert: Links 3-5 lead to smokey01's Puppy Newsletter but not to the advertised topics.
Could they be fixed?
Thanks.

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#1409 Post by 01micko »

@zigbert.. to make the request of MochiMoppel easier..

http://blog.puppylinux.com/archive/curr ... -menu.html
http://blog.puppylinux.com/archive/curr ... -knob.html
http://blog.puppylinux.com/archive/curr ... -tabs.html

That was a result of migrating the blog to a new platform.
Puppy Linux Blog - contact me for access

User avatar
zigbert
Posts: 6621
Joined: Wed 29 Mar 2006, 18:13
Location: Valåmoen, Norway
Contact:

#1410 Post by zigbert »

Fixed!
Thank you both for input :)

User avatar
smokey01
Posts: 2813
Joined: Sat 30 Dec 2006, 23:15
Location: South Australia :-(
Contact:

#1411 Post by smokey01 »

I've been beaten again by this gtkdialog.

It's an entry widget with a checkbox widget. The entry widget is to enter a password. The checkbox widget should show the password when true and hide it when false.

Code: Select all

#!/bin/sh

[ -z $GTKDIALOG ] && GTKDIALOG=gtkdialog

MAIN_DIALOG='
<window>
	<vbox>
		<frame Not Working>
			<entry visibility="$CHECKBOX">
				<default>Password</default>
				<variable>ENTRY</variable>
			</entry>
			<checkbox>
				<label>Show/Hide Password</label>
				<variable>CHECKBOX</variable>
				<action>echo $CHECKBOX</action>
				<action>if true enable:ENTRY</action>
				<action>if false disable:ENTRY</action>
				<action>refresh:ENTRY</action>
			</checkbox>
		</frame>
		<hbox>
			<button ok></button>
			<button cancel></button>
		</hbox>
	</vbox>
</window>
'
export MAIN_DIALOG

case $1 in
	-d | --dump) echo "$MAIN_DIALOG" ;;
	*) $GTKDIALOG --program=MAIN_DIALOG ;;
esac
I disable/enable the entry widget to make sure it is toggling properly.
I am also echoing the $CHECKBOX variable to make sure it's changing state which it is.

How do I make the tag attribute visibility="$CHECKBOX" update when the checkbox state is changed. I am refreshing the ENTRY widget but that's not doing it.

It's looks simple enough but it's got me stumped.

Thanks.
Attachments
password.png
(7.35 KiB) Downloaded 750 times

User avatar
SFR
Posts: 1800
Joined: Wed 26 Oct 2011, 21:52

#1412 Post by SFR »

That's how I did this once: you need 2 synced <entry> fields (I used <notebook> as a container for them), one with visibility="false" and the other one with visibility="true".
Then by using a checkbox you can simply switch between them, i.e. <notebook>'s tabs.

Also, having a <notebook> with tabs hidden somehow messes with the layout (empty space beneath buttons), so we need to to hide it initially and show on 'map-event' signal.

Code: Select all

#!/bin/sh

[ -z $GTKDIALOG ] && GTKDIALOG=gtkdialog

MAIN_DIALOG='
<window>
   <vbox>

      <frame Working Now>

         <notebook show-tabs="false" show-border="false" visible="false">
			<entry visibility="false">
				<default>Password</default>
				<variable>ENTRY</variable>
				<input>echo "$ENTRY_PLAIN"</input>
				<action>refresh:ENTRY_PLAIN</action>
			</entry>

			<entry visibility="true">
				<default>Password</default>
				<variable>ENTRY_PLAIN</variable>
				<input>echo "$ENTRY"</input>
				<action>refresh:ENTRY</action>
			</entry>

            <variable>PASS_MODE</variable>
            <input>echo $(( (PASS_MODE + 1) & 1 ))</input>
		</notebook>

         <checkbox>
            <label>Show/Hide Password</label>
            <action>refresh:PASS_MODE</action>
         </checkbox>

      </frame>

      <hbox>
         <button ok></button>
         <button cancel></button>
      </hbox>
   </vbox>

   <action signal="map-event">show:PASS_MODE</action>
</window>
'
export MAIN_DIALOG

case $1 in
   -d | --dump) echo "$MAIN_DIALOG" ;;
   *) $GTKDIALOG --program=MAIN_DIALOG ;;
esac
Greetings!
[color=red][size=75][O]bdurate [R]ules [D]estroy [E]nthusiastic [R]ebels => [C]reative [H]umans [A]lways [O]pen [S]ource[/size][/color]
[b][color=green]Omnia mea mecum porto.[/color][/b]

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#1413 Post by 01micko »

While doing a tiny bit of research on Smokey's problem I stumbled upon Michael Czapski's work. (Sorry Grant but at least SFR came up with the goods :P )

This guy is a serious programmer and scratched an itch with gtkdialog.

There might be some useful examples on his blog.

Check it out!
Puppy Linux Blog - contact me for access

User avatar
smokey01
Posts: 2813
Joined: Sat 30 Dec 2006, 23:15
Location: South Australia :-(
Contact:

#1414 Post by smokey01 »

@SFR that does the job nicely but there must be an easier and shorter method.

Thanks.
SFR wrote:That's how I did this once: you need 2 synced <entry> fields (I used <notebook> as a container for them), one with visibility="false" and the other one with visibility="true".
Then by using a checkbox you can simply switch between them, i.e. <notebook>'s tabs.

Also, having a <notebook> with tabs hidden somehow messes with the layout (empty space beneath buttons), so we need to to hide it initially and show on 'map-event' signal.

Code: Select all

#!/bin/sh

[ -z $GTKDIALOG ] && GTKDIALOG=gtkdialog

MAIN_DIALOG='
<window>
   <vbox>

      <frame Working Now>

         <notebook show-tabs="false" show-border="false" visible="false">
			<entry visibility="false">
				<default>Password</default>
				<variable>ENTRY</variable>
				<input>echo "$ENTRY_PLAIN"</input>
				<action>refresh:ENTRY_PLAIN</action>
			</entry>

			<entry visibility="true">
				<default>Password</default>
				<variable>ENTRY_PLAIN</variable>
				<input>echo "$ENTRY"</input>
				<action>refresh:ENTRY</action>
			</entry>

            <variable>PASS_MODE</variable>
            <input>echo $(( (PASS_MODE + 1) & 1 ))</input>
		</notebook>

         <checkbox>
            <label>Show/Hide Password</label>
            <action>refresh:PASS_MODE</action>
         </checkbox>

      </frame>

      <hbox>
         <button ok></button>
         <button cancel></button>
      </hbox>
   </vbox>

   <action signal="map-event">show:PASS_MODE</action>
</window>
'
export MAIN_DIALOG

case $1 in
   -d | --dump) echo "$MAIN_DIALOG" ;;
   *) $GTKDIALOG --program=MAIN_DIALOG ;;
esac
Greetings!

User avatar
smokey01
Posts: 2813
Joined: Sat 30 Dec 2006, 23:15
Location: South Australia :-(
Contact:

#1415 Post by smokey01 »

01micko wrote:While doing a tiny bit of research on Smokey's problem I stumbled upon Michael Czapski's work. (Sorry Grant but at least SFR came up with the goods :P )

This guy is a serious programmer and scratched an itch with gtkdialog.

There might be some useful examples on his blog.

Check it out!
Thanks Mick. A very interesting blog.

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#1416 Post by MochiMoppel »

SFR wrote:Also, having a <notebook> with tabs hidden somehow messes with the layout (empty space beneath buttons), so we need to to hide it initially and show on 'map-event' signal.
You can avoid this empty space with

Code: Select all

<window resizable="false"> 

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#1417 Post by MochiMoppel »

Slightly shorter:

Code: Select all

#!/bin/bash
[ -z $GTKDIALOG ] && GTKDIALOG=gtkdialog 

MAIN_DIALOG=' 
<window> 
<vbox> 
   <frame Also working> 

	   <entry visibility="false"> 
		 <default>Password</default> 
		 <variable>ENTRY</variable> 
		 <input>echo "$ENTRY_PLAIN"</input> 
		 <action>refresh:ENTRY_PLAIN</action> 
	  </entry> 

	  <entry visible="false"> 
		 <default>Password</default> 
		 <variable>ENTRY_PLAIN</variable> 
		 <input>echo "$ENTRY"</input> 
		 <action>refresh:ENTRY</action> 
	  </entry> 

	  <checkbox> 
		 <label>Show/Hide Password</label> 
		 <action>if true hide:ENTRY</action> 
		 <action>if true show:ENTRY_PLAIN</action> 
		 <action>if false show:ENTRY</action> 
		 <action>if false hide:ENTRY_PLAIN</action> 
	  </checkbox> 

   </frame> 

   <hbox> 
	  <button ok></button> 
	  <button cancel></button> 
   </hbox> 
</vbox> 

</window> 
' 
export MAIN_DIALOG 
case $1 in 
	-d | --dump) echo "$MAIN_DIALOG" ;; 
	*) $GTKDIALOG --program=MAIN_DIALOG ;; 
esac

User avatar
SFR
Posts: 1800
Joined: Wed 26 Oct 2011, 21:52

#1418 Post by SFR »

smokey01 wrote:@SFR that does the job nicely but there must be an easier and shorter method.
Surely it would be nice if there was an easier way, but there isn't, to my knowledge.
You can do it The Right Way™ in pure GTK+ (e.g. via C, Python, etc.) using gtk-entry-set-visibility, but AFAIK Gtkdialog does not implement a mechanism to change widget's specific properties on the fly, except for a couple of them that are common to all widgets (sentitive, visible).

@Mochi: thanks for simplifying it!

Greetings!
[color=red][size=75][O]bdurate [R]ules [D]estroy [E]nthusiastic [R]ebels => [C]reative [H]umans [A]lways [O]pen [S]ource[/size][/color]
[b][color=green]Omnia mea mecum porto.[/color][/b]

User avatar
don570
Posts: 5528
Joined: Wed 10 Mar 2010, 19:58
Location: Ontario

#1419 Post by don570 »

Tip:

Xdialog has a limit to the number of characters in a message box

but 'backtitle' option allows more lines to shown in window

Example:
Xdialog --left --backtitle "\n$(gettext 'Conversion factor\nUnit A to Unit B')" --msgbox "$MSG1\n\n $MSG2\n\n $MSG3\n\n $MSG4\n\n $MSG5\n\n $MSG6" 0 0
Reference:
http://murga-linux.com/puppy/viewtopic.php?t=114156
_________________________________________________

wiak
Posts: 2040
Joined: Tue 11 Dec 2007, 05:12
Location: not Bulgaria

#1420 Post by wiak »

SFR wrote: Surely it would be nice if there was an easier way, but there isn't, to my knowledge.
You can do it The Right Way™ in pure GTK+ (e.g. via C, Python, etc.) using gtk-entry-set-visibility, but AFAIK Gtkdialog does not implement a mechanism to change widget's specific properties on the fly, except for a couple of them that are common to all widgets (sentitive, visible).
Gtkdialog does use gtk-entry-set-visibility function but only during first initialisation.

Current gtkdialog (since ver 0.7.21) recognises the sensitive states: true, false, or password during that initialisation. That additional 'password' state really refers to gtk-entry-set-visibility, rather than actual GTK GtkWidget sensitive state, which only includes true or false (grayed out or not).

Adding additional sensitive states and associated logic (as was done for 'password' itself), it is possible to toggle at least some widget states 'on-the-fly' via a checkbox refresh action. For example, I am currently trying out an experimental gtkwialog compile that includes extra sensitive state 'toggle_password' (each time the entry is refreshed via a checkbox). I'm still however considering whether the approach is good and what additional 'sensitive' state name(s) to actually use in practice, before any possible gtkwialog release with that extra functionality. The resultant sh/gtkwialog code is certainly a bit simpler than the hide/show password entry-box workarounds described earlier. The following straightforward code, for example, works with my experimental gtkwialog compile:

Code: Select all

#!/bin/bash
[ -z $GTKDIALOG ] && GTKDIALOG=gtkwialog

MAIN_DIALOG='
<window>
<vbox>
 <frame Also working>

  <entry>
   <sensitive>toggle_password</sensitive>
   <variable>ENTRY</variable>
   <default>Password</default>
  </entry>

  <checkbox>
   <variable>CHKBOX</variable>
   <label>Show/Hide Password</label>
   <action>refresh:ENTRY</action>
  </checkbox>

 </frame>

 <hbox>
  <button ok></button>
  <button cancel></button>
 </hbox>   

</vbox>
</window>
'
export MAIN_DIALOG
case $1 in
   -d | --dump) echo "$MAIN_DIALOG" ;;
   *) $GTKDIALOG --program=MAIN_DIALOG ;;
esac
I'll post further about it if I decide to proceed with/publish that addition; just hesitant to adopt a new strategy (since once formalised hard to take it back...) in case a better approach is found. I'm hesitant because I'm not sure if overloading sensitive with additional states is best mechanism (despite that already being done for 'password' state itself) - it is certainly easy to apply. Might instead be better to have a new 'Directive' for such on-the-fly refresh additions, which I have yet to think of a suitable name for... However, I'm inclined towards these additional 'sensitive' states to toggle between since it involves only a little bit extra code to implement. If you feel you have any use for this facility, let me know since it is not worth further consideration if not likely to be used anyway.

wiak

Note: gif created using weX screencapture along with its utility button to fredx181's gifenc-yad utility. On looking at it, according to checkbox label, I should of course make password show on clicking check box, rather than hide on click...
Attachments
toggle_password.gif
(209.5 KiB) Downloaded 446 times

Post Reply