CLI+GUI

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michele Simionato

    CLI+GUI

    I wonder what is the recommended way of using Tkinter
    together with a command line oriented application.
    I have in mind something like that:

    import cmd,sys

    class CMD(cmd.Cmd):
    def do_this(self,*a rgs):
    draw_a_diagram( )
    def do_that(self,*a rgs):
    draw_another_di agram()
    def do_exit(self,*a rgs):
    sys.exit(0)

    c=CMD()
    c.cmdloop()

    Here the methods ``draw_a_diagra m`` and ``draw_another_ diagram``
    should do what you expect. Notice that I don't want to use
    different windows, the graphs should be displayed on the same
    window one over the other. BTW, I am not really displaying
    diagrams, this is only the simplest example I can figure out
    of graphics program driven by a command line interpreter.
    I want to stay with the CLI interface, which I like a lot
    thanks to the readline and completion support, the easy
    of use and the easy of implementation.

    I have no idea of how to do that, except via contorsions
    such as saving (a representation of) the diagrams in a file
    and having a separated Tkinter process that periodically look at the
    file, changing the display if the file has been updated. I
    guess there is a better way, since this is a quite common issue.
    Any suggestion?

    TIA,

    Michele
  • Michele Simionato

    #2
    Re: CLI+GUI

    [email protected] (Michele Simionato) wrote in message news:<2259b0e2. 0308080948.5a95 [email protected] ogle.com>...[color=blue]
    > I wonder what is the recommended way of using Tkinter
    > together with a command line oriented application.[/color]

    Replying to myself ...

    I tried to implement what I discussed in my previous mail via the
    threading module:

    #cmdriven.py

    import Tkinter as t
    import cmd,threading

    root=t.Tk()
    s=t.StringVar()
    s.set('ciao')
    label=t.Label(r oot,textvariabl e=s)
    label.pack()

    class Cmd(cmd.Cmd):
    def do_display(self ,arg):
    s.set(arg)
    def do_quit(self,ar g):
    root.quit()
    return 'quit' # anything <> None will do the job

    def cmdloop(stringv ar):
    try: Cmd().cmdloop()
    finally: pass # gracefully exit if sometimes goes wrong

    thread=threadin g.Thread(target =cmdloop,args=( s,))
    thread.start()
    root.mainloop()

    It works if I do something like

    $ python cmdriven.py
    (Cmd) display hello
    (Cmd) display It works!
    (Cmd) quit

    However, I wonder if this is a robust solution and if I should expect
    problems in more complicate situations (some time passes ... I have
    just discovered that this script hangs under Windows 98!)

    BTW, I have another question, why the Cmd class does not have a default quit
    method? Looking at the source I see that any method returning something
    different from None will stop the command loop, and so I have used this
    hack, but I don't like it. Maybe I have missed something in the documentation?
    Thanks,

    Michele

    Comment

    • Eric Brunel

      #3
      Re: CLI+GUI

      Michele Simionato wrote:[color=blue]
      > [email protected] (Michele Simionato) wrote in message news:<2259b0e2. 0308080948.5a95 [email protected] ogle.com>...
      >[color=green]
      >>I wonder what is the recommended way of using Tkinter
      >>together with a command line oriented application.[/color]
      >
      >
      > Replying to myself ...
      >
      > I tried to implement what I discussed in my previous mail via the
      > threading module:
      >
      > #cmdriven.py
      >
      > import Tkinter as t
      > import cmd,threading
      >
      > root=t.Tk()
      > s=t.StringVar()
      > s.set('ciao')
      > label=t.Label(r oot,textvariabl e=s)
      > label.pack()
      >
      > class Cmd(cmd.Cmd):
      > def do_display(self ,arg):
      > s.set(arg)
      > def do_quit(self,ar g):
      > root.quit()
      > return 'quit' # anything <> None will do the job
      >
      > def cmdloop(stringv ar):
      > try: Cmd().cmdloop()
      > finally: pass # gracefully exit if sometimes goes wrong
      >
      > thread=threadin g.Thread(target =cmdloop,args=( s,))
      > thread.start()
      > root.mainloop()
      >
      > It works if I do something like
      >
      > $ python cmdriven.py
      > (Cmd) display hello
      > (Cmd) display It works!
      > (Cmd) quit
      >
      > However, I wonder if this is a robust solution and if I should expect
      > problems in more complicate situations (some time passes ... I have
      > just discovered that this script hangs under Windows 98!)[/color]

      I don't know if this is the problem, because you didn't say exactly when the
      script hangs, but Tkinter apparently has problems when calls to it are made from
      a thread different from the one into which it was initialized. I'd use an Event
      between Tkinter's thread and Cmd's thread, checking it regularly with Tkinter's
      after method.

      HTH
      --
      - Eric Brunel <eric.brunel@pr agmadev.com> -
      PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

      Comment

      • Michele Simionato

        #4
        Re: CLI+GUI

        Eric Brunel <eric.brunel@pr agmadev.com> wrote in message news:<bh7hs3$dt [email protected] .fr>...[color=blue]
        > I don't know if this is the problem, because you didn't say exactly when the
        > script hangs, but Tkinter apparently has problems when calls to it are made
        > from a thread different from the one into which it was initialized. I'd use
        > an Event between Tkinter's thread and Cmd's thread, checking it regularly
        > with Tkinter's after method.
        >
        > HTH[/color]

        It hangs immediately when I start the script by clicking on its icon.
        What do you mean with "I'd use an Event" ? I thought an Event object
        is automatically generated when I click on a widget, or press a key,
        or something. Are you saying can I can programmaticall y generate an
        Event, faking a real mouse/key press? How so? That is something I
        always wanted to know ;)


        Michele

        Comment

        • Alex Martelli

          #5
          Re: CLI+GUI

          Michele Simionato wrote:
          [color=blue]
          > Eric Brunel <eric.brunel@pr agmadev.com> wrote in message
          > news:<bh7hs3$dt [email protected] .fr>...[color=green]
          >> I don't know if this is the problem, because you didn't say exactly when
          >> the script hangs, but Tkinter apparently has problems when calls to it
          >> are made from a thread different from the one into which it was
          >> initialized. I'd use an Event between Tkinter's thread and Cmd's thread,
          >> checking it regularly with Tkinter's after method.
          >>
          >> HTH[/color]
          >
          > It hangs immediately when I start the script by clicking on its icon.
          > What do you mean with "I'd use an Event" ? I thought an Event object
          > is automatically generated when I click on a widget, or press a key,
          > or something. Are you saying can I can programmaticall y generate an
          > Event, faking a real mouse/key press? How so? That is something I
          > always wanted to know ;)[/color]

          When talking of event objects in a context of synchronizing threads,
          it seems likely one is talking about threading.Event in specific. As
          the online docs for the threading module say:

          Event()
          A factory function that returns a new event object. An event manages a flag
          that can be set to true with the set() method and reset to false with the
          clear() method. The wait() method blocks until the flag is true.

          all details are at:




          There is no implication whatsoever that such objects are "automatica lly
          generated" by any GUI toolkit. The terminology confusions are, alas,
          almost inevitable.


          Alex

          Comment

          • Eric Brunel

            #6
            Re: CLI+GUI

            Michele Simionato wrote:[color=blue]
            > Eric Brunel <eric.brunel@pr agmadev.com> wrote in message news:<bh7hs3$dt [email protected] .fr>...
            >[color=green]
            >>I don't know if this is the problem, because you didn't say exactly when the
            >>script hangs, but Tkinter apparently has problems when calls to it are made
            >>from a thread different from the one into which it was initialized. I'd use
            >>an Event between Tkinter's thread and Cmd's thread, checking it regularly
            >>with Tkinter's after method.
            >>
            >>HTH[/color]
            >
            >
            > It hangs immediately when I start the script by clicking on its icon.
            > What do you mean with "I'd use an Event" ? I thought an Event object
            > is automatically generated when I click on a widget, or press a key,
            > or something.[/color]

            I wasn't thinking about this Event class. I thought about the one described here:


            It allows very basic communications between threads.
            [color=blue]
            > Are you saying can I can programmaticall y generate an
            > Event, faking a real mouse/key press? How so? That is something I
            > always wanted to know ;)[/color]

            Generating a *Tk* event is quite easy: just use the event_generate method that
            exists on all widgets. I used it to generate simple events, often user-defined
            one. The syntax is simple:

            myWidget.event_ generate("<<MyE vent>>")

            If you have a binding for "<<MyEvent> >" for myWidget, you can trigger it this way.

            I never tried to pass event detail, though.

            HTH
            --
            - Eric Brunel <eric.brunel@pr agmadev.com> -
            PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

            Comment

            • Cousin Stanley

              #7
              Re: CLI+GUI

              | It hangs immediately when I start the script
              | by clicking on its icon.

              Michele ....

              I experience hangs with SIMPLE Python/Tk scripts
              regularly using Windows 98 and this has been
              a source of much frustration, almost to the point
              of giving up on Tk ....

              Your tk_cli script works for me, displaying the Tk window,
              accepting display whatEver commands, and displaying the
              results back in the Tk window ....

              However, it will hang _sometimes_ at the (Cmd) prompt
              on the second pass through after displaying the first
              time as expected ....

              --
              Cousin Stanley
              Human Being
              Phoenix, Arizona


              Comment

              • Eric Brunel

                #8
                Re: CLI+GUI

                Cousin Stanley wrote:[color=blue]
                > Michele ....
                >
                > I experience hangs with SIMPLE Python/Tk scripts
                > regularly using Windows 98 and this has been
                > a source of much frustration, almost to the point
                > of giving up on Tk ....[/color]

                Same problem, different solution: it made me give up on Windows 98... ;-)

                FYI, and just to make this post a bit more useful, it seems to be a problem in
                Windows 95/98, since no problem ever occured with the same scripts/distros on
                Win2k or WinXP, not to mention Unices...
                --
                - Eric Brunel <eric.brunel@pr agmadev.com> -
                PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

                Comment

                • Fredrik Lundh

                  #9
                  Re: CLI+GUI

                  Eric Brunel wrote:
                  [color=blue]
                  > Same problem, different solution: it made me give up on Windows 98... ;-)[/color]

                  quoting microsoft's lifecycle page:

                  "Mainstream support for Windows 98/98 SE ended on June 30th 2002,
                  and no-charge incident support and extended hotfix support ends on
                  June 30th 2003."
                  [color=blue]
                  > FYI, and just to make this post a bit more useful, it seems to be a problem in
                  > Windows 95/98, since no problem ever occured with the same scripts/distros on
                  > Win2k or WinXP, not to mention Unices...[/color]

                  iirc, the problem is that (some versions of the) Tk DLL locks up during the cleanup
                  phase (probably due to a race problem), and Win2k/XP is smart enough to kill the
                  process when that happens.

                  the sourceforge bug tracker has more details.

                  </F>




                  Comment

                  • Cousin Stanley

                    #10
                    Re: CLI+GUI

                    | Same problem, different solution:
                    | it made me give up on Windows 98 ...

                    Eric ...

                    I do plan on eventually moving to a Linux distribution
                    in the near future, but have to deal with what I have
                    at the moment ...

                    The limited experimentation that I've done using Knoppix,
                    proved to me that Tk under Win98 was the problem
                    as the same scripts that hang intermittently under Win98
                    ran under Knoppix without any problems ...

                    It's also good to hear that the Tk problems
                    under later versions of Windows are alleviated ...

                    Thanks for the info ...

                    --
                    Cousin Stanley
                    Human Being
                    Phoenix, Arizona


                    Comment

                    • Michele Simionato

                      #11
                      Re: CLI+GUI

                      Eric Brunel <eric.brunel@pr agmadev.com> wrote in message news:<bh8da1$ti [email protected] .fr>...[color=blue]
                      > Cousin Stanley wrote:[color=green]
                      > > Michele ....
                      > >
                      > > I experience hangs with SIMPLE Python/Tk scripts
                      > > regularly using Windows 98 and this has been
                      > > a source of much frustration, almost to the point
                      > > of giving up on Tk ....[/color]
                      >
                      > Same problem, different solution: it made me give up on Windows 98... ;-)
                      >
                      > FYI, and just to make this post a bit more useful, it seems to be a problem in
                      > Windows 95/98, since no problem ever occured with the same scripts/distros on
                      > Win2k or WinXP, not to mention Unices...[/color]

                      These are very good news to me, since it means that the fault is not
                      mine
                      and that the approach I came out is not unreasonable (I hope). No bad,
                      for my first program using thread ;) For the record, I NEVER use
                      Windows for development(act ually I use it only for watching DVDs),
                      nevertheless I
                      wanted to try the script to check about portability issues.


                      Michele

                      Comment

                      • Miki Tebeka

                        #12
                        Re: CLI+GUI

                        Hello Michele,
                        [color=blue]
                        > I wonder what is the recommended way of using Tkinter
                        > together with a command line oriented application.[/color]
                        I know it's not Tkinter but what about wxPython with wxCrust?

                        HTH.
                        Miki

                        Comment

                        • dan

                          #13
                          Re: CLI+GUI

                          Late to this thread, but --

                          in a similar situation, I just put:

                          _tkinter.doonee vent(_tkinter.D ONT_WAIT)

                          in my main logic loop (cmd interpreter in your case), instead of
                          calling Frame.mainloop( ). I believe Frame.update() does something
                          similar but for some reason this worked better.

                          ISTM this would be cleaner (and safer) than using threads. You can do
                          all your draw operations from your command line routines, and they
                          will get displayed as soon as the routine returns to your main loop to
                          wait for more input.

                          Am I missing something?

                          -dbm

                          [email protected] (Michele Simionato) wrote in message news:<2259b0e2. 0308080948.5a95 [email protected] ogle.com>...[color=blue]
                          > I wonder what is the recommended way of using Tkinter
                          > together with a command line oriented application.
                          > I have in mind something like that:
                          >
                          > import cmd,sys
                          >
                          > class CMD(cmd.Cmd):
                          > def do_this(self,*a rgs):
                          > draw_a_diagram( )
                          > def do_that(self,*a rgs):
                          > draw_another_di agram()
                          > def do_exit(self,*a rgs):
                          > sys.exit(0)
                          >
                          > c=CMD()
                          > c.cmdloop()
                          >
                          > Here the methods ``draw_a_diagra m`` and ``draw_another_ diagram``
                          > should do what you expect. Notice that I don't want to use
                          > different windows, the graphs should be displayed on the same
                          > window one over the other. BTW, I am not really displaying
                          > diagrams, this is only the simplest example I can figure out
                          > of graphics program driven by a command line interpreter.
                          > I want to stay with the CLI interface, which I like a lot
                          > thanks to the readline and completion support, the easy
                          > of use and the easy of implementation.
                          >
                          > I have no idea of how to do that, except via contorsions
                          > such as saving (a representation of) the diagrams in a file
                          > and having a separated Tkinter process that periodically look at the
                          > file, changing the display if the file has been updated. I
                          > guess there is a better way, since this is a quite common issue.
                          > Any suggestion?
                          >
                          > TIA,
                          >
                          > Michele[/color]

                          Comment

                          • Michele Simionato

                            #14
                            Re: CLI+GUI

                            danbmil99@yahoo .com (dan) wrote in message news:<fbf8d8f2. 0308120814.75e8 [email protected] gle.com>...[color=blue]
                            > Late to this thread, but --
                            >
                            > in a similar situation, I just put:
                            >
                            > _tkinter.doonee vent(_tkinter.D ONT_WAIT)
                            >
                            > in my main logic loop (cmd interpreter in your case), instead of
                            > calling Frame.mainloop( ). I believe Frame.update() does something
                            > similar but for some reason this worked better.
                            >
                            > ISTM this would be cleaner (and safer) than using threads. You can do
                            > all your draw operations from your command line routines, and they
                            > will get displayed as soon as the routine returns to your main loop to
                            > wait for more input.
                            >
                            > Am I missing something?
                            >
                            > -dbm[/color]

                            I like quite a lot you suggestion! "dooneevent " was the method I was
                            looking for! Actually, I would rather prefer to avoid threads for such a
                            simple program. Thanks to the power of Python I wrote down a working
                            script in less than five minutes, even if probably I will need more
                            than five minutes to understand what I wrote ;)
                            Here it is:

                            import Tkinter as t
                            import cmd

                            root=t.Tk()
                            s=t.StringVar()
                            s.set('ciao')
                            label=t.Label(r oot,textvariabl e=s)
                            label.pack()

                            class Cmd(cmd.Cmd):
                            def do_display(self ,arg):
                            s.set(arg)
                            root.tk.dooneev ent(0)
                            def do_quit(self,ar g):
                            root.quit()
                            return 'quit' # anything != None will do

                            Cmd().cmdloop()


                            I will later try it on Windows 98. Dunno exactly what "dooneevent " is doing,
                            I searched my python directories for "dooneevent " and found only one
                            usage of "doonevent" and copied it ;) Unfortunately "dooneevent "
                            has no docstring, however few experiments show that "dooneevent ()"
                            is the same that "dooneevent (0)" whereas "dooneevent (1)" hangs up
                            (it is waiting for what??)

                            Thanks for your help,


                            Michele

                            Comment

                            • dan

                              #15
                              Re: CLI+GUI

                              davesum99@yahoo .com (smarter_than_y ou) wrote in message
                              [color=blue]
                              > Also note that there are at least three ways to get this behavior:
                              >
                              > _tkinter.doonee vent(TCL_DONT_W AIT)
                              > Frame.update()
                              > Tkinter.dooneev ent(0) #this is new to me! You found a third way to
                              > call it
                              >[/color]
                              that would be:

                              root.tk.dooneev ent()

                              but anyway --

                              in my experiments, this last way (Michelle's way) has very bad timing,
                              if you care about that sort of thing. Both the _tkinter call and
                              update() seem to be more reactive.

                              Comment

                              Working...