Issue
I'm very new to PyQt, so it's possible I'm doing this entirely wrong. I'm currently struggling to set the title
property of a QMessageBox
during instantiation in PyQt6. Here is my code:
import PyQt6.QtWidgets as Qtw
app = Qtw.QApplication([])
alert_window = Qtw.QMessageBox(text="Foo", title="Bar")
alert_window.exec()
When running this, I get the following error:
TypeError: 'title' is an unknown keyword argument
However, __init__
for QMessageBox
(located in the Python stub QtWidgets.pyi
) seems to clearly define title
as a string argument, which I am passing correctly:
@typing.overload
def __init__(self, icon: 'QMessageBox.Icon', title: str, text: str, buttons: 'QMessageBox.StandardButton' = ..., parent: typing.Optional[QWidget] = ..., flags: QtCore.Qt.WindowType = ...) -> None: ...
I've tried to run this by removing the title
keyword argument and just leaving text
and it seems to work just fine. Am I missing something entirely, or is the .pyi
file incorrect? And, if this file is incorrect, is there any other documentation for PyQt that I can reference to find which arguments I can and cannot use? Thanks.
Solution
You have two issues:
- you're confusing positional and named arguments;
- QObject properties can be used as named arguments;
Positional vs. Named arguments
def function(positional1, positional2, named1=something, named2=whatever):
The above means, simply put, that function
:
- requires two arguments (
positional1
and positional2`); - can have two optional arguments (
named1
andnamed2
);
The positional arguments:
- are required when calling the function;
- must respect the order (and, possibly, their expected type);
- their names are just for reference;
The named arguments:
- are not required when calling the function;
- if not specified, use their default value, which is whatever is evaluated after the
=
sign; - might be added as positional arguments, while respecting the order (
function(x, y, z)
means thatnamed1
will be equal toz
within the function); - might not be in the same order (
function(x, y, named2=z, named1=w)
);
The above means that calling function(x)
will be correct, while function(positional1=x)
will not.
QObject properties
Almost all QObjects accept named arguments that correspond to the object's properties, even if they're not declared in the constructor's definition.
For instance, all QWidgets support the enabled
property, meaning that you can do the following:
button = QPushButton(enabled=False)
The problem
Why this doesn't work?
Qtw.QMessageBox(text="Foo", title="Bar")
That's for two reasons:
- the
title
argument listed in the constructor is just a positional argument, so, as explained above, using a named argumenttitle="Bar"
is wrong; title
is not listed in QMessageBox property list (nor in its inherited classes);
Why this does work?
Qtw.QMessageBox(text="Foo")
This is for two reasons:
- Among the QMessageBox constructors, there is one that also doesn't require positional arguments;
text()
is a valid Qt property of QMessageBox;
Final notes
- Don't use
pyi
stubs/definitions as reference; use the documentation, starting with the official C++ API (which is 99.9% the same as it's for Python) and eventually check the interactive Python console usinghelp(class.function)
for arguments and return values; - Do more careful research and study about function arguments in Python, including argument [un]packing (conventionally,
*args
and**kwargs
); - PyQt (just as PySide) is a binding; it just wraps classes and functions that actually exist in the C++ side of the Qt library; that's why you can (and should) use the official C++ documentation instead of looking for the official PyQt one (or even the, sometimes misleading, PySide one) unless when strictly required;
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.