Iterating over controls in wxPython in order to save session data - python

I have a GUI written in wxPython (with boa constructor).
I would like to save a user's session to a file, to be loaded the next time the application starts.
I would like to avoid saving each value 'by hand' by iterating over the controls and saving their values to a dictionary.
Is there a way to get a hold of all the wxIDs used in the application, and their corresponding widgets?

You don't need the IDs at all, just start from the top level window and recursively enumerate all the children using wxWindow::GetChildren() method. Then, for each child, you will need to dynamically determine its type (this is simpler if you only use controls of a few types) and save its value. You may also find it useful to specify the names (not labels) for your controls when creating them to have a more convenient unique identifier for each of them than a numeric ID.

IMHO you are going at this wrong. The state of a user's session is best not stored in the values of the controls. The state should be stored in a 'model'. The 'view' should query the model when it needs to display the state of the model, and when it wants to save the state to a file. http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller.
This makes lots of things easier, even trivial, including your problem.

I would look at the PersistenceManager mechanism in wx.lib.agw. Here are the original docs for it: http://xoomer.virgilio.it/infinity77/AGW_Docs/persist.persistencemanager.PersistenceManager.html
And here are the newer docs:
https://docs.wxpython.org/wx.lib.agw.persist.persistencemanager.PersistenceManager.html#wx.lib.agw.persist.persistencemanager.PersistenceManager
Alternatively, you can probably use the frame or panel's GetChildren() method to grab all the widgets and pull the values from them, but I think the PersistenceManager would make more sense.

Related

How to keep multiple QAbstractItemModel classes in sync

I've been working really hard trying to find a solution to this for the past few weeks. I have committed to a direction now, but I am still not entirely satisfied with what I have come up with. Asking this now purely out of curiosity and for hope of a more proper solution for next time.
How on earth do I keep multiple QAbstractItemModel classes in sync that are referring to the same source data but displaying in different ways in the tree view?
One of the main reasons for using model/view is to keep multiple views in sync with one another. However, if each of my views requires different data being displayed at the same column, as far as I can tell I need to then subclass my model to two different models with different implementations that will then cater to each of those unique view displays of the same items.
Underlying source items are the same, but data displayed is different. Maybe the flags are different as well, so that the user can only select top level items in one view and then can only select child items in the other view.
I'll try to give an example:
Lets say my TreeItem has three properties: a, b, c.
I have two tree views: TreeView1, TreeView2. Each has two columns.
TreeView1 displays data as follows: column1 -> a, column2 -> b
TreeView2 displays data as follows: column1 -> a, column2 -> c
I then need to create two different models, one for TreeView1 and one for TreeView2, and override the data and flags methods appropriately for each.
Since they are now different models, even though they are both referring to the same TreeItem in the background, they are no longer staying in sync. I have to manually call the refresh on TreeView2 whenever I change data on TreeView1, and vice versa.
Consider that column1, or property a, is editable and allows the user to set the name of the TreeItem. Desired behaviour would be for the edit that is done in TreeView1 to instantly be reflected in TreeView2.
I feel like I am missing some important design pattern or something when approaching this. Can anyone out there see where I am going wrong and correct me? Or is this a correct interpretation?
Thanks!
One way to do it is to use viewmodels. Have one QAbstractItemModel adapter to your underlying data model. All interaction must pass through that model. When you need to further adapt the data to a view, simply use a proxy view model class that refers to the adapter above and reformats/adapts the data for a view. All the view models will then be automagically synchronized. They can derive from QAbstractProxyModel, although that's not strictly necessary.
There is no other way of doing it if the underlying source of data doesn't provide change notification both for the contents and for the structure. If the underlying data source provides relevant notifications, it might as well be a QAbstractItemModel to begin with :)

Django: how to transfer scattered data to a template?

