Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > пустой окно QLabel


Автор: yngwie19 13.6.2009, 22:20
Всем привет вот мой код. Подскажите почему при показе QLabel появляется пустое окно без текста "My Name":
Код

#include <QtGui>

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(char* name READ GetName WRITE SetName)
    public:
        MyClass(QObject *obj = NULL);
        char* GetName()const;
        void SetName(char*);
    private:
        char *szName;
};

int main(int argc, char *argv[])
{
    QApplication app(argc,argv);
    MyClass *mc = new MyClass;
    QLabel *lbl = new QLabel(mc->property("name").toString()); 
    lbl->show();
    
    return app.exec();
}

MyClass::MyClass(QObject *obj) : QObject(obj), szName("My Name")
{;
}

char* MyClass::GetName()const
{
    return szName;
}

void MyClass::SetName(char* name)
{
}

#include "main.moc"

Автор: andrew_121 14.6.2009, 04:56
Потому что метод show() вызывать нужно у объекта MyClass. А QLabel должен быть его членом, и в качестве парента должен использовать this. Именно об этом я тебе и пытался сказать здесь: http://forum.vingrad.ru/forum/topic-263063.html

Автор: Любитель 14.6.2009, 05:17
Это, конечно, не по теме вопроса, но:
1. Возвращать указатель на char?! smile Мало того, что это ужасно неудобно юзать, так ещё и даёт возможность модификации поля извне...
2. В чём смысл пользование методом property со статическим параметром (известным в компайл-тайм, всмысле) для известного класса? Это ж ведь значительно медленнее, чем нормальный вызов конкретного метода!
3. Зачем создавать lbl и mc в куче? Да ещё и не удалять их (да, это уже обсуждалось тут не раз - в данном случае ничего не случится, но это ужасная практика).
4. И ещё - NULL в С++ всё-таки не особо принято писать (ибо требует никому не нужного инклюда, а ведь достаточно написать 0).

Автор: yngwie19 14.6.2009, 09:11
andrew_121, 
не понял. у MyClass нет метода show. исправь пожалуйста в моем коде, покажи что ты имеешь в виду.

Автор: Любитель 14.6.2009, 11:32
yngwie19, посмотри какие дебажные сообщения при запуске выводит твой код ;)

Цитата

QMetaProperty::read: Unable to handle unregistered datatype 'char*' for property 'MyClass::name'


Ещё раз - зачем так извращаться?! Почему не использовать "обычный" (для Qt) QString?

Автор: yngwie19 14.6.2009, 11:40
Любитель, спасибо теперь получилось! Я не понял о чем говорит andrew_121, стоит так делать?

Автор: SABROG 14.6.2009, 11:51
У QVariant'a нет типа "char *": http://doc.trolltech.com/latest/qvariant.html#Type-enum
Поэтому тебе надо использовать QString, если ты хочешь содержать в свойстве строку.

Но, если ты все-таки хочешь содержать там указатель на Си строку или любой другой тип, то тогда тебе его нужно зарегистрировать:

Код

#include <QtCore/QMetaType>
#include <QtCore/QVariant>
#include <QtGui/QApplication>
#include <QtGui/QLabel>

Q_DECLARE_METATYPE(char *)

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(char *name READ GetName WRITE SetName)
public:
    MyClass(QObject *parent = 0) : QObject(parent), name("My Name") {}
    inline char *GetName() const {return name;}
    inline void SetName(char *newname) {name = newname;}
private:
    char *name;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    qRegisterMetaType<char *>("char *");
    MyClass mc;
    QLabel lbl(QLatin1String(mc.property("name").value<char *>()));
    char *buff = "New Name";
    mc.setProperty("name", qVariantFromValue(buff));
    QLabel lbl2(QLatin1String(mc.property("name").value<char *>()));
    lbl.show();
    lbl2.show();   
    return app.exec();
}

#include "main.moc"


Автор: yngwie19 14.6.2009, 12:52
SABROG, спасибо тебе большое.

Автор: andrew_121 14.6.2009, 13:28
Цитата(Любитель @  14.6.2009,  05:17 Найти цитируемый пост)
в данном случае ничего не случится, но это ужасная практика

