473,659 Members | 3,631 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Refactoring question

I currently have a GUI application (using Tkinter) in which all the code
is placed in a single script. This means that the GUI bits are a bit too
tightly bound to the "under-the-hood" logic of the app. Here's an
example snippet:

def installPackage( self):

self.package = self.infotable. getcurselection ()
if not self.package:
showwarning('Er ror', 'Please select a package name.')
return
else:
self.packagenam e = self.package[0][1]
self.status.set ('Installing %s' % self.packagenam e)
self.showProgre ss()
self.file = os.popen('echo %s | sudo -S /sw/bin/fink -y
install %s' % (self.passtext, self.packagenam e), 'r', os.O_NONBLOCK)
for line in self.file:
self.textdispla y.configure(sta te='normal')
self.textdispla y.insert(END, line)
self.update()
self.textdispla y.see(END)
self.textdispla y.configure(sta te='disabled')
self.endProgres s()
self.categorytr ee.selection_se t('All')
self.listCatego ryPackages()

I'd like to refactor and separate the GUI code from the back-end code;
for instance, to move the "self.file = os.popen" bits into a separate
category. I want to do this so that I can redesign the GUI using another
toolkit, if I so choose, such as wxPython.

What's the best way to do this? Can anyone point me in the right
direction? How could, for instance, the top snippet be rewritten to
separate the Tkinter parts from the generic stuff?

--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com
Apr 4 '07 #1
3 1208
On Behalf Of Kevin Walzer
What's the best way to do this? Can anyone point me in the
right direction? How could, for instance, the top snippet be
rewritten to separate the Tkinter parts from the generic stuff?
I like to use the broadcaster/broker recipe at
http://aspn.activestate.com/ASPN/Coo...n/Recipe/81983

I added a few features (such as decorators for listener functions --
see below sig).
There are other recipes out there, such as PyDispatcher.

Basically, I have GUI events translated into broadcaster events (by
passing lambdas that call broadcaster.Bro adcast() to the event
binders), which are received by controller functions/classes.

Feedback (status/progress) is also communicated via broadcaster
events.

Something I tried on my current project, which is going fairly well,
is first writing a command-line version, then writing a GUI version,
with the same controller back-end used in each case, and the
controller communicating progress/results via the same interface. This
approach has made me keep presentation and logic very loosely
coupled.

So for instance, the view class would send request for processing,
which the controller gets.
The controller performs the requested action, sending broadcasts of
progress (note that the controller can start a worker thread for the
processing, but the broadcasts should be made on the GUI thread...)

broadcaster.Bro adcast( "progress", "start", (100, "Doing your
bidding now..." ) ) # number of items we will process

# ...
broadcaster.Bro adcast( "progress", "progress", (i, "Working on
item %i" % i ) ) # current item
# ...

broadcaster.Bro adcast( "progress", "end", (100, "Done!") )

Depending on who is showing the progress, this might go onto a status
bar, progress dialog, the console, a log file, and so on, or some
combination thereof -- the controller doesn't know or care.

When the controller is finished, it asks the broker for a view, and
calls show results on the view

view = broker.Request( "view" )
view.ShowResult s( results )

That could have been done equally with the broadcaster, but for some
reason I like the broker here (it makes the view "dumber").

Regards,
Ryan

--
Ryan Ginstrom

=============== ===
# listener decorators

def BrokerRequestHa ndler( title ):
"""A decorator for broker listeners

@param title: the title to provide

The decorated function must take no arguments
(it can retrieve them using CurrentData())
"""

def decorator(func) :
broker.Register ( title, func )
return func
return decorator

def BroadcasterEven tHandler( source, title ):
"""A decorator for broadcaster event handlers

@param source: the broadcast source
@param title: the title of the broadcast

The decorated function must take no arguments
(it can retrieve them using CurrentData())
"""

def decorator(func) :
broadcaster.Reg ister( func, source, title )
return func
return decorator

# example ...
@BrokerRequestH andler( "meaning of life" )
def getMeaningOfLif e():
return 42

## A little more complicated for class methods. I stole this technique
from WCK

# Lifted shamelessly from WCK (effbot)'s wckTkinter.bind
def EventHandler( source, title ):
"""Dectorat or for event-handling methods"""

def decorator(func) :
func.Broadcaste rEvent = (source, title)
return func
return decorator

class FrameController :
"""Controll er for the main frame window"""

def __init__( self ):

for key in dir(self):
method = getattr(self, key)
if hasattr(method, "BroadcasterEve nt") and
callable(method ):
source, title = method.Broadcas terEvent
broadcaster.Reg ister( method,
source=source,
title=title )
@EventHandler( "event", "onExport" )
def onExport( self ):
"""Handles the onExport broadcast by exporting the database to
the requested format"""

format = broadcaster.Cur rentData()
# Perform export...

Apr 4 '07 #2
On Apr 3, 11:41 pm, "ginstrom" <ginst...@tree. odn.ne.jpwrote:
On Behalf Of Kevin Walzer
What's the best way to do this? Can anyone point me in the
right direction? How could, for instance, the top snippet be
rewritten to separate the Tkinter parts from the generic stuff?

I like to use the broadcaster/broker recipe athttp://aspn.activestat e.com/ASPN/Cookbook/Python/Recipe/81983

I added a few features (such as decorators for listener functions --
see below sig).
There are other recipes out there, such as PyDispatcher.

Basically, I have GUI events translated into broadcaster events (by
passing lambdas that call broadcaster.Bro adcast() to the event
binders), which are received by controller functions/classes.

Feedback (status/progress) is also communicated via broadcaster
events.

Something I tried on my current project, which is going fairly well,
is first writing a command-line version, then writing a GUI version,
with the same controller back-end used in each case, and the
controller communicating progress/results via the same interface. This
approach has made me keep presentation and logic very loosely
coupled.

So for instance, the view class would send request for processing,
which the controller gets.
The controller performs the requested action, sending broadcasts of
progress (note that the controller can start a worker thread for the
processing, but the broadcasts should be made on the GUI thread...)

broadcaster.Bro adcast( "progress", "start", (100, "Doing your
bidding now..." ) ) # number of items we will process

# ...
broadcaster.Bro adcast( "progress", "progress", (i, "Working on
item %i" % i ) ) # current item
# ...

broadcaster.Bro adcast( "progress", "end", (100, "Done!") )

Depending on who is showing the progress, this might go onto a status
bar, progress dialog, the console, a log file, and so on, or some
combination thereof -- the controller doesn't know or care.

When the controller is finished, it asks the broker for a view, and
calls show results on the view

view = broker.Request( "view" )
view.ShowResult s( results )

That could have been done equally with the broadcaster, but for some
reason I like the broker here (it makes the view "dumber").

Regards,
Ryan

--
Ryan Ginstrom

=============== ===
# listener decorators

def BrokerRequestHa ndler( title ):
"""A decorator for broker listeners

@param title: the title to provide

The decorated function must take no arguments
(it can retrieve them using CurrentData())
"""

def decorator(func) :
broker.Register ( title, func )
return func
return decorator

def BroadcasterEven tHandler( source, title ):
"""A decorator for broadcaster event handlers

@param source: the broadcast source
@param title: the title of the broadcast

The decorated function must take no arguments
(it can retrieve them using CurrentData())
"""

def decorator(func) :
broadcaster.Reg ister( func, source, title )
return func
return decorator

# example ...
@BrokerRequestH andler( "meaning of life" )
def getMeaningOfLif e():
return 42

## A little more complicated for class methods. I stole this technique
from WCK

# Lifted shamelessly from WCK (effbot)'s wckTkinter.bind
def EventHandler( source, title ):
"""Dectorat or for event-handling methods"""

def decorator(func) :
func.Broadcaste rEvent = (source, title)
return func
return decorator

class FrameController :
"""Controll er for the main frame window"""

def __init__( self ):

for key in dir(self):
method = getattr(self, key)
if hasattr(method, "BroadcasterEve nt") and
callable(method ):
source, title = method.Broadcas terEvent
broadcaster.Reg ister( method,
source=source,
title=title )

@EventHandler( "event", "onExport" )
def onExport( self ):
"""Handles the onExport broadcast by exporting the database to
the requested format"""

format = broadcaster.Cur rentData()
# Perform export...
I usually put all my GUI code into their own methods(s) and call those
methods from the __init__(). I do the same with the logic (where
applicable). This makes the code easier to manipulate and/or import.

In wxPython, you can also use XRC to define most of the common
elements of you GUI. I've found this method to be very helpful in
keeping my code short and easy to read, for GUI code.

Mike

Apr 4 '07 #3
ky******@gmail. com wrote:
On Apr 3, 11:41 pm, "ginstrom" <ginst...@tree. odn.ne.jpwrote:
>>On Behalf Of Kevin Walzer
What's the best way to do this? Can anyone point me in the
right direction? How could, for instance, the top snippet be
rewritten to separate the Tkinter parts from the generic stuff?
I like to use the broadcaster/broker recipe athttp://aspn.activestat e.com/ASPN/Cookbook/Python/Recipe/81983
[lots of code that was pretty irrelevant to the reply]
>
I usually put all my GUI code into their own methods(s) and call those
methods from the __init__(). I do the same with the logic (where
applicable). This makes the code easier to manipulate and/or import.

In wxPython, you can also use XRC to define most of the common
elements of you GUI. I've found this method to be very helpful in
keeping my code short and easy to read, for GUI code.
While talking about keeping things short and easy to read, maybe you
could be a bit more considerate in your quoting practices. We really
didn't need to see all the code quoted to hear what you had to say ...

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Recent Ramblings http://holdenweb.blogspot.com

Apr 4 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
2024
by: Peter Dembinski | last post by:
I am trying to write Master Thesis on refactoring Python code. Where should I look for information? -- http://www.dembiñski.prv.pl
4
1599
by: | last post by:
Hi, Refactoring a winform causes problems if moving this form to a subdirectory in the same project. What is the workaround for this and will this be fixed in future? Thanks /BOB
0
1969
by: Andre Baresel | last post by:
Hello together, just a year ago I was searching arround for a tool supporting refactoring for c++. I've seen implementations for java and was impressed how an IDE can help with such a feature. Just rename classes / member / parameter with a mouse click. reduce the size of a method by transforming parts of it into a seperate
2
2100
by: Sachin Garg | last post by:
Hi, I was trying to find (like many others here) a tool for refactoring C++ code as I have lately been noticing that I spend most of my coding time doing refactoring and some refactoring which I skip, due to the enormous effort it seems to require, usually comes back to me with larger costs. I read a few comp.lang.c++ threads over past few years regarding
11
3264
by: Master of C++ | last post by:
Hi, I am writing a simulation package in C++, and so far I've written about 8000 lines of code and have about 30 classes. I haven't used C++ exceptions so far (for various reasons). The only two "resources" I use are memory and file I/O and whenever there is a memory allocation failure or file I/O failure I just simply call a custom assert-type function to check, print a error message and abort. This seems to be OK for now (for the...
6
3346
by: Dean Ware | last post by:
Hi, I am part way through developing a C++ application. I am developing it on my own and using VC++ 6.0. I am now at the stage where I wish to start tidying up my code. I have lots of superfluous code that is hard to be sure about removing. For example, I have classes that are ONLY used in methods that are never
8
2008
by: Frank Rizzo | last post by:
I keep hearing this term thrown around. What does it mean in the context of code? Can someone provide a definition and example using concrete code? Thanks.
15
4388
by: Simon Cooke | last post by:
Does anyone know of any tools for refactoring header files? We're using a third party codebase at work, and pretty much every file includes a 50Mb precompiled header file. I'm looking for a tool that will let us figure out which header files are actually needed by each .cpp, and allow us to break this up so that we're not including the world in each one. Ideally, the same tool would also recognize where #includes can be replaced with...
0
972
by: bryan rasmussen | last post by:
Hi, I'm doing a sort of symbolic linking app in Windows for my own enjoyment, and figured I would do it in python for the same reason + learning the language. The following functions could obviously do with some refactoring. One obvious thing would be to make wordsetter and wordsforfolder more generic, and just pass a few extra parameters. But that seems sort of stupid. Any suggestions on refactoring here? other improvements?
3
4629
Frinavale
by: Frinavale | last post by:
I have been researching the best approach to migrating a VB6 application into a VB.NET application. There is a lot of information out there but most of it recommends that you "train in the migration process before jumping into it". One site even recommends that this training process should take at least 2-3 weeks. I'm not sure how you can train for such a process...but maybe I'll find something while I'm researching. I was wondering if anyone...
0
8428
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8337
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8748
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8531
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
4175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2754
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1978
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1739
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.