Search code examples
rgwidgets

gWidgets how to handle invalid reference if window is closed


How should I handle the situation in the gWidgets example below?

What I am trying to achieve with this little graphical user interface is to have a sub window that can be updated. It works well. However, if the user close the 'Click history' window by clicking the 'X' an error arise:

Error: attempt to call 'GetBuffer' on invalid reference 'view'

It seem that the reference/pointer to the sub window is lost. I have tried various strategies to solve the problem. For example to use tryCatch and re-create the window. That resulted in a new window opened for every click. Can the reference be retained somehow?

Update: I'm using R 3.2.2 and the gWidgetsRGtk2 toolkit on a Windows 7 system.

mainWindow <- function(){

  require(gWidgets)

  # This works well until the log window is closed.
  # Next click gives this error:
  # Error: attempt to call 'GetBuffer' on invalid reference 'view'

  w_main <- gwindow(title="Main", visible=TRUE)
  b_time <- gbutton("Show time!", container=w_main)
  w_time <- gwindow(title="Click history", visible=FALSE)
  t_time <- gtext("", container=w_time)

  addHandlerChanged(b_time, handler = function(h, ...) {

    # Log click.
    insert(t_time, paste(date()))

    # Show window.
    visible(w_time) <- TRUE  

  } )

}

Update2: Implementation according to jverzani's suggestion seem to work fine. In fact I have tried something similar, but I think I forgot the <<-

mainWindow <- function(){

  require(gWidgets)

  # This works well also when the log window has been closed!

  w_main <- gwindow(title="Main", visible=TRUE)
  b_time <- gbutton("Show time!", container=w_main)
  w_time <- gwindow(title="Click history", visible=FALSE)
  t_time <- gtext("", container=w_time)
  closed <- FALSE

  addHandlerChanged(b_time, handler = function(h, ...) {

    if(closed){
       # Re-create window.
       w_time <<- gwindow(title="Click history", visible=FALSE)
       t_time <<- gtext("", container=w_time)
       closed <<- FALSE
    }

    # Log click.
    insert(t_time, paste(date()))

    # Show window.
    visible(w_time) <- TRUE  

  } )

  addHandlerDestroy(w_time, handler = function(h, ...) {

    # Subwindow closed!
    closed <<- TRUE

  } )

}

Solution

  • Here is the solution as provided by @jverzani

    mainWindow <- function(){
    
      require(gWidgets)
    
      # This works well also when the log window has been closed!
    
      w_main <- gwindow(title="Main", visible=TRUE)
      b_time <- gbutton("Show time!", container=w_main)
      w_time <- gwindow(title="Click history", visible=FALSE)
      t_time <- gtext("", container=w_time)
    
      addHandlerChanged(b_time, handler = function(h, ...) {
    
        if(!isExtant(w_time)){
          # Re-create window.
          w_time <<- gwindow(title="Click history", visible=FALSE)
          t_time <<- gtext("", container=w_time)
        }
    
        # Log click.
        insert(t_time, paste(date()))
    
        # Show window.
        visible(w_time) <- TRUE  
    
      } )
    
    }