[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: Question regarding enums and IntEnum/IntFlags
From:       Nyall Dawson <nyall.dawson () gmail ! com>
Date:       2024-02-18 23:09:09
Message-ID: CAB28Asjv+JcyDN-Rba70kTsjJJ1DoWA+-MeF9vnLHc=HsDwLmA () mail ! gmail ! com
[Download RAW message or body]

On Sat, 17 Feb 2024 at 09:13, Florian Bruhin <me@the-compiler.org> wrote:
> 
> Hey,
> 
> > I'm wondering if there's a specific reason why some Qt enums are exposed as
> > IntEnum/IntFlags, and others not?
> 
> They're exposed as IntEnum/IntFlag if the underlying C++ API uses them
> in such a way - e.g. QEvent.Type (due to QEvent.Type.User), or
> Qt.ItemDataRole (Qt.ItemDataRole.UserRole) or QUrl.UrlFormattingOption
> (can be mixed with Qt.ComponentFormttingOption).

Ok, on second thoughts I agree about Qt.ItemFlag, that's fine to be a
Flags type enum.

> 
> > Specifically, I'm looking at Qt.ItemFlag (which I'd have expected to be an
> > IntFlags type) and Qt.CheckState (which I'd expected to be an IntEnum type).

But looking at the Qt.CheckState situation -- from custom models it's
typical to see a ::data implementation which does something like:

switch ( role )
  ...
  case Qt::CheckStateRole:
     return some condition ? Qt::Unchecked : Qt::Checked;

(And this is what Qt internal code does too. See eg
https://github.com/qt/qtbase/blob/adc0920c48d812fb1b3e2b7bfc76217a7126a41e/src/widgets/itemviews/qtreewidget.cpp#L1828


but this means that Python data(...) from Python and querying the
CheckStateRole returns just an integer value. And then if the Python
code tries to do something like:

 if model.data(index, Qt.ItemDataRole.CheckStateRole) ==
Qt.CheckState.Unchecked:
    # something

then the condition will NEVER be met, because model.data( ... ) will
return just an integer 0, and 0 != Qt.CheckState.Unchecked (unless
Qt.CheckState was an IntEnum).

Things work as expected if the c++ ::data implementation does something like:

case Qt::CheckStateRole:
   return some condition ? QVariant::fromValue( Qt::Unchecked ) :
QVariant::fromValue( Qt::Checked );

because then the Python call to .data returns an Qt.CheckState enum
value. But this seems to go against Qt design, and again it's not an
approach used in the Qt internal c++ code either.

So the difference to me seems to be whether a model (or any c++
function implementation) is expected to return the "raw" enum value as
a QVariant, and not a QFlags wrapper around it. If it's expected to
return the raw enum value then that enum needs to be an IntEnum /
IntFlags type to consistently work for different model
implementations.

Nyall






> 
> Why?
> 
> Florian


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic