save state of SpeedControl widget

More
17 Sep 2018 12:22 #117648 by bkt
Hi,

I'm completely new in python and not very well understand it for now, I use these script:
import hal
import glib
import time
import gtk
import gtk.glade
import gobject
import os,sys
from gladevcp.persistence import IniFile,widget_defaults,set_debug,select_widgets
import hal_glib



class HandlerClass:
    '''
    class with gladevcp callback handlers
    '''

    def on_button_press(widget,data=None):

        '''
        a callback method
        parameters are:
            the generating object instance, likte a GtkButton instance
            user data passed if any - this is currently unused but
            the convention should be retained just in case
        '''
        print "on_button_press called"
        self.nhits += 1
        self.builder.get_object('hits').set_label("Hits: %d" % (self.nhits))


    def on_notebook1_destroy(self,obj,data=None):
        self.ini.save_state(self)

    def on_discesa_value_changed(self,obj,data=None):
        xa = self.builder.get_object('discesa').get_value()
        

    def on_salita_value_changed(self,obj,data=None):
        xb = self.builder.get_object('salita').get_value()        

    def on_posizione_value_changed(self,obj,data=None):
        xc = self.builder.get_object('posizione').get_value()       

    def on_delay_value_changed(self,obj,data=None):
        xd = self.builder.get_object('delay').get_value()  
    

    def on_restore_defaults(self,button,data=None):
        '''
        example callback for 'Reset to defaults' button
        currently unused
        
        self.ini.create_default_ini()
        self.ini.restore_state(self)
        '''



    def __init__(self, halcomp,builder,useropts):

        '''
        Handler classes are instantiated in the following state:
        - the widget tree is created, but not yet realized (no toplevel window.show() executed yet)
        - the halcomp HAL component is set up and the widhget tree's HAL pins have already been added to it
        - it is safe to add more hal pins because halcomp.ready() has not yet been called at this point.

        after all handlers are instantiated in command line and get_handlers() order, callbacks will be
        connected with connect_signals()/signal_autoconnect()

        The builder may be either of libglade or GtkBuilder type depending on the glade file format.
        '''

        self.halcomp = halcomp
        self.builder = builder
        self.nhits = 0
        self.useropts = useropts
        self.defaults = {
            # the following names will be saved/restored as method attributes
            # the save/restore mechanism is strongly typed - the variables type will be derived from the type of the
            # initialization value. Currently supported types are: int, float, bool, string
            IniFile.vars : { 'nhits' : 0, 'a': 1.67, 'd': True ,'c' : "a string"},
            # to save/restore all widget's state which might remotely make sense, add this:
            IniFile.widgets : widget_defaults(builder.get_objects())
            # a sensible alternative might be to retain only all HAL output widgets' state:
            # IniFile.widgets: widget_defaults(select_widgets(self.builder.get_objects(), hal_only=True,output_only = True)),
        }

        builder.get_object('vcp_filechooserbutton1').set_current_folder(os.path.expanduser('/home/pc/folder1/'))
        builder.get_object('vcp_filechooserbutton2').set_current_folder(os.path.expanduser('/home/pc/folder2/'))

        self.ini_filename = __name__ + '.save'
        self.defaults = {  IniFile.vars: dict(),
                           IniFile.widgets : widget_defaults(select_widgets(self.builder.get_objects(), hal_only=False,output_only = True))
                        }
        self.ini = IniFile(self.ini_filename,self.defaults,self.builder)
        self.ini.restore_state(self)



def get_handlers(halcomp,builder,useropts):
    '''
    this function is called by gladevcp at import time (when this module is passed with '-u <modname>.py')

    return a list of object instances whose methods should be connected as callback handlers
    any method whose name does not begin with an underscore ('_') is a  callback candidate

    the 'get_handlers' name is reserved - gladevcp expects it, so do not change
    '''


    return [HandlerClass(halcomp,builder,useropts)]