Да. И за это нужно бить по рукам.



SABROG, Странный код получился) Обычно виджеты пихают в базовый класс.

Автор: SABROG 14.6.2009, 14:19
Цитата(andrew_121 @ 14.6.2009,  13:28)
Цитата(Любитель @  14.6.2009,  05:17 Найти цитируемый пост)
в данном случае ничего не случится, но это ужасная практика

Да. И за это нужно бить по рукам.



SABROG, Странный код получился) Обычно виджеты пихают в базовый класс.

Предлагаешь привести указатель QObject'a к QWidget'у и передать в качестве родителя? ;)

setParent() тоже не поможет, он переопределен у QWidget'a под QWidget* вместо QObject*.

Автор: andrew_121 14.6.2009, 15:17
В %QTDIR%/examples есть куча примеров. Именно для того, чтоб не возникало подобных вопросов.


Цитата(SABROG @  14.6.2009,  14:19 Найти цитируемый пост)
Предлагаешь привести указатель QObject'a к QWidget'у и передать в качестве родителя? ;)

setParent() тоже не поможет, он переопределен у QWidget'a под QWidget* вместо QObject*.

Кроме нормального учебника, тутваще ничего не поможет)))

Добавлено @ 15:19
Цитата(yngwie19 @  14.6.2009,  09:11 Найти цитируемый пост)
у MyClass нет метода show

Естественно! Я бы удивился если бы он там был smile  Унаследуйся от QDialod. читай книжки....

Автор: SABROG 14.6.2009, 15:47
Цитата(andrew_121 @  14.6.2009,  15:17 Найти цитируемый пост)
Кроме нормального учебника, тутваще ничего не поможет)))

Учебники - скукота. Я например пишу то, что мне интересно, выбираю себе задачки сам. Если мне не интересно возится с сокетами, пока не припрет не стану изучать. 

Цитата(SABROG @  14.6.2009,  14:19 Найти цитируемый пост)
Обычно виджеты пихают в базовый класс.

Создавать третий виджет как-то влом было, да и превращать QObject в QWidget неохото smile

Автор: andrew_121 14.6.2009, 16:48
Цитата(SABROG @  14.6.2009,  15:47 Найти цитируемый пост)
Учебники - скукота. Я например пишу то, что мне интересно, выбираю себе задачки сам.

Гм... Уважаемый, вы же не новичек!



Цитата(SABROG @  14.6.2009,  15:47 Найти цитируемый пост)
пока не припрет не стану изучать. 

Все так. Потом локти грызем.




Цитата(SABROG @  14.6.2009,  15:47 Найти цитируемый пост)
Создавать третий виджет как-то влом было, да и превращать QObject в QWidget неохото

Да. Но было бы правильно.

Автор: SABROG 14.6.2009, 19:58
Цитата(andrew_121 @  14.6.2009,  16:48 Найти цитируемый пост)
Гм... Уважаемый, вы же не новичек!

Новичек. Я еще ни одного серьезного приложения на Qt не написал. Всё утилиты небольшие.

Цитата(andrew_121 @  14.6.2009,  16:48 Найти цитируемый пост)
Да. Но было бы правильно.

Еще было бы правильно придерживаться стиля Qt и написать так:

Код

Q_DECLARE_METATYPE(char *)

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(char *name READ name WRITE setName)
public:
    MyClass(QObject *parent = 0) : QObject(parent), m_name("My Name") {}
    inline char *name() const {return m_name;}
    inline void setName(char *newname) {m_name = newname;}
private:
    char *m_name;
};


Тогда не смотря на внутреннее имя переменной m_name к свойству можно обращаться как к "name" и использовать методы в Qtшном стиле: 

Код

    QLabel lbl(QLatin1String(mc.name()));
    char *buff = "New Name";
    mc.setName(buff);
    QLabel lbl2(QLatin1String(mc.name()));


Странно, что на это никто не обратил внимания smile

Автор: andrew_121 14.6.2009, 22:41
Цитата(SABROG @  14.6.2009,  19:58 Найти цитируемый пост)
Странно, что на это никто не обратил внимания

 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)