How to add a border to a python console-menu - python

I'm having some issues using the console-menu module for Python. I made my menu with the constructor and added a few items to it, but i'm having a hard time figuring out how to add formatting to it. There is a MenuStyle class in the documentation that I think I need to use:
classconsolemenu.format.MenuStyle(margins=None, padding=None, border_style=None, border_style_type=None, border_style_factory=None)
The full documentation is available here: https://console-menu.readthedocs.io/en/latest/consolemenu.html
It's pretty short and to the point. I just don't understand what to do. Do I need to construct the border object and then use it in the ConsoleMenu() constructor? or add it in later?

From reading the documentation it looks like you need to set ConsoleMenu's formatter argument to an instance of MenuFormatBuilder. example2.py has the following that might help you:
menu_format = MenuFormatBuilder().set_border_style_type(MenuBorderStyleType.HEAVY_BORDER)
...
menu = ConsoleMenu("Root Menu", "This is the Root Menu Subtitle", formatter=menu_format)

Related

Manipulating userforms using xlwings

I was trying to find out the methods of the pywin32 object of a userform ComboBox in Excel, but I honestly has no idea what I'm doing and got nowhere.
VBA Code (Sending combobox object to python):
Private Sub ComboBox1_Change()
s = test(ComboBox1)
End Sub
Python Code :
#xw.func
def test(obj):
print(obj._dict__)
So, the print above returned this :
{'_oleobj_': <PyIDispatch at 0x03957A90 with obj at 0x01218C8C>, '_username_': 'IMdcCombo', '_olerepr_': <win32com.client.build.LazyDispatchItem object at 0x03FB0FD0>, '_mapCachedItems_': {}, '_builtMethods_': {}, '_enum_': None, '_unicode_to_string_': None, '_lazydata_': (<PyITypeInfo at 0x03957B50 with obj at 0x0121919C>, <PyITypeComp at 0x03957B68 with obj at 0x012196F4>)}
I guess I was expecting to see the same methods/properties found in VBA, but I have no idea what to take from this.
Anyone knows a way to manipulate userform/controls directly from python using xlwings?
Specifically I'm looking for dynamically adding new controls to the userform, reading/modifying controls attributes, and ideally modifying their events, all through python.
I guess I was expecting to see the same methods/properties found in VBA, but I have no idea what to take from this.
You can take anything from this, but this isn't a real Combobox nor something from COM environment - it's just a "wrapper" object over a COM object, implemented via IDispatch interface, and it's possibily thanks to the win32com dependency.
Because of that there's no an "intellisense"-like feature, but you're still able to use properties/methods:
#xw.func
def test(obj):
# accesing method
obj.AddItem('Hello world!')
# accesing property
obj.Enabled = False
also you can pass an UserForm as obj to add a new control to it:
#xw.func
def test(obj):
# add new label
control = obj.Add('Forms.Label.1')
# accesing property
control.Caption = 'Hello world!'
When looking under the documentation for xlWings under the Shapethere does seem to be access to all properties.
Under missing features, you can find a workaround using .api to access all vba methods. Through this you could create and modify controls, just like you would do in VBA.
Also what you could do is using the macro(name)-function you could create functions in VBA to modify, create comboboxes and pass values to the function, i.e to create a combobox at position x, y , width, height and pass these parameters trough python.
As it seems, you cannot access events trough xlWings. But i've found IronPython, it uses the .NET interop facilities to access the excel object and events. As you can see under the documentation, you can work with the excel object as you would do in C#, VB.NETetc..
So as a conclusion, i would suggest you looking up the documentations of both. As they both reveal the excel object to python you should be able to do what you want with one of them.

How to add an Entry to a gtk.ComboBox

