Home > Enterprise >  PyQt6: 'Title' keyword not recognized for QMessageBox
PyQt6: 'Title' keyword not recognized for QMessageBox

Time:08-09

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.

CodePudding user response:

Where can I find PyQt5 Method Signatures?

It seems that you cannot use those as keyword arguments. You must do:

alert_window = Qtw.QMessageBox("Foo", "Bar")

CodePudding user response:

Where I see that you are having problems is in the arguments that you pass to Qtw.QMessangeBox.

You'd have to pass it this way: alert_window = Qtw.QMessageBox("Foo", "Bar")

Since you cannot assign variables to it with data within the argument, it has to be directly a variable already set in the Global or Local Scope or arguments written at the time.

CodePudding user response:

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 and named2);

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 that named1 will be equal to z 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:

  1. the title argument listed in the constructor is just a positional argument, so, as explained above, using a named argument title="Bar" is wrong;
  2. 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:

  1. Among the QMessageBox constructors, there is one that also doesn't require positional arguments;
  2. text() is a valid Qt property of QMessageBox;

Final notes

  1. 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 using help(class.function) for arguments and return values;
  2. Do more careful research and study about function arguments in Python, including argument [un]packing (conventionally, *args and **kwargs);
  3. 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;
  • Related