jverzani / gWidgets2

Rewrite of gWidgets
35 stars 9 forks source link

addHandlerClicked triggered when changing gbutton text #93

Closed OskarHansson closed 7 years ago

OskarHansson commented 7 years ago

Hi,

I'm working on an update for the strvalidator (https://github.com/OskarHansson/strvalidator) package to use gWidgets2 instead of gWidgets. I noticed that a function was triggered twice. This happened when I changed the button text using svalue(button) <- "Text". This does not happen in gWidgets.

Here is a reproducible example, also showing how I have built my functions.

This works in gWidgets:

library(gWidgets)

example <- function(){

  # Create the GUI.
  w <- gwindow()
  b <- gbutton("Calculate", cont=w)

  # Button clicked.
  addHandlerClicked(b, handler = function (h, ...) {

    # Change button text.
    svalue(b) <- "Processing..."
    Sys.sleep(1)

    # Perform the work by calling another function.    
    print("Button clicked!")

    # Change button.
    svalue(b) <- "Finished!"
    Sys.sleep(1)

    # Close window.
    dispose(w)

  })

  # Show the GUI.
  visible(w) <- TRUE

}

Run by typing example() and click the button.

In gWidgets2 an infinite loop is created (restart the R session before testing):

library(gWidgets2)

example2 <- function(){

  # Create the GUI.
  w <- gwindow()
  b <- gbutton("Calculate", cont=w)

  # Button clicked.
  addHandlerClicked(b, handler = function (h, ...) {

    # Change button text.
    svalue(b) <- "Processing..."
    Sys.sleep(1)

    # Perform the work by calling another function.    
    print("Button clicked!")

    # Change button.
    svalue(b) <- "Finished!"
    Sys.sleep(1)

    # Close window.
    dispose(w)

  })

  # Show the GUI.
  visible(w) <- TRUE

}

Run by typing example2() and click the button.

Is this a bug or am I using the wrong approach or syntax?

PS. In the original function I had used addHandlerChanged instead of addHandlerClicked, but the result was the same.

OskarHansson commented 7 years ago

I found this workaround suggested by @jverzani on Stackoverflow that prevents the issue: https://stackoverflow.com/questions/30337937/gwidgets2-how-to-prevent-gbutton-handler-to-run-when-change-gbutton-value

So changing the above example2 to this works:

library(gWidgets2)

example2 <- function(){

  # Create the GUI.
  w <- gwindow()
  b <- gbutton("Calculate", cont=w)

  # Button clicked.
  addHandlerClicked(b, handler = function (h, ...) {

    # Change button text.
    blockHandlers(b)
    svalue(b) <- "Processing..."
    unblockHandlers(b)
    Sys.sleep(1)

    # Perform the work by calling another function.    
    print("Button clicked!")

    # Change button.
    blockHandlers(b)
    svalue(b) <- "Finished!"
    unblockHandlers(b)
    Sys.sleep(1)

    # Close window.
    dispose(w)

  })

  # Show the GUI.
  visible(w) <- TRUE

}

I will go with this workaround for now.

jverzani commented 7 years ago

You could also write a function svalue_btn as follows

svalue_btn = function(b, txt) b$widget$setText(txt)

and call that instead of svalue(b) <- txt. This will bypass gWidgets behaviour.

OskarHansson commented 7 years ago

Thanks for the tip! For me this is no longer a serious issue (when using the above solutions) so you can close this issue if you want.