Trouble with inherited properties



  • Hi - I'm doing something wrong with inherited properties, so maybe someone can help me out. I have two classes, one which inherits from the other, both of which defined properties as follows:

    @
    class AcmeCommand : public QObject
    {
    Q_OBJECT
    Q_PROPERTY(char commandGroup READ getGroup)
    Q_PROPERTY(char commandId READ getId)

    public:
    char commandGroup;
    char commandId;

    char getGroup() { return commandGroup; }
    char getId() { return commandId; }
    };

    class PowerIgniter : public AcmeCommand
    {
    Q_OBJECT

    Q_PROPERTY(float power READ getPower)
    Q_PROPERTY(quint32 duration READ getDuration)

    public:
    PowerIgniter()
    {
    commandGroup = IGNITER_GROUP_ID;
    commandId = IGNITER_POWER_ID;
    }

    float power;
    quint32 durationMs;

    float getPower() { return power; }
    quint32 getDuration() { return durationMs; }
    }
    @

    So later on, I allocate a PowerIgniter, and pass it as an AcmeCommand* to a function that is going to put its values into an array. The problem is this - I can successfully get out the subclass' properties, but the base class' properties are blank, even though the subclass constructor assigns them. When I run this code:

    @
    const QMetaObject* pMetaObj = pMessage->metaObject();

    quint32 propertyCount = pMetaObj->propertyCount();

    for(quint32 i = 0; i < propertyCount; i++)
    {
    qDebug() << pMetaObj->property(i).name() << " " << pMessage->property(pMetaObj->property(i).name());
    }
    @

    (pMessage is an AcmeCommand*)

    I get this output:

    @
    objectName QVariant(QString, "")
    commandGroup QVariant(char, )
    commandId QVariant(char, )
    power QVariant(float, 1)
    duration QVariant(uint, 1)
    @

    Why are commandGroup and commandId blank? I'm sure I'm doing something really dumb.

    M



  • While type char is a valid metatype, it is not a "real" type of a QVariant. Do you have any reasons for not using QChar? Using the latter, everything works.

    BTW: your code is ok, the property is set correctly, try a cast to a QChar for the qDebug output:

    @
    qDebug() << pMessage->property("commandGroup").toChar();
    @



  • Here is the problem: I'm using the char as an actual 8 bit storage device. It is part of a network packet that is defined to be a byte, so I need to use the char as a byte, not as an ASCII character. Qt seems to not really "think" this way, but here is what I ended up doing...

    @
    QVariant idInfo = pMessage->property("commandGroup");

    char groupData = idInfo.toChar().cell();
    @

    For example, the value of commandGroup in my program will always be greater than 0xC4, which outside the bounds of valid ascii characters.

    Also, I don't think I should have to do the .toChar() above because wont QVariant know that it is QMetaType::Char and spit out a QChar? There are no other 8 bit types in the QVariant public functions.

    Speaking of QVariant, why isn't there a toShort()? For example, in my code, I'll probably have 16 bit values... I'll have to do some weird conversion to an int, then just get the short part (or something like that).



  • You can always use "value() ":/doc/qt-4.8/qvariant.html#value to convert to the desired type.

    @
    QVariant vv(0xc4);

    char c = vv.value<char>();
    quint8 ui8 = vv.value<quint8>();
    @

    The conversions will not fail if the value doesn't fit into 8 bits, but it is truncated to the last 8 bits. If you have a QVariant int containing 0xffff, the conversions above will set c and ui8 to 0xff. But as your underlying storage is only capable of 8 bits, this should not be a big concern here - just watch out, as there is no compilation error or runtime warning, the truncation happens silently.

    You can use quint8 as unsigned 8 bit storage for your data too.



  • Good tip on quint8, I like using those types over the built in ones.

    However, it turns out that it might be easier to use char* because of what I am doing with the data after I get it out of the QVariant. I am shoving it into a QByteArray, like this:

    @
    QVariant idInfo = pMessage->property("commandGroup");

    char groupData = idInfo.toChar().cell();

    message.append(QByteArray::fromRawData(&groupData, 1));
    @

    and it turns out that if you do a quint8 instead of char, you get this compiler error:

    @
    error: invalid conversion from ‘quint8* {aka unsigned char*}’ to ‘const char*’
    @

    and it doesn't like casting.



  • Oh, and message is a QByteArray.



  • Why not append the char directly? QByteArray's append has several overloads, one of it taking a plain char (which is compatible to the quint8):

    @
    message.append(groupData);
    @

    PS:
    If you need to add something to a previous comment, please use the edit link to the right of the post and add it there, instead of posting a new comment. This looks nicer :)



  • I was leery of doing so because the documentation described Qt putting in a '/0' character into the QByteArray when you do char based operations. Admittadely, this is probably not an issue since size() returns the size w/o the /0 string ending character. I just figured I'd do it the same way I had to do my quint32s and floats, but maybe that isn't the smartest.

    I assume when I hand a QLocalSocket a QByteArray to shove out via write() it won't include any /0's.

    Thanks for the editing tip.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.