Introduction
In Django, when the data you want to display on a template is included in one object, It's f**** easy. To sum up the steps (that everyone knows actually):
You Write the right method to get your object in your model class
You Call this method in your view, passing the result to the template
You Iterate on the result in the template with a for loop, to display your objects in a table, for example.
Now, let's take a more complex situation
Let's say that the data you want to display is widely spread over different objects of different classes. You need to call many methods to get these data.
Once you call these different methods, you got different variables (unsimilar objects, integers, list of strings, etc.)
Nevertheless, you still want to pass everything to a template and display a pretty table in the end.
The problem is:
If you're passing all the raw objects containing the data you need to your template, it is completely unorganised and you can't iterate on variables in a clean way to get what you need to display your table.
The question is:
How (which structure) and where (models? views?) should I organize my complex data before passing it to a template?
My idea on this (which can be totally wrong):
For each view that need "spread data" to pass to a template, I could create a method (like viewXXX_organize_data()) in views.py, that would take the raws objects and would return a data structure with organized data that would help me to display a table by iterating on it.
About the data structure to choose, I compared lists with dictionaries
dictionaries have key so it's cleaner to call {{dict.a-key-name}} rather than {{ tabl.3}} in the template.
lists can be sorted, so when you need to sort by date the elements you want to display, dictionary is not helpful, arghh, stuck again!
What do you think about all that? Thanks for reading until there, and sharing on this!
With your question you are entering in a conceptual/architectural domain rather than in a "this particular view of the data in my project is hard to represent in the template layer of django". So I will try to give you the birds view (when flying and not on the ground) of the problem and you can decide for yourself.
From the first philosophy box in the django template language documentation it's clearly stated that templates should have as little program logic as possible. This indicates that the representation of the data used in the template should be simple and totally adapted to the template you are trying to build (this is my interpretation of it). This approach indicates that you should have a layer responsible for intermediating the representation of your data (models or other sources) and the data that your template needs to achieve the final representation you want you users to see.
This layer can simple stay in your view, in viewXXX_organize_data, or in some other form respecting to a more complex/elaborated architecture (see DCI or Hexagonal).
In your case I would start by doing something like viewXXX_organize_data() where I would use the most appropriate data structures for the template you are trying to build, while keeping some independence from the way you obtain your data (through models other services etc).
You can even think of not using you model objects directly in the template and creating template specific objects to represent a certain view of the data.
Hope this helps you make a decision. It's not a concrete answer but will help you for sure make a decision and then staying coherent all trough your app.

Using custom role in QTreeView instead of DisplayRole

A simple question, (hopefully with a simple answer).
QTreeView will pass Qt.DisplayRole to the model's data function when fetching rows for display, by default.
But say I wanted to pass 'MyAwesomeTreeDisplayRole' instead of Qt.DisplayRole, what would I need to do?
I can't seem to find anything about where the view decides to use displayrole or how to override it.
Just before you ask why I want to do such awful things..
Basically, my QAbstractItemModel is intended to be usable both for a treeview (1 column) and a tableview (multiple columns, based on parent).
Using the same DisplayRole for both types of views doesn't really work, since then I'm forced to return the same data for both. This results in me only seeing the first column in the treeview when I want to return a concatenation of a couple of columns.
I think the simplest way would be to just use custom roles (TreeDisplayRole and TableDisplayRole).
Thanks in advance.
I don't know, how to do it in python, but you have to create your own delegate to render items data. Delegate is actually the object, that requests any data from indices and renders it
Note, that in common case QTreeView is able to show multiple columns, you should only have columnCount set incorrectly for top-level index
I've used QTreeView to view a simple table with many columns - it works well - you can adjust the column count by sending it the columnCountChanged signal. So I'm not sure you need to do what you are asking.
But I've used ItemDelegates too: use my_treeview.setItemDelegate() to point the treeview to your item delegate. If this subclasses QStyledItemDelegate then it doesn't need to do much work - it can mostly just pass it all through to super.
The user roles then are just agreed between your custom ItemDelegate and your ItemModel and can be anything you like as long as they are >= than QtCore.Qt.UserRole.
(Edit: Sorry, I put this in as a new answer but it's really just an elaboration on what Lol4t0 said - apart from the columnCountChanged thing)

Use an SQL-like function with GAE's datastore

I have a property (isFull) in a model whose value depends on other properties in that same model (counter).
So far I've been setting the property's value myself whenever any of the properties it depends on change. I wrote a function isFull() that checks the counter and returns True or False. But I can't use it with a query unless I fetch everything then iterate over the results checking if any of them isFull, which is BAD I know..
Is there a way to use my function with filter or gql ? or is there a different way of doing it? I know I can use a filter to check the counter but it goes more complex than that in some cases where I need to check dates, a counter and another flag all at the same time.
Use a ComputedProperty to store your computed value as a property in the datastore that you can filter on.
I don't know how to automatically recalculate a property when another has changed. While you could hide some of the updating by creating a custom property you would still have to manually update it when you are updating properties it depends on.
You might instead want to make the need for the isFull property obsolete by chaining the filtering, something along the lines of
query.filter('counter >', 42)
query.filter('created <', datetime(2011,12,21))
query.filter('created >', datetime(2011,12,19))
query.filter('myflag =', true)

Move or copy an entity to another kind

Is there a way to move an entity to another kind in appengine.
Say you have a kind defines, and you want to keep a record of deleted entities of that kind.
But you want to separate the storage of live object and archived objects.
Kinds are basically just serialized dicts in the bigtable anyway. And maybe you don't need to index the archive in the same way as the live data.
So how would you make a move or copy of a entity of one kind to another kind.
No - once created, the kind is a part of the entity's immutable key. You need to create a new entity and copy everything across. One way to do this would be to use the low-level google.appengine.api.datastore interface, which treats entities as dicts.
Unless someone's written utilities for this kind of thing, the way to go is to read from one and write to the other kind!

Categories

Resources