I'm trying to add an Entry field to a gtk.ComboBox. The easy way out would be to use gtk.ComboBoxEntry, but I read somewhere that ComboBoxEntry is deprecated.
I tried setting the property "has-entry" to True, but this can only be done on construction.
Then I tried, somewhat desperately, to add this as a keyword parameter to the constructor, but 'has_entry' doesn't seem to be an existing keyword parameter.
So, how do I set a property at construction time in Python?
Thanks to help on the #gtk+ IRC channel, I found out that (at least some) of the pygtk functions are available by their C-names in Python. So, it is possible to write:
cbboxe = gtk.combo_box_new_with_entry() or
cbboxe = gtk.combo_box_text_new_with entry()
Strangely enough, it was also indicated that
gtk.ComboBox(has_entry = True)
should work. #ebassi (IRC) showed me it worked - I tried it here but wasn't able to get it accepted. Same PyGTK version and all. YMMV :)
(Thanks #SiHa for reminding me I had this question still open!)

Number of arguments in Tkinter classes

relative noob here! I'm running 2.7, if that helps.
I'm trying to call a function defined in my main application class in a different function (I think that's called inheritance?) But I keep having problems with the number of args I put into my function!
Here's the function (is it called a method? if not, what's a method) I'm trying to call:
def student_list_updater(self, list):
self.StudentListDisplay.delete(0, END)
for student in list:
self.StudentListDisplay.insert(END, student)
And here's the function I'm calling it in (it's inheriting student_list_updater, right?):
def OnRemoveClick(self, student_list_updater):
self.student_list_updater = student_list_updater
index = self.StudentListDisplay.curselection()
index = int(index[0])
del student_list_temp[index]
self.student_list_updater(student_list_temp)
Thank you for the help in advance!
It's a little difficult to understand your question without more of the code, but hopefully this answer points you in the right direction.
First, to clarify, methods are just functions that can be accessed through an instance of a class, so yes, these are methods, but they're also functions--don't get too hung up on it. Next, I don't think inheritance is necessary here--inheritance will be one class inheriting attributes from another, and I believe all of your methods are only in one class (correct me if I'm mistaken).
Now, as to your code: it's giving you an error that one of your methods takes a number of arguments, and you gave it a different number. Well, to me, it looks like you only need to pass one argument for this whole process: student_list_temp to student_list_updater(). Once again, I can't say for sure that this will solve your problems, based on the lack of code you posted, but this might work:
def student_list_updater(self, studentlist): #change list to studentlist,
self.StudentListDisplay.delete(0, END) #Python already has a list() method
for student in studentlist:
self.StudentListDisplay.insert(END, student)
def OnRemoveClick(self): #Remove student_list_updater from the args, it has no value
#self.student_list_updater = student_list_updater #this doesn't do anything
index = self.StudentListDisplay.curselection() #This part I can't really comment on
index = int(index[0]) #without knowing the contents of the
del student_list_temp[index] #Listbox and student_list_temp,
self.student_list_updater(student_list_temp) #but this should call student_list_updater()
#and update the Listbox if it's working
The last thing I want to point out is how you call OnRemoveClick() will probably change. If you're calling it from a Button, it would look like this:
self.btn = Button(self, text='GO', command=self.OnRemoveClick)
Note that you're not passing any arguments to it.
Hope that helps. You also might want to take a look at https://docs.python.org/2/tutorial/classes.html and https://docs.python.org/2/tutorial/modules.html to clear up any classes and functions questions you might have.

Is it considered bad practice to use a widgets title attribute to refer to it?

Would it be considered bad practice to use a widgets title attribute to refer it?
For example I have a number of custom radioBoxCtrls on a panel
I only ever need to get/set all the values at once
so the container class(a panel) for the radioBoxCtrls objects has the following methods
get_options()
set_options()
To set options for all the radioBoxCtrls a dictionary is passed to the set_options() method.
Each key, value pair in the dictionary is a title of a radioBoxCtrl and the title of the button on the radioBoxCtrl that should be set
def set_options(self, options={}):
"""
This method sets which radio button is selected
on each RadioBoxCtrl object
#param options: A dictionary
Each key is the title of a RadioBoxCtrl
each keys value is the button on the radio box that is to be selected
"""
for option_box in self.option_boxes:
if option_box.title in options.keys()
option_box.set_selected_button(options[option_box.title])
def get_options(self):
"""
This method returns a dictionary of the selected options
Each key is the title of a RadioBoxCtrl object
and each keys value is the name of the button selected on the radio box
"""
options = defaultdict(list)
for option_box in self.option_boxes:
options[option_box.title]=option_box.get_selected_btn()
return options
So (in an attempt to be clear) when I call the set method from my controller
I pass in a dictionary like so:
options = {"Name of radioBoxCtrl": "Option 2", ... }
self.gui.optionsPanel.set_options(options)
Why the hell do you want do that? (you may ask)
Short answer: mvc
I want to create a suitable layer of abstraction. All that my controller needs to know with
regard to the options is how to get them to pass to the model when some processing needs to be done and how set them when a config file is loaded...
I thought it would simplify things if I could just call one method to set and vice-versa -but Im not so sure now!
I realize that this is probably more of question on the acceptability of refering to objects by some string attribute they posses, which in my case just happens to be the title.. so feel free to answer it accordingly..
Please feel free to improve the title of question(I wasnt really sure how to word it) and add tags.
Thanks
I can't tell whether the gurus would call it bad practive. I just know I'd never do it - it is slower, more error-prone, possibly makes it very hard to change a title's name (admittedly, only if you hardcode it everywhere) and (arguably) very inelegant. At least you should associate te options with the widget's identity, which still smells imho, but at least has a few problems less. Maybe that whole part of the application should be refactored to be less centralized so the issue disappears completely.
Edit on how to refactor: Honestly, I can't tell - I know little about the application. The obvious approach would be subclassing all widgets and making them responsible for somehow getting the options and changing accordingly. But I can't tell whether that's really feasible.