I try to save the state of my gladevcp widgets on my .save file .... for boolean state all works ok ... my tooggle button if true in the last session become true when start again my lcnc sim test .... but nothing to do with SpeedControl widget .... probabily my xa, xb, xc. xd vars is ok ... but not know how to set the corrispondant widget to these value at restart, and no understand how is possible to save that vars in .save file.

any help is appreciate.

regards
Giorgio

Please Log in or Create an account to join the conversation.

More
17 Sep 2018 13:10 #117653 by andypugh
I guess you are working from this? linuxcnc.org/docs/2.7/html/gui/gladevcp....ariables_in_gladevcp

I don't see the on-destroy callback in your code, which is what saves the variables on exit.

Please Log in or Create an account to join the conversation.

More
17 Sep 2018 14:24 #117657 by bkt

def on_notebook1_destroy(self,obj,data=None):
self.ini.save_state(self)


these work ....

regards
Giorgio

Please Log in or Create an account to join the conversation.

More
17 Sep 2018 19:56 #117667 by Grotius
Hi Brother Pinguin,



You could consider to save your screen parameter's in text or excel based file's.
Then you could also implement and save ini or hal file's.

Please Log in or Create an account to join the conversation.

More
18 Sep 2018 06:24 #117694 by bkt
thanks I love pinguin I use it on all my pc except for the plc unfortunately... python and I are almost enemies ... so that every strategy is difficult for myself ... I would not learn to do anything else with python and if there is any Samaritan who suggests me a code to adapt I take it willingly. In this period I started a gui all in c++ and I prefer to concentrate on that. Unfortunately I have this problem to solve ....

regards
Giorgio

Please Log in or Create an account to join the conversation.

More
18 Sep 2018 19:10 - 18 Sep 2018 19:17 #117726 by Grotius
Hi Giorgio,

For info only :

For saving and loading text files :

User widgets : Travelheight (glade scale value), entry (glade tekst entry), etc. You know how to handle this.
def on_save_settings_as_pressed(self, widget, data=None):
      value = self.widgets.Travelheight.get_value()
      print(value)
      #f= open("plasma_tools.txt","w+")
      x = self.widgets.entry.get_text()
      f=open(x, "w+")
      f.write("Travelheight\r\n")
      f.write("%d\r\n" % (value))
      f.close() 

  def on_load_settings_pressed(self, widget, data=None):
     x = self.widgets.entry.get_text()
     f=open(x, "r")
     if f.mode == 'r':
        content =f.readlines()
        print content[1] # actual line 2 in file.
        y = float(content[1])
        self.widgets.Travelheight.set_value(y)

