Directly modify a specific item in a TKinter listbox? - listbox

This is one of those just-making-sure-I-didn't-miss-anything posts.
I have a TKinter GUI in Python 2.7.3 that includes a listbox, and there are circumstances where I'd like to directly modify the text of a specific item at a known index. I've scoured the documents and there's no lb.itemset() method or anything like it. As best I can tell I have two options, either of which would work but just seem kind of klunky to me:
lb.delete() the old item and lb.insert() the new value for it at the same index (including a step to re-select the new value if the old deleted one happened to be selected).
Create a listvariable for the listbox, then use get() and set() on it -- with a pile of replace/split/join acrobatics in between to handle the differing string formats involved.
Is there some simpler, more direct way to do it that I'm missing? Or have I turned up all the available options?

Assuming from silence that there's nothing I missed. I went with option 2 -- the acrobatics weren't quite as complex as I'd thought. I just created a behind-the-scenes list wrapped up in a class; every time I update the list, the class syncs up the content of the listbox by doing a ' '.join on the list then setting the listbox's listvariable to the resulting string.

Related

How to tell which file came from which input?

I have two file input controls on my view. In my controller the first parameter is IEnumerable<HttpPostedFileBase> documentFiles and all this is working perfectly.
The only problem is I don't know which file came from which file input control. Maybe if there are two files added they will be in the order the controls were presented... or maybe they are in the order the user added them? I can test and find this out, but another issue would also be if only one file is uploaded (both fields are optional).
Off the top of my head, the only solution I can think of would involve creating a hidden field that tracks which inputs have been populated (and, possibly, track the order in which they are populated as well if that determines the order in which they are received).
Surely there is a more "correct" way to handle this though that I must be overlooking?
It turns out that it does put the files in the order the controls are displayed, and to my pleasant surprise it actually includes a null entry in the list if there is no file. So there will always be two entries and I can determine which is which file based on its position.

How to deactivate an item of the context-menu (Mozilla addon-kit)

I would like to deactivate all top-level context-menu-items of my addon under certain circumstances (for example when the addon has been disabled by the user).
Somehow I can't figure out how this is done except for completely destroying the item; but I'd prefer using a method that allows easy switching between deactivation and activation.
There must be some way around the missing of an remove- or deactivate-method. For items that are not on top-level but belong to a submenu this is easyly done with the methods addItem() and removeItem() of the parentMenu.
EDIT:
Items on top-level do have the property parentMenu- which is null though. So the problem seems to be that the context-menu.js only offers removeItem/addItem methods for the submenus but not for the parentNode of top-level items.
I still find the context-menu-api kind of confusing. There is no onClick method for the item. It seems to me that I need a content script for every item, instead(?)
Also, I havent found a way to place items on top-level where I want (instead of being forced to the bottom).
Upcoming changes in the SDK's context-menu module due to ship at the end of the month should allow you to use addItem()/removeItem(). This re-written implementation of the context-menu module will ship in SDK 1.13. Currently there is no way to 'deactivate' an item programmatically until this new version is available.

auto_complete_for: prevent the first item from being auto-selected

The auto_complete_for dealio from script.aculo.us is great an all, but is there a way for me to selectively disable the fact that it always auto-selects the first item in the list?
The problem is that, if I want to type my own entry that is new, and novel, I don't want the first item in the list to be auto-selected. The reason is because when I TAB out of the field, it selects, and fills the text box with that first item.
I got around that, somewhat, by making the first item in the list the same as what I'm typing, but that's not perfect either, because the auto_complete list doesn't always update with every keystroke, depending on how fast I type. I've tried setting the list refresh rate to the lowest value (1 millisecond) but no go.
What I really want is an option in "auto_complete_for" that doesn't select that first item at all - the same way that Google Instant doesn't automatically select the first suggested search phrase - you have to arrow-down to select one.
Maybe I can do this via an HTML option that I'm missing?
Looking at the source, there doesn't appear to be an option for that, but I bet if you changed line 284 of controls.js to this.index = -1; it would do what you want.
Otherwise, it might be time to look for a different autocomplete widget.
If your requirements are too far away from the available plugin, then I guess there is no point in tinkering around. Its best to write your own JS code.
You might want to consider this: https://github.com/laktek/jQuery-Smart-Auto-Complete
or this : https://github.com/reinh/jquery-autocomplete
I'll add another alternative that works great with Rails 3:
http://github.com/crowdint/rails3-jquery-autocomplete
I recently implemented auto complete for more than a field for Rails 2.0.2.
The plugin I used is:- https://github.com/david-kerins/auto_complete . Not sure if it supports Rails 3.
I have also encountered issues on implementing the above scenario and have posted questions( Implementing auto complete for more than one field in Rails ; Implementing a OnClick kind of functionality and formatting wrt Rails Partial-Views ) on stackoverflow for the same, I have been lucky on getting things working for me based on my requirement.
Kindly refer to these questions, they might have relevance to your requirement.

