How to make links in a QWizard's subtitle clickable? - python

I am constructing a little wizard following Qt's classwizard example.
Now I set the subTitle of my QWizard instance to some html text that includes a link.
I know about QLabel.setOpenExternalLinks(True) but how do I achieve the same effect with a QWizard's subTitle?
I looked at QWizardOptions but there is nothing there.
Please take a look at the following image:
I want to make www.plugincafe.com open in the default browser.
Thanks for reading.
EDIT: I am already calling self.setSubTitleFormat(1) where self is the QWizard instance and 1 is the enum value for Qt::RichText because I don't know how to get the proper enum constant in PyQt.
I tried all possible 4 enum values but other than text styling or no it didn't change anything.
The string value with the embedded HTML is 'Obtain a unique ID from www.plugincafe.com or use <font color="maroon">%s</font> for testing purposes.' % PLUGIN_ID_TESTING

QWizard (and QWizardPage) only expose mimimal control over the QLabel used as subtitle, but you can just iterate through all child QLabels in your QWizard and call setOpenExternalLinks(True):
for label in wizard.findChildren(QLabel):
label.setOpenExternalLinks(True)
If you don't want to set it on all labels, then you need to check if you found the correct one.

Related

How to add a border to a python console-menu

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)

pywinauto: how to use the memory location string given by wrapper_object()?

I found that in the docs
Actual window lookup is performed by wrapper_object() method. It
returns some wrapper for the real existing window/control or raises
ElementNotFoundError. This wrapper can deal with the window/control by
sending actions or retrieving data.
>>> dlg_spec.wrapper_object()
<pywinauto.controls.win32_controls.DialogWrapper object at 0x05639B70>
What is 0x05639B70? And how can I use for instance to print what it contains? (ex: print(0x05639B70) )
[edit] Since it's actually the memory location (address) of the object (thanks to Juan for that) can I click on it? How?
You can list all available methods of the object because it's Python:
print(dir(dlg_spec.wrapper_object()))
Some controls may have method .invoke() because sometimes its meaning is different than just a click. So we left it as .invoke().
For retrieving control's text ("Name" property in Inspect.exe):
print(dlg_spec.window_text())
Yes, default printing could be improved with a text instead of an address. Added issue #322 to remember this.

Custom view with InstanceEditor

I'm working on a dynamic Traits UI where I can select the class to use for certain instances. I've got it working nicely using an InstanceEditor with a "values" argument containing InstanceFactoryChoice instances.
My problem appears when I want to specify a view to use for the selected instance. Using the "view" argument works if I omit the "values" argument, but with it I get the default view instead. The relevant part of the view looks like this:
Item('item',
show_label=False,
editor=InstanceEditor(
view=item_view,
values=[InstanceFactoryChoice(klass=k) for k in classes],
editable=True),
style='custom')
What's more confusing to me is that it also works as expected (i.e. uses the "item_view" view to display the instance) when I use the "simple" style instead of "custom". However, then the view appears in a new window, I want it to be inline.
Am I missing something here? I'm on TraitsUI 4.3.
OK, after some source-diving I found that adding the "view" argument to the InstanceFactoryChoice call instead seems to do what I want. Still, it seems there's an inconsistency in there somewhere...
InstanceFactoryChoice(klass=k, view=item_view)

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