I'm designing a (hopefully) simple GUI application using PyQt4 that I'm trying to make scalable. In brief, the user inputs some basic information and sends it into one of n queues (implementing waiting lists). Each of these n queues (QTableviews) are identical and each have controls to pop, delete from and rearrange its queue. These, along with some labels etc. form a 'module'. Currently my application is hardcoded to 4 queue modules, so there's elements named btn_table1_pop, btn_table2_pop...etc; four copies of every single module widget. This is obviously not very good UI design if you always assume your clients have four people that need waiting lists! I'd like to be able to easily modify this program so 8 people could use it, or 3 people could use it without a chunk of useless screen-estate!
The really naive solution to programming my application is duplicating the code for each module, but this is really messy, unmaintainable, and bounds my application to always four queues. A better thought would be to write functions for each button that sets an index and calls a function that implements the common logic, but I'm still hardcoded to 4, because the branch logic and the calling functions still have to take into account the names of the elements. If there was a way to 'vectorize' the names of the elements so that I could for example write
btn_table[index]_pop.setEnabled(False)
...I could eliminate this branch logic and really condense my code. But I'm way too new at Python/PyQt to know if this is 1) even possible? or 2) how to even go about it/if this is even the way to go?
Thanks again, SO.
In case anyone is interested I was able to get it working with dummybutton = getattr(self,'btn_table{}'.format(i)) and calling the button's methods on dummybutton.
Related
At the moment I'm struggling a bit with Python asyncio, and with event loops in general. It's probably a rather uncommon experiment, though: I'm trying if I could implement my own event loop (i.e. subclassing asyncio.AbstractEventLoop or similar) which allows me to 'plug' other main loops inside it (e.g. the native main loop of GTK/GLib or another UI toolkit).
I could then instantiate and run my loop, and use it as usual, e.g. using async/await syntax. Beyond that, I can add and remove "other main loops" to it, and it would process this ones as well. For example, I could add the GLib loop to it, so I can use async functions in my GTK project. Maybe even other ones alongside.
So, this surely needs some glue code for each kind of "other loop", which implements an interface that I have to define, and takes care of processing that particular loop when I add it to "my loop". I want this interface to be versatile, i.e. it should be possible to not only use GLib's loop, but all kinds of other ones.
I'm not sure what that interface should indeed be, and how it interacts with my loop implementation. Is there a common pattern or idea how to integrate main loops, which works for GLib and a lot of other ones?
It should also be resource efficient. Otherwise I could just have a while True loop inside run_forever which constantly checks for tasks to execute (and executes them), and constantly calls a particular method of my "other loop" interface, say ForeignLoop.process(self), which could then e.g. call gtk_loop.get_context().iteration(False) for GTK. This would keep one CPU core constantly busy.
So my questions are: Are there better ways to implement my loop idea? Do you think it is possible (without an insane bunch of code, which maybe is even hard to maintain)?
There are already some projects out there which have at least GLib loop integration: There is https://github.com/beeware/gbulb and https://github.com/python-trio/trio, but it will take me ages to understand what they do, since they do a lot of other things as well. There is also https://github.com/jhenstridge/asyncio-glib. That's much more compact and looks interesting. Unfortunately, I don't understand this one as well so far. It does some things that I cannot find much documentation about. What is its basic mechanism? It looks like it works with UNIX' select (as the whole default event loop impl does), but how is that wired to GLib's main loop? And, is that a common approach or a very GTK specific trick?
It turned out to be important to note: My question is not if the idea itself is useful or not. Unless there is a very significant reason to consider it as not useful, at least. :)
I'm currently working on my first larger scale piece of software, and am running into an ugly situation. Most features I have added thus far have required an additional private member in order to function properly. This is due to the fact that most features have been giving more power to the user, by allowing them to modify my program through either arguments passed to the constructor, or methods that specify a setting they wish to toggle.
I currently have around 13 private variables, and can see this spiraling out of control. The constructor code is starting to look very ugly. I was wondering if this is just a result of adding features, or if there was a creative/clever way to avoid this issue.
I would recommend abstracting the concept of of "behavior"
You'd have a base class "behavior" which actually performs the requested action, or manages the modification to behavior. Then you can initialize your code using an array of "parameters" and "behaviors".
Your startup code would become a simple "for" loop, and to add/remove behaviors you just add or remove to the list.
Of course, the tough part of this is actually fitting the activities of the behavior classes into your overall program flow. But I'm guessing that a focus on "single responsibility principle" would help figure that out.
So I'm using tkinter to make a GUI and at the moment I have several different frames. The way I programmed it is by just using one massive class but everywhere I look online (like here - https://pythonprogramming.net/change-show-new-frame-tkinter/), people are using a new class for every single "page". Is what I am doing wrong/not efficient or is it fine?
Unfortunately I cannot show my code as it's for a CA but the below is similar:
class App(tk.Frame):
def __init__(self):
tk.Frame.__init(self)
self.PageOne()
def PageOne(self):
coding stuff
def PageTwo(self):
pass
What you are doing is probably fine. I say "probably" because it depends on many factors which you haven't explained in your question.
The tutorial you referenced came from a stackoverflow answer that was explicitly addressing how to switch between two frames. It's not necessarily a recommended way to code, it's simply one of many ways.
That being said, if you have distinct pages then you might find it easier to manage your code if each page was a self-contained object. Doing so gives each page its own namespace, so you don't have to worry that one page is accidentally modifying the data that belongs to some other page. Plus, for larger projects it allows you to implement each page in a separate file so you don't end up with one huge file full of code.
Since not all GUIs are oriented around the concept of pages, this technique isn't a one-size-fits-all solution. It's OK to make each page a class, it's also OK to create each page via a function. The choice depends on many variables, such as your comfort with working with classes, the size of your project, the type of UI you're creating, and so on.
I am implementing a workflow management system, where the workflow developer overloads a little process function and inherits from a Workflow class. The class offers a method named add_component in order to add a component to the workflow (a component is the execution of a software or can be more complex).
My Workflow class in order to display status needs to know what components have been added to the workflow. To do so I tried 2 things:
execute the process function 2 times, the first time allow to gather all components required, the second one is for the real execution. The problem is, if the workflow developer do something else than adding components (add element in a databases, create a file) this will be done twice!
parse the python code of the function to extract only the add_component lines, this works but if some components are in a if / else statement and the component should not be executed, the component apears in the monitoring!
I'm wondering if there is other solution (I thought about making my workflow being an XML or something to parse easier but this is less flexible).
You cannot know what a program does without "executing" it (could be in some context where you mock things you don't want to be modified but it look like shooting at a moving target).
If you do a handmade parsing there will always be some issues you miss.
You should break the code in two functions :
a first one where the code can only add_component(s) without any side
effects, but with the possibility to run real code to check the
environment etc. to know which components to add.
a second one that
can have side effects and rely on the added components.
Using an XML (or any static format) is similar except :
you are certain there are no side effects (don't need to rely on the programmer respecting the documentation)
much less flexibility but be sure you need it.
I'm starting out with wxPython and have been working my way through every tutorial and example I can get my hands on. I've run into a slight problem, however, and it has to do with the wx.App versus the wx.Frame and which should contain specific methods. Just about every example I've seen don't go much beyond layouts/sizers and event handling, none really tackle project organization of a wxPython project.
For example, I have a method that gets a list of folders. The way most examples would deal with this would be to stick the method right in the frame class. This method has the potential to be used in several other parts of the application, so it would make more sense to store it at the application class level.
How should I organize and call "universal" methods like these so that I don't clutter up my frame classes.
UPDATE:
To clarify, the "list of folders" was just an example, my actual method does a lot more work. What I'm saying is I have code that isn't Frame-specific. If I had this in the application class, what is the best way to call it from and event method in my frame.
I'm looking for actual project organization techniques, not programming fundamentals.
Your classes that inherit from wxWidgets/wxPython data types should not implement any business logic. wxWidgets is a GUI library, so any subclasses of wxApp or wxFrame should remain focused on GUI, that is on displaying the interface and being responsive to user actions.
The code that does something useful should be separated from wx, as you can decide later to use it in some web or console application and you don't want to create wxApp object in such case. You can also decide later on to move some computations to separate 'worker threads', while your GUI will be the 'main thread' - responsive, and repainted properly during long lasting computations.
Last but not least - the classes that encapsulate your logic might tend to grow during projects lifetime. If they're mixed with your GUI classes they will grow faster, and finally they become so complex that you're almost unable to debug them...
While having them separated leads to clean code when you don't mix bugs in logic with bugs in GUI (refreshing/layout/progress bar etc.). Such approach has another nice feature - ability to split work among GUI-people and logic-people, which can do their work without constant conflicts.
As Mark stated you should make a new class that handles things like this.
The ideal layout of code when using something like wxWidgets is the model view controller where the wxFrame class only has the code needed to display items and all the logic and business rules are handled by other class that interact with the wxFrame. This way you can change logic and business rules with out having to change your interface and change (or swap) your interface with out having to change your logic and business rules.
I probably should have been a lot clearer from the start, but I found what I was looking for:
http://wiki.wxpython.org/ModelViewController/
Burried within the wxpython wiki, I found several simple, concrete examples of MVC projects.
In a proper OOP design, this would be independent or part of a filesystem class - it wouldn't be part of the app or the frame.