Silverlight databinding with IronPython and Datagrid

We've been successfully using clrtype with IronPython 2.6 and
Silverlight for databinding, based on the example provided by Lukás(:
http://gui-at.blogspot.com/2009/11/inotifypropertychanged-and-databinding.html
We create the binding when we create the datagrid columns programatically. Because we are using IronPython some of the static databinding techniques you would normally use with C# don't work.
I've been trying (and failing) to get a column in the grid show
different colors based on databinding.
I've got the colored bubble showing in the grid, but can't get
databinding to the color to work. First the basics.
This is the xaml for the bubble with a fixed color:
<DataTemplate xmlns='http://schemas.microsoft.com/client/2007'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Ellipse Stroke="#FF222222" Height="15" Width="15">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop x:Name="bubbleColor" Offset="0.694"
Color="#FF00FF40" />
<GradientStop Color="#FFE6E6E6"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
I can add a column based on this template very simply. The loadXaml function is a thin wrapper around XamlReader.Load:
from com_modules.loadxaml import loadXaml
from System.Windows.Controls import DataGridTemplateColumn
column = DataGridTemplateColumn()
column.CellTemplate = loadXaml('templatecolumn')
column.Header = 'Bubble'
grid.Columns.Add(column)
If I try to naively specify a binding in the xaml then I get a
PARSER_BAD_PROPERTY_VALUE when I attempt to load the xaml (so no hope of
setting up the binding after load):
<GradientStop x:Name="bubbleColor" Offset="0.694" Color="{Binding color}" />
One approach I tried was to create a ValueConverter. Here is the
skeleton of the class I created:
from System import Type
from System.Globalization import CultureInfo
from System.Windows.Data import IValueConverter
class ColorConverter(IValueConverter):
_clrnamespace = "Converters"
__metaclass__ = clrtype.ClrClass
#clrtype.accepts(object, Type, object, CultureInfo)
#clrtype.returns(object)
def Convert(self, value, targetType, parameter, culture):
pass
#clrtype.accepts(object, Type, object, CultureInfo)
#clrtype.returns(object)
def ConvertBack(self, value, targetType, parameter, culture):
pass
As there is a _clrnamespace specified I thought I might then be able to use this converter in xaml. Trying to reference the ColorConverter class in the Converters namespace in a resources dictionary again causes blow ups when loading the xaml.
Setting this up programatically would be ideal. Anyone got any ideas?
I don't know anything about IronPython, but I know that you cannot bind to a Color in Silverlight, regardless of the language used. This has caused me many grievances. In Silverlight 3 you can only bind properties on a FrameworkElement, and since GradientStop is a DependencyObject, it will not work. The good news is that Silverlight 4 will get rid of that limitation and allow you to bind properties on DependencyObject. I haven't tried it though, so I cannot say for sure. More info here:
http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx#dobind
At the moment, what you could do is to bind the Fill property on the Ellipse instead. But then you will have to create the entire LinearGradientBrush in your converter code, so it's a bit complicated.

Categories

Resources