[Tkinter-discuss] Fwd: WxPython -> Tkinter

Olrik Lenstra o.lenstra at gmail.com
Sun Nov 2 22:41:03 CET 2008


I see, now if I recall correctly I can run the scan by using the
following command:
thread.start_new_thread(myfunction,("Thread No:1",2))

So I'd replace myfunction with the scan function and it would run at
the same time?

Regards,
Olrik

2008/11/2 Guilherme Polo <ggpolo at gmail.com>:
> On Sun, Nov 2, 2008 at 7:17 PM, Olrik Lenstra <o.lenstra at gmail.com> wrote:
>> Hmm, The program worked and no error messages popped up but the GUI
>> still hung when I tried running the scan.
>
> If the scan blocks the application then that safe_yield is not
> supposed to work, it wouldn't work in wxpython either (using only
> that). Do use polling to determine when the scan finishes for example
> ? That would be the place to run safe_yield. If this is not the case,
> and the scanner doesn't let you work it in an asynchronous way, then
> you will have to run that scan in another thread/process and the gui
> will not block.
>
>> Maybe this is a help:
>>
>> The program is a program that does a couple of scans like ipconfig / dxdiag etc.
>> While the scan is running the GUI has a status bar in which the text
>> changes when the scan is running a new part of the scan.
>> like: "TSO is now making an ipconfig log"
>>
>> Thanks again! :)
>> Regards,
>> Olrik
>>
>> 2008/11/2 Guilherme Polo <ggpolo at gmail.com>:
>>> On Sun, Nov 2, 2008 at 2:40 PM, Guilherme Polo <ggpolo at gmail.com> wrote:
>>>> On Sun, Nov 2, 2008 at 12:34 PM, Olrik Lenstra <o.lenstra at gmail.com> wrote:
>>>>> I would like to thank you already for all the help you've given me, it
>>>>> is really appreciated :)
>>>>
>>>> You are welcome.
>>>>
>>>>> I decided to update to Python2.6 instead of using the tile pack. My
>>>>> application now shows the GUI again.
>>>>> So I added the code you gave me to prevent the window from hanging
>>>>> once I execute my scan.
>>>>> I get the following Traceback:
>>>>>
>>>>> D:\Documents\OLPrograms\TroubleShooting Olrik\sourcecode\TSO(source)>python TSO.
>>>>> pyw
>>>>> Exception in Tkinter callback
>>>>> Traceback (most recent call last):
>>>>>  File "D:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
>>>>>    return self.func(*args)
>>>>>  File "D:\Documents\OLPrograms\TroubleShooting Olrik\sourcecode\TSO(source)\TSO
>>>>> main.pyw", line 29, in OnScan
>>>>>    TSOscn.Scan(root, status)
>>>>>  File "D:\Documents\OLPrograms\TroubleShooting Olrik\sourcecode\TSO(source)\TSO
>>>>> scn.pyw", line 23, in Scan
>>>>>    TSOex.safe_yield(Frame, True)
>>>>>  File "D:\Documents\OLPrograms\TroubleShooting Olrik\sourcecode\TSO(source)\TSO
>>>>> ex.pyw", line 75, in safe_yield
>>>>>    window_disabler(window)
>>>>>  File "D:\Documents\OLPrograms\TroubleShooting Olrik\sourcecode\TSO(source)\TSO
>>>>> ex.pyw", line 90, in window_disabler
>>>>>    if widget.instate(['!disabled']):
>>>>> AttributeError: Button instance has no attribute 'instate'
>>>>>
>>>>
>>>> That is because Button is not a ttk.Button, but a "normal"
>>>> Tkinter.Button. I didn't know before you would be using windows, but
>>>> since this is the case, you may try substituting the use of instate
>>>> and state calls (that are available only for ttk widgets) by the use
>>>> of widget.wm_attributes('-disabled', 1),
>>>> widget.wm_attributes('-disabled', 0) and
>>>> widget.wm_attributes('-disabled'). I will be able to test it here
>>>> later since my new pc arrived with a windows vista.
>>>>
>>>
>>> I have changed it a bit now, please retry with this one:
>>>
>>> import sys
>>>
>>> inside_tkyield = False
>>> disabled_wins = {}
>>> platform_win = 'win' in sys.platform
>>> if not platform_win:
>>>    import ttk
>>>
>>> def safe_yield(window, only_if_needed=False):
>>>    window_disabler(window)
>>>    try:
>>>        return tk_yield(window, only_if_needed)
>>>    finally:
>>>        window_enabler(window)
>>>
>>>
>>> def window_enabler(window):
>>>    for widget, flags in disabled_wins.iteritems():
>>>        if platform_win:
>>>            window.wm_attributes('-disabled', 0)
>>>        else:
>>>            ttk.Widget.state(widget, flags)
>>>    disabled_wins.clear()
>>>
>>>
>>> def window_disabler(window):
>>>    if platform_win and not int(window.wm_attributes('-disabled')):
>>>        window.wm_attributes('-disabled', 1)
>>>        disabled_wins[window] = 1
>>>        return
>>>
>>>    widgets = window.children.values()
>>>    widgets.append(window)
>>>
>>>    for widget in widgets:
>>>        if widget.instate(['!disabled']):
>>>            prev_flags = widget.state(['disabled'])
>>>            disabled_wins[widget] = prev_flags
>>>
>>>
>>> def tk_yield(window, only_if_needed=False):
>>>    # wx implements this differently based on the backend it is using
>>>    global inside_tkyield
>>>    if inside_tkyield:
>>>        if not only_if_needed:
>>>            raise RuntimeError("safe_yield called recursively")
>>>
>>>        return False
>>>
>>>    inside_tkyield = True;
>>>
>>>    window.update()
>>>    window.update_idletasks()
>>>
>>>    inside_tkyield = False;
>>>
>>>    return True
>>>
>>> It should work under windows, but it is not very nice elsewhere right
>>> now unfortunately.
>>>
>>>>> D:\Documents\OLPrograms\TroubleShooting Olrik\sourcecode\TSO(source)>
>>>>>
>>>>> I don't know if it makes a difference, But I think you should know
>>>>> that I use different files that import other applications (made by me)
>>>>> Example:
>>>>>
>>>>> TSO.pyw is the main script, this looks if the very first argument is
>>>>> "TSO.pyw", if it is, run "TSOmain.TSO()"
>>>>> TSOmain.pyw is the GUI and the GUI only, from there it calls other files etc.
>>>>> I hope that wasn't too confusing.
>>>>>
>>>>> Thanks again, I really appreciate it.
>>>>>
>>>>> Regards,
>>>>> Olrik
>>>>>
>>>
>>>
>>> --
>>> -- Guilherme H. Polo Goncalves
>>>
>>
>
>
>
> --
> -- Guilherme H. Polo Goncalves
>


More information about the Tkinter-discuss mailing list