How to create a changelog?

I'm building a site that shows changes in deals that we have in our db. For example, if a deals status changes from pending to win, I want to show it, and if the value goes up or down, I want to show it, that kind of thing. Also, if you open the overview page, I want it to show the history of changes. So I need some kind of change logging, to be able to look in the past. How do I do this?
It is a rails project, but I think that's irrelevant.
I doubt there is any generic solution to this problem.
You can roll out your own. Start by considering all objects that need change logging. How many types are there? How often do you expect changes to occur? This will help you estimate the potential number of changes throughput you'll need to be dealing with. If there aren't too many, just stick them into database. If you are generating a lot, try storing to comma-separated-value file.
I have implemented a similar system before. I had 3 types of changes: 1) property value change, 2) adding of a value to a list, 3) removing value from a list.
I used the following format, stored in a log file:
//For type 1)
1,2011/01/01 00:00:00,MyObject,myProperty,oldValue,newValue
//For type 2)
2,2011/01/01 00:00:00,MyObject,myListProperty,addedValue
//For type 3)
3,2011/01/01 00:00:00,MyObject,myListProperty,removedValue
This captured most information I needed. The value parts were just some user-readable summary of the changed/added/removed property value.
Paper Trail Gem
Since you're on Rails, take a look at the PaperTrail gem. It does exactly what you're looking for and is beautifully built. You'll just need to add in a callback so that your overview page knows that a change occurred. But for the history of a model, just use the built-in PaperTrail functionality.

Hpricot CSS Class search

I am working on some code that scrapes a page for two css classes on a page. I am simply using the Hpricot search method for this as so:
webpage.search("body").search("div.first_class | div.second_class")
...for each item found i create an object and put it into an array, this works great except for one thing.
The search will go through the entire html page and add an object into an array every time it comes across '.first_class' and then it will go through the document again looking for '.second_class', resulting in the final array containing all of the searched items in the incorrect order in the array, i.e all of the '.first_class' objects, followed by all the '.second_class' objects.
Is there a way i can get this to search the document in one go and add an object into the array each time it comes across one of the specified classes, giving me an array of items that is in the order they are come across in on the page i am scraping?
Any help much appreciated. Thanks
See the section here on "Checking for a Few Attributes":
http://wiki.github.com/why/hpricot/hpricot-challenge
You should be able to stack the elements in the same way as you do attributes. This feature is apparently possible in Hpricot versions after 2006 Mar 17... An example with elements is:
doc.search("[#href][#type]")
Ok so it turned out i was mistaken and this didn't do anything different to what i previously had at all. However, i have come up with a solution, wether it is the most suitable or not i am not sure. It seems like a fairly straight forward for an annoying problem though.
I now perform the search for the two classes above as i mentioned above:
webpage.search("body").search("[#class~='first_class']|[#class~='second_class']")
However this still returned an array firstly containing all the divs with a class of 'first_class' followed by all divs with a class of 'second_class'. So to fix this and get an array of all the items as they appear in order on the page, i simply chain the 'add_class' method with my own custom class e.g. 'foo_bar'. This then allows me to perform another search on the page for all divs with just this one tag, thus returning an array of all the items i am after, in the order they appear on the page.
webpage.search("body").search("[#class~='first_class']|[#class~='second_class']").add_class("foo_bar")
webpage.search("body").search("[#class~='foo_bar']")
Thanks for the tip. I hadn't spotted that in the documentation and also found another page i hadnt seen either. I have fixed this with the following line:
webpage.search("body").search("[#class~='first_class']|[#class~='second_class']")
This now adds an object into the array each time it comes across one of the above classes in the document. Brilliant!

Resources