For saving and loading excel files :
Writing excel files is easy with xlsxwriter, for reading i currently use openpyxl. (reading is difficulter then writing in python, i don't know why)

To install the dependencies in terminal :
sudo apt-get install python-openpyxl
sudo apt-get install python-xlsxwriter

On top in your file :
from openpyxl import load_workbook
import xlsxwriter 

def on_load_excel_file_pressed(self, widget, data=None):  
	  wb = load_workbook(filename = 'plasma_tools.xlsx')
	  sheet_ranges = wb['plasma_mild_steel']
	  print(sheet_ranges['A1'].value)
	  print "loading file is succesfull"

  def on_write_excel_file_pressed(self, widget, data=None):
      print "writing excel file"

      # Create an new Excel file and add a worksheet.
      workbook = xlsxwriter.Workbook('plasma_tools.xlsx')
      worksheet = workbook.add_worksheet('plasma_mild_steel')

      # Widen the first column to make the text clearer.
      worksheet.set_column('A:A', 20)

      # Add a bold format to use to highlight cells.
      bold = workbook.add_format({'bold': True})

      # Write some simple text.
      worksheet.write('A1', 'Block Tool Settings', bold)
      worksheet.write('A2', 'Travelheight')
      worksheet.write('B2', self.widgets.Travelheight.get_value())
      worksheet.write('A3', 'Pierceheight')
      worksheet.write('B3', self.widgets.Pierceheight.get_value())
      worksheet.write('A4', 'Cutheight')
      worksheet.write('B4', self.widgets.Cutheight.get_value())
      worksheet.write('A5', 'Probe Switch Offset')
      worksheet.write('B5', self.widgets.Probe_switch_offset.get_value())
      worksheet.write('A6', 'Probe Search Limit')
      worksheet.write('B6', self.widgets.Probe_search_limit.get_value())
      worksheet.write('A7', 'Cutheight')
      worksheet.write('B7', self.widgets.Cutheight.get_value())

      worksheet.write('A9', 'Block Time settings', bold)
      worksheet.write('A10', 'Restart Time Back')
      worksheet.write('B10', self.widgets.Restart_time_back.get_value())
      worksheet.write('A11', 'Anti Dive Delay')
      worksheet.write('B11', self.widgets.Anti_dive_delay.get_value())
      worksheet.write('A12', 'Pierce Delay')
      worksheet.write('B12', self.widgets.Pierce_delay.get_value())
      worksheet.write('A13', 'Auto Restart Times')
      worksheet.write('B13', self.widgets.Auto_restart_times.get_value())

      worksheet.write('A15', 'Block Probe Over Distance', bold)
      worksheet.write('A16', 'X Offset')
      worksheet.write('B16', self.widgets.Dist_x.get_value())
      worksheet.write('A17', 'Y Offset')
      worksheet.write('B17', self.widgets.Dist_y.get_value())

      worksheet.write('A19', 'Block Z Axis', bold)
      worksheet.write('A20', 'Max Speed')
      worksheet.write('B20', self.widgets.Max_z_speed.get_value())
      worksheet.write('A21', 'Max Acceleration')
      worksheet.write('B21', self.widgets.Max_z_acceleration.get_value())
      worksheet.write('A22', 'Piercespeed')
      worksheet.write('B22', self.widgets.Piercespeed.get_value())
      worksheet.write('A23', 'Probespeed')
      worksheet.write('B23', self.widgets.Probespeed.get_value())

      worksheet.write('A25', 'Block Mesa', bold)
      worksheet.write('A26', 'Cut Chart Voltage')
      worksheet.write('B26', self.widgets.Cut_chart_voltage.get_value())

      # Write some numbers, with row/column notation.
      #worksheet.write(2, 1, 123)
      #worksheet.write(3, 1, 123.456)
      workbook.close()
Last edit: 18 Sep 2018 19:17 by Grotius.

Please Log in or Create an account to join the conversation.

More
18 Sep 2018 19:43 - 18 Sep 2018 20:34 #117727 by Grotius
Hi K1,

If you look further than this, we can make linuxcnc ini and hal files configurable within the running linuxcnc program.
I ask myself if a value is changed we could do a ini and hal reload command. I think that would be possible after some research.

It is like adapting the stepconfig wizard into a running program. But a parameter reload command is required. Maybe someone
know this command or maybe someone knows the command line command for reload certain parts of linuxcnc.

The glade panel can be 90% copied from stepconfig wizard and be adapted to a running config.

For the previous post :
To set your excel file parameters in your current gui :
x = float(sheet_ranges.value)
self.widgets.Travelheight.set_value(x)
Last edit: 18 Sep 2018 20:34 by Grotius.
The following user(s) said Thank You: bkt

Please Log in or Create an account to join the conversation.

More
19 Sep 2018 17:03 #117753 by bkt
I find out these exaple in app folder, named complex.py .... thats all folks.

#!/usr/bin/env python
# vim: sts=4 sw=4 et
#    This is a component of LinuxCNC
#    complex.py Copyright 2010 Michael Haberler
#
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.''''''
'''
    gladevcp complex demo example
    Michael Haberler 11/2010

'''

import os,sys
from gladevcp.persistence import IniFile,widget_defaults,set_debug,select_widgets
import hal
import hal_glib
import gtk
import glib

debug = 0

class HandlerClass:
    '''
    class with gladevcp callback handlers
    '''

    def on_button_press(self,halwidget,data=None):
        '''
        a callback method
        parameters are:
            the generating object instance, like a GtkButton instance
            user data passed if any - this is currently unused but
            the convention should be retained just in case
        '''
        print "on_button_press()"
        self.nhits += 1
        halwidget.set_label("hits: %d" % self.nhits)


    def on_toggle_button(self,hal_button,data=None):
        '''
        standard button-pressed callback. Parameter is the widget object instance.
        '''
        print "on_toggle_button() HAL pin value: %s" %(str(hal_button.hal_pin.get()))

    def _on_example_trigger_change(self,hal_pin,data=None):
        '''
        executed when the 'example-trigger' hal pin value changes
        note that this callback will not be exposed as potential callback
        handler through gladevcp since the name begins with an underscore (_) .
        Parameter is the HAL pin instance.
        '''
        print "_on_example_trigger_change() - HAL pin value: %s" % (hal_pin.get())

    def on_led_pin_changed(self,hal_led,data=None):
        '''
        this is an example of a hal-pin-changed signal handler as set in glade.
        The purpose of this callback is to deliver an optional notification to your code beyond
        just reacting to the changed HAL pin.
        the on_led_pin_changed signal is set in the complex.ui hal_led1 signals section
        '''
        print "on_led_pin_changed() - HAL pin value:",hal_led.hal_pin.get()

    def _on_timer_tick(self,userdata=None):
        '''
        the full glib functionality is available if needed.
        here's a timer function which will be called periodically
        returning True restarts the timer
        returning False makes it a one-shot
        '''
        self.lifetime_ticks += 1
        self.builder.get_object('message').hal_pin.set(self.lifetime_ticks)
        return True


    def on_unix_signal(self,signum,stack_frame):
        print "on_unix_signal(): signal %d received, saving state" % (signum)
        self.ini.save_state(self)
        gtk.main_quit()
        self.halcomp.exit()

    def on_destroy(self,obj,data=None):
        '''
        gladevcp_demo.ui has a destroy callback set in the window1 Gobject
        note the widget tree is not safely accessible here any more
        '''
        print "on_destroy() - saving state)"
        self.ini.save_state(self)

    def on_restore_defaults(self,button,data=None):
        self.ini.create_default_ini()
        self.ini.restore_state(self)
        self.builder.get_object('hal_button1').set_label("past hits: %d" % self.nhits)

    def on_save_settings(self,button,data=None):
        print "on_save_settings() - saving state"
        self.ini.save_state(self)

    def _hal_setup(self,halcomp, builder):
        '''
        hal related initialisation
        '''

        # the toplevel window is always named 'window1'. Do not change.
        # widgets may be accessed through builder.get_object() and
        # builder.get_objects()
        self.window1 = self.builder.get_object("window1")
        self.led1 = self.builder.get_object("hal_led1")

        # standard hal pins not associated with any widget
        self.halcomp.newpin("example-out", hal.HAL_BIT, hal.HAL_OUT)
        self.halcomp.newpin("example-in", hal.HAL_S32, hal.HAL_IN)

        # hal pins with change callback. Also unrelated to any HAL widget.
        # When the pin's value changes the callback is executed.
        self.example_trigger = hal_glib.GPin(halcomp.newpin('example-trigger',  hal.HAL_BIT, hal.HAL_IN))
        self.example_trigger.connect('value-changed', self._on_example_trigger_change)

    def __init__(self, halcomp,builder,useropts):
        '''
        Handler classes are instantiated in the following state:
        - the widget tree is created, but not yet realized (no toplevel window.show() executed yet)
        - the halcomp HAL component is set up and the widhget tree's HAL pins have already been added to it
        - it is safe to add more hal pins because halcomp.ready() has not yet been called at this point.

        after all handlers are instantiated in command line and get_handlers() order, callbacks will be
        connected with connect_signals()/signal_autoconnect()

        The builder may be either of libglade or GtkBuilder type depending on the glade file format.
        '''
        self.halcomp = halcomp
        self.builder = builder

        (directory,filename) = os.path.split(__file__)
        (basename,extension) = os.path.splitext(filename)
        self.ini_filename = os.path.join(directory,basename + '.save')

        # the dict driving the ini file persistence feature
        # a signature checks variable names,types,sections
        #
        # to see the mechanism at work, do this:
        # - run the application, change some values, and exit
        # - edit the complex.save file and change a variable name in the widgets or vars section
        #   for example, rename 'a' to 'z'
        #   and remove one of the widgets in the widgets section
        # - then re-run the application
        # during startup, you get a message saying
        # "key 'a' in section 'vars' : missing"
        # "key 'hal_radiobutton1' in section 'widgets' : missing"
        #
        # to see how the protection of ini file versus a changed program works,
        # change the defaults dict below, for instance remove the 'c' : "a string variable
        # then re-run - the signature check at startup should fail, you should get:
        # "signature mismatch in ./complex.save -  resetting to default"
        # and a default ini file is generated

        self.defaults = {  # these will be saved/restored as method attributes
                            IniFile.vars: { 'nhits' : 0, 'lifetime_ticks': 0, 'a': 1.67, 'd': True, 'c' :  "a string"},

                            # we're interested restoring state to output HAL widgets only
                            # NB: this does NOT restore state pf plain gtk objects - set hal_only to False to do this
                            IniFile.widgets: widget_defaults(select_widgets(self.builder.get_objects(), hal_only=True,output_only = True)),
                       }

        self.ini = IniFile(self.ini_filename,self.defaults, self.builder)
        self.ini.restore_state(self)

        # at this point it is ok to refer to restored attributes like self.nhits and self.lifetime_ticks:
        self.builder.get_object('hal_button1').set_label("past hits: %d" % self.nhits)
        self.builder.get_object('message').hal_pin.set(self.lifetime_ticks)

        self._hal_setup(halcomp,builder)

        # demonstrate a slow background timer - granularity is one second
        # for a faster timer, use this:
        # glib.timeout_add(5000,  self._on_timer_tick)
        glib.timeout_add_seconds(1, self._on_timer_tick)


def get_handlers(halcomp,builder,useropts):
    '''
    this function is called by gladevcp at import time (when this module is passed with '-u <modname>.py')

    return a list of object instances whose methods should be connected as callback handlers
    any method whose name does not begin with an underscore ('_') is a  callback candidate

    the 'get_handlers' name is reserved - gladevcp expects it, so do not change
    '''

    # try this at command line:
    #  -U debug=42 -U "print 'debug=%d' % debug"
    global debug
    for cmd in useropts:
        exec cmd in globals()

    set_debug(debug)

    if debug: print "%s.get_handlers() called" % (__name__)

    return [HandlerClass(halcomp,builder,useropts)]

Please Log in or Create an account to join the conversation.

More
19 Sep 2018 21:22 #117766 by Grotius
Hi K1,

That will work.
www.linuxcnc.org/docs/2.5/html/gui/gladevcp.html => sector 8.9

But you can not make user defined or tool defined saving's. And it's inside of the gladevcp ....
If glade will be updated to gtk3 with linuxcnc widget's, it's possible you have to rewrite your code again.

I think saving data is best outside of the linuxcnc source code. Then you are free of everything. You can even use
something other than glade, i heard you are writing your gui in c code. How is it going?
The following user(s) said Thank You: bkt

Please Log in or Create an account to join the conversation.

More
24 Sep 2018 20:52 - 24 Sep 2018 20:55 #117934 by bkt
actually i use a big part of xemc.cc code ... cmd seems to work ... stat end error channel not implemented yet. I think the major problem was error channel .... in 1/2 week i think can i have some news and i post for shure the code .... i think i need to hear some new trik.

You suggest me parametersaver comp of ArkEye. For shure is a good choice, In these way I can save only needed parameter. Good choice.

regards
Giorgio
Last edit: 24 Sep 2018 20:55 by bkt.

Please Log in or Create an account to join the conversation.

Moderators: HansU
Time to create page: 0.099 seconds
Powered by Kunena Forum