Python.NET: How to access generic member of an interface

114
April 05, 2022, at 00:50 AM

I am trying to use a generic member from an interface in FlaUI through Python.NET.

The below C# code works,

// myLegacyTreeItem is a valid AutomationElement
// this works and the default action expands the tree node
myLegacyTreeItem.Patterns.LegacyIAccessible.Pattern.DoDefaultAction();

However, the below corresponding Python.NET code doesn't work,

# my_legacy_tree_item is a valid element
my_legacy_tree_item.Patterns.LegacyIAccessible.Pattern.DoDefaultAction()

I am getting the following error,

AttributeError: 'UIA3FrameworkAutomationElement' object has no attribute 'LegacyIAccessible'

I can see the the LegacyIAccessible member is using generic syntax. But I am not able to figure out how to bind it to the concrete type.

https://github.com/FlaUI/FlaUI/blob/master/src/FlaUI.Core/FrameworkAutomationElementBase.Patterns.cs

using FlaUI.Core.Patterns;
namespace FlaUI.Core
{
    public abstract partial class FrameworkAutomationElementBase : FrameworkAutomationElementBase.IFrameworkPatterns
    {
        private IAutomationPattern<IAnnotationPattern> _annotationPattern;
        private IAutomationPattern<IDockPattern> _dockPattern;
        private IAutomationPattern<IDragPattern> _dragPattern;
        private IAutomationPattern<IDropTargetPattern> _dropTargetPattern;
        private IAutomationPattern<IExpandCollapsePattern> _expandCollapsePattern;
        private IAutomationPattern<IGridItemPattern> _gridItemPattern;
        private IAutomationPattern<IGridPattern> _gridPattern;
        private IAutomationPattern<IInvokePattern> _invokePattern;
        private IAutomationPattern<IItemContainerPattern> _itemContainerPattern;
        private IAutomationPattern<ILegacyIAccessiblePattern> _legacyIAccessiblePattern;
        ...
        public IFrameworkPatterns Patterns => this;
        IAutomationPattern<IAnnotationPattern> IFrameworkPatterns.Annotation => _annotationPattern ?? (_annotationPattern = InitializeAnnotationPattern());
        IAutomationPattern<IDockPattern> IFrameworkPatterns.Dock => _dockPattern ?? (_dockPattern = InitializeDockPattern());
        IAutomationPattern<IDragPattern> IFrameworkPatterns.Drag => _dragPattern ?? (_dragPattern = InitializeDragPattern());
        IAutomationPattern<IDropTargetPattern> IFrameworkPatterns.DropTarget => _dropTargetPattern ?? (_dropTargetPattern = InitializeDropTargetPattern());
        IAutomationPattern<IExpandCollapsePattern> IFrameworkPatterns.ExpandCollapse => _expandCollapsePattern ?? (_expandCollapsePattern = InitializeExpandCollapsePattern());
        IAutomationPattern<IGridItemPattern> IFrameworkPatterns.GridItem => _gridItemPattern ?? (_gridItemPattern = InitializeGridItemPattern());
        IAutomationPattern<IGridPattern> IFrameworkPatterns.Grid => _gridPattern ?? (_gridPattern = InitializeGridPattern());
        IAutomationPattern<IInvokePattern> IFrameworkPatterns.Invoke => _invokePattern ?? (_invokePattern = InitializeInvokePattern());
        IAutomationPattern<IItemContainerPattern> IFrameworkPatterns.ItemContainer => _itemContainerPattern ?? (_itemContainerPattern = InitializeItemContainerPattern());
        IAutomationPattern<ILegacyIAccessiblePattern> IFrameworkPatterns.LegacyIAccessible => _legacyIAccessiblePattern ?? (_legacyIAccessiblePattern = InitializeLegacyIAccessiblePattern());
        ...
    }
}

If I change the call as below, there is no error, but the tree item is not expanded,

((FrameworkAutomationElementBase.IFrameworkPatterns)(my_legacy_tree_item.Patterns)).LegacyIAccessible.Pattern.DoDefaultAction()

Trying to use the below cast throws error,

((FrameworkAutomationElementBase.IFrameworkPatterns[ILegacyIAccessiblePattern])(parent.Patterns)).LegacyIAccessible.Pattern.DoDefaultAction()
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at Python.Runtime.GenericUtil.GenericByName(String ns, String name, Int32 paramCount)
   at Python.Runtime.ClassBase.type_subscript(IntPtr idx)
Answer 1

Answering my own question as it was a silly mistake.

The below line indeed expands the legacy tree item,

((FrameworkAutomationElementBase.IFrameworkPatterns)(my_legacy_tree_item.Patterns)).LegacyIAccessible.Pattern.DoDefaultAction()

However, since in my case, I was also immediately right clicking on the same item, the context menu was getting popped up before the tree item could be expanded. So adding sleep(1) after the above call worked for me.

Alternatively my_legacy_tree_item.DoubleClick() followed by sleep(1) worked too.

Rent Charter Buses Company
READ ALSO
Python: Error occurred when learning with Tensorflow using levenberg marquardt library

Python: Error occurred when learning with Tensorflow using levenberg marquardt library

I'm new to TensorflowI'm trying to create a network like this: ・ Input layer: 400 pieces ・ Hidden layer: 20 pieces, activation functions tanh ・ Output layer: 1 pieces, activation function sigmoid ・ Optimization method: levenberg marquardt ・ Library...

90
How to open a new MDI sub-window in PyQt5?

How to open a new MDI sub-window in PyQt5?

What I want to do is to open a new Countrypage sub-window by clicking on the "New" button which is in Countrypage itself

119
Finding optimal nearest neighbour pairs

Finding optimal nearest neighbour pairs

I am writing a "colocalization" script to identify unique co-localized pairs of coordinates between two sets of dataMy data is quite large with <100k points in each set so performance is pretty important

114
Send raw hex and strings over sockets

Send raw hex and strings over sockets

I'm trying to send data over sockets with Python to trigger IDS rules

132