Search code examples
pythonpython-3.xpyqtpyqt5qt-designer

Autocomplete from .ui


I am working on an app using Python3 and PyQt5, with my UI layout begin defined in a Qt .ui file and loaded into my QDialog class at runtime. Therefore, the instances of my UI elements, such as a QPushButton, are automatically assigned as instance variables of my QDialog class when the UI is loaded in.

The problem with this is that when I go to use these variables to modify the elements, I don't get any kind of Intellisense type hinting or autocompletion because Python and my IDE have no clue what the object's class is.

In Java, you can use explicit narrowing casting cast your object to the correct type, at which point intellisense can begin providing autocompletion because it knows the type.

For example, in Java and Android SDK:

TextView name = (TextView) findViewById(R.id.name); 

In this example, findViewById returns a View, so you can use type casting to ensure that it is cast to a TextView.


In Python, I'd like to do the same kind of thing, both to ensure that the UI elements I'm accessing are the correct type and to be able to use autocompletion for instance methods.

Here is my current situation:

""" 
Because Python doesn't know whether self.my_push_button is an instance 
of QPushButton, this may or may not work, but it won't know until runtime, 
so no autocompletion.
"""
self.my_push_button.setEnabled(False) 

What I want to be able to do is something like this:

( (QPushButton) self.my_push_button ).setEnabled(False) 

I tried this:

QPushButton(self.my_push_button).setEnabled(False)

But from what I can tell, it duplicates the original object and performs setEnabled on the new object, which is obviously not what I want.

I also tried using assert statements with the isinstance function:

assert isinstance(self.my_push_button, QPushButton)

"""
This works for providing the code completion and checking the type.
However, it only works within the scope of the assert statement, so adding an assert for each variable in each scope in which it is used would be unnecessarily verbose.
"""
self.my_push_button.setEnabled(False) 

I understand that there's not real "casting" with objects in Python, but it there any way to be able to something similar in Python to narrowing casting, as shown above, in Java?


Solution

  • Code completion does not work for dynamically generated elements as uic does.

    One possible solution is to convert the .ui to .py using pyuic and then use that class indicated in Using the Generated Code.