Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set properties using keyword arguments in constructor #147

Open
ThePhilgrim opened this issue Mar 27, 2021 · 16 comments · Fixed by #148
Open

Set properties using keyword arguments in constructor #147

ThePhilgrim opened this issue Mar 27, 2021 · 16 comments · Fixed by #148

Comments

@ThePhilgrim
Copy link

"self.scroll_area = QtWidgets.QScrollArea(widgetResizable=True)"

generates following error message:

error: Unexpected keyword argument "widgetResizable" for "QScrollArea"

@altendky
Copy link
Collaborator

Well this is fun. So, I agree that it works at run time and therefor should work when type checking.

https://replit.com/@altendky/OldfashionedRemoteComputergames-2

from PyQt5 import QtCore
from PyQt5 import QtWidgets


print(QtCore.PYQT_VERSION_STR)

application = QtWidgets.QApplication([])
scroll_area_1 = QtWidgets.QScrollArea(widgetResizable=False)
scroll_area_2 = QtWidgets.QScrollArea(widgetResizable=True)
print(scroll_area_1.widgetResizable())
print(scroll_area_2.widgetResizable())
5.15.4
False
True

But... it isn't documented for Qt itself.

https://doc.qt.io/qt-5/qscrollarea.html

Anyways, we're for accuracy so I'll plan on putting together a PR.

@BryceBeagle
Copy link
Collaborator

BryceBeagle commented Mar 27, 2021

This is a feature of PyQt that's gonna be a pain to support:

PyQt5 does not support the setting and getting of Qt properties as if they were normal instance attributes. This is because the name of a property often conflicts with the name of the property’s getter method.

However, PyQt5 does support the initial setting of properties using keyword arguments passed when an instance is created. For example:

act = QAction("&Save", self, shortcut=QKeySequence.Save,
              statusTip="Save the document to disk", triggered=self.save)

So every single widget's constructor supports kwargs for every single one of their Qt Properties

@altendky
Copy link
Collaborator

yay...

@ThePhilgrim
Copy link
Author

"self.dialog_groupbox = QtWidgets.QGroupBox(objectName="job_post_box")"

gives me:

"error: No overload variant of "QGroupBox" matches argument type "str"
note: Possible overload variants:
note: def QGroupBox(self, parent: Optional[QWidget] = ...) -> QGroupBox
note: def QGroupBox(self, title: str, parent: Optional[QWidget] = ...) -> QGroupBox"

Should this be considered the same issue, or do you want me to create a separate issue?

@altendky
Copy link
Collaborator

Since @BryceBeagle identified this as a systemic issue, I'm not going to be tackling them all. If you want to add them, just direct PRs would suffice. No need for tickets first.

@BryceBeagle
Copy link
Collaborator

BryceBeagle commented Mar 29, 2021

Well here's a way to get all the Qt Properties of an object:

from PyQt5.QtWidgets import QScrollArea, QApplication

app = QApplication([])

meta = QScrollArea().metaObject()

for prop_idx in range(meta.propertyCount()):
    prop = meta.property(prop_idx)
    print(prop.name(), prop.typeName())
objectName QString
modal bool
windowModality Qt::WindowModality
enabled bool
geometry QRect
frameGeometry QRect
normalGeometry QRect
x int
y int
pos QPoint
frameSize QSize
size QSize
width int
height int
rect QRect
childrenRect QRect
childrenRegion QRegion
sizePolicy QSizePolicy
minimumSize QSize
maximumSize QSize
minimumWidth int
minimumHeight int
maximumWidth int
maximumHeight int
sizeIncrement QSize
baseSize QSize
palette QPalette
font QFont
cursor QCursor
mouseTracking bool
tabletTracking bool
isActiveWindow bool
focusPolicy Qt::FocusPolicy
focus bool
contextMenuPolicy Qt::ContextMenuPolicy
updatesEnabled bool
visible bool
minimized bool
maximized bool
fullScreen bool
sizeHint QSize
minimumSizeHint QSize
acceptDrops bool
windowTitle QString
windowIcon QIcon
windowIconText QString
windowOpacity double
windowModified bool
toolTip QString
toolTipDuration int
statusTip QString
whatsThis QString
accessibleName QString
accessibleDescription QString
layoutDirection Qt::LayoutDirection
autoFillBackground bool
styleSheet QString
locale QLocale
windowFilePath QString
inputMethodHints Qt::InputMethodHints
frameShape Shape
frameShadow Shadow
lineWidth int
midLineWidth int
frameWidth int
frameRect QRect
verticalScrollBarPolicy Qt::ScrollBarPolicy
horizontalScrollBarPolicy Qt::ScrollBarPolicy
sizeAdjustPolicy SizeAdjustPolicy
widgetResizable bool
alignment Qt::Alignment

An absolute massive amount of properties. Not sure if we want to support all this, but if we do I'm thinking we could script this operation somehow.

Unfortunately, this snippet here requires knowing how to properly instantiate the QObject so that we can get the QMetaObject

@BryceBeagle
Copy link
Collaborator

Something interesting I noticed is that some properties (e.g x and y) are read-only (prop.isReadable() == True and prop.isWritable() == False), but PyQt still lets me use them as arguments in the constructor. Doing so does not seem to change their actual values post-construction.

@altendky
Copy link
Collaborator

*uuughHGHGHGHGHH*

I tend to think our focus should be on Qt6 and maybe trying to get Phil fixing whatever issues we find rather than developing our own modifier or generator. But who knows what will really work out...

@BryceBeagle
Copy link
Collaborator

I agree, this should probably be something to get Phil to implement upstream. Unfortunately, I haven't had the best experience using the mailing list in the past... I have been unable to properly reply to a thread without also turning off the email digests... 😐

@altendky
Copy link
Collaborator

It's not like it's a high traffic maillist. Aren't half the digests a single message anyways? But, I can try again when we get to working with PyQt6. I didn't get far with 'there are lots of changes, take a look at the diff and the PRs and the changelog'. So I guess the next pass will be one by one sequential reports.

What do you think @BryceBeagle and @The-Compiler, should we leave this as 'will accept PRs but presently no plan to fully implement'?

@The-Compiler
Copy link
Collaborator

What do you think @BryceBeagle and @The-Compiler, should we leave this as 'will accept PRs but presently no plan to fully implement'?

My stance is still that we should strive to automate those fixes rather than doing them manually - but then again I haven't been contributing much, so it's not like I have much of a say 🙂

@altendky
Copy link
Collaborator

altendky commented Apr 1, 2021

Is there a reason to not be fixing SIP/PyQt? Is it a bad system? Too much hassle to go through the half-open-source development path? Or, maybe you include fixing upstream generation in 'automate those fixes'.

Also, my statement was 'we are not prioritizing automating them and also will not be manually doing them en-masse'. Which I think is somewhat just a different perspective on what you wrote. :]

@bluebird75
Copy link
Collaborator

An alternative approach to find all the properties of an object is to parse Qt documentation. This can be automated.

@bluebird75
Copy link
Collaborator

This issue was incorrectly closed.

We should strive to support setting all properties using the object constructor .

@bluebird75 bluebird75 reopened this Apr 24, 2022
@bluebird75 bluebird75 changed the title Unexpected keyword argument "widgetResizable" for "QScrollArea" Set properties using keyword arguments in constructor Apr 24, 2022
@senyai
Copy link

senyai commented Aug 17, 2022

Can we have __init__(self, **kwargs:any)? Yes, it's incorrect because it defeats the purpose of type checking, but it's less incorrect (IMO) than blaming valid arguments.

@bluebird75
Copy link
Collaborator

@senyai interesting suggestion but we would be validating incorrect code in this case. I prefer a long term correct solution, or patching as people report the problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants