Russian Qt Forum

Qt => Общие вопросы => Тема начата: labview от Август 23, 2010, 19:46



Название: Использование QVariant
Отправлено: labview от Август 23, 2010, 19:46
Привет!

Мне нужно передать данные из одного места программы в другое. Для этого я определил структуру данных PortOpenParamsType в одном месте:

Код:
#ifndef THREAD1_H
#define THREAD1_H

#include <QThread>
#include <QList>

#include "Tasking.h"

typedef struct PortOpenParamsType
{
    QString IPAdress;
    int PortNum;
}PortOpenParams;

Q_DECLARE_METATYPE(PortOpenParams*);

class Thread1 : public QThread
{
    Q_OBJECT

public:
    Thread1(const QList<Tasking*>& allTasks);
private:
    virtual void run();
    QList<Tasking*> Tasks;
    QVariant v;
signals:
    void showData(QString data);
};

#endif // THREAD1_H


И внёс это определение в друге место, а так же заполнил значениями:

Код:
#include "mainwidget.h"

#include <QGridLayout>

#include "thread1.h"

MainWidget::MainWidget(const QList<Tasking*>& allTasks, QWidget *parent)
    :QWidget(parent)
{
    Tasks = allTasks;
    textEdit = new QTextEdit(this);
    sendButton = new QPushButton(tr("send"));
    exitButton = new QPushButton(tr("exit"));
    QGridLayout *layout = new QGridLayout;
    layout->addWidget(textEdit, 0, 0);
    layout->addWidget(sendButton, 1, 0);
    layout->addWidget(exitButton, 2, 0);
    setLayout(layout);
    connect(exitButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(sendButton, SIGNAL(clicked()), this, SLOT(send()));
}

void MainWidget::addText(QString text)
{
    textEdit->append(text);
}

void MainWidget::close()
{
    task Task;
    Task.tasknum = 0;
    Tasks[0]->addTask(Task);
    Tasks[1]->addTask(Task);
}

void MainWidget::send()
{
    PortOpenParamsType *Parameters;
    Parameters->IPAdress = "IP Adress example";
    Parameters->PortNum = 1;

    QVariant v;
    v.setValue(Parameters);

    task Task;
    Task.tasknum = 1;
    Task.data = v;
    Tasks[0]->addTask(Task);
}


Здесь хочу извлечь значение (case 1):

Код:
#include "thread1.h"

Thread1::Thread1(const QList<Tasking*>& allTasks)
{
    Tasks = allTasks;
}

void Thread1::run()
{
    task myTask;
    bool exit = FALSE;
    while(!exit)
    {
        myTask = Tasks[0]->getTask();
        v.setValue(myTask.data);
        switch (myTask.tasknum)
        {
            case 0:
                exit = TRUE;
            case 1:
                PortOpenParams *Parameters = v.value<PortOpenParamsType *>();
                emit showData(Parameters->IPAdress);
        }
    }
}

Прога вылетает, скажите плиз где я ошибся?


Название: Re: Использование QVariant
Отправлено: BRE от Август 23, 2010, 19:50
Я про указатель, который никуда не указывает...
Код
C++ (Qt)
void MainWidget::send()
{
   PortOpenParamsType *Parameters;
   ...
}
 


Название: Re: Использование QVariant
Отправлено: labview от Август 23, 2010, 19:55
Хорошо, я заменил одну строку, или что то друге имелось в виду? Прога ведёт себя так же.

Код:
    Parameters->IPAdress.fromAscii("IP Adress example");


Название: Re: Использование QVariant
Отправлено: BRE от Август 23, 2010, 20:00
Хорошо, я заменил одну строку, или что то друге имелось в виду? Прога ведёт себя так же.
Я про указатель, который никуда не указывает...
Код
C++ (Qt)
void MainWidget::send()
{
   PortOpenParamsType *Parameters;
   ...
}
 


Название: Re: Использование QVariant
Отправлено: labview от Август 23, 2010, 20:01
Так тоже вылетает  :(

Код:
void MainWidget::send()
{
    PortOpenParamsType Parameters;
    Parameters.IPAdress = "IP Adress example";
    Parameters.PortNum = 1;

    QVariant v;
    v.setValue(&Parameters);

    task Task;
    Task.tasknum = 1;
    Task.data = v;
    Tasks[0]->addTask(Task);
}


Название: Re: Использование QVariant
Отправлено: BRE от Август 23, 2010, 20:08
Сейчас ты помещаешь указатель на структуру Parameters в переменную QVariant, переменная Parameters выделена на стеке и после выхода из метода send() будет разрушена.
Т.е. ты передаешь указатель на структуру, которая будет тут же разрушена.
Может в этом дело, может еще в чем.
Отлаживай.


Название: Re: Использование QVariant
Отправлено: kuzulis от Август 23, 2010, 20:09
1. А у нас что, QVariant умеет работать с пользовательскими данными? типо структура, объект класса и т.п. ? О_о
2.
Код:
..
v.setValue(&Parameters);
...
Вы передаете адрес на несуществующий объект Parameters . (не существующий вне void MainWidget::send())

---
упс.. опередил


Название: Re: Использование QVariant
Отправлено: BRE от Август 23, 2010, 20:11
1. А у нас что, QVariant умеет работать с пользовательскими данными? типо структура, объект класса и т.п. ? О_о
А разве нет?


Название: Re: Использование QVariant
Отправлено: kuzulis от Август 23, 2010, 20:13
упс... понял, что преждевременно вбросил.  :)


Название: Re: Использование QVariant
Отправлено: labview от Август 23, 2010, 20:45
Работает! Только я не совсем понимаю что мне, после того как я передал данные, делать с ненужным мне обьектом.


Название: Re: Использование QVariant
Отправлено: BRE от Август 23, 2010, 20:47
Работает! Только я не совсем понимаю что мне, после того как я передал данные, делать с ненужным мне обьектом.
Передавай его по значению, а не по указателю. Тогда объект разрушиться вместе с QVariant.


Название: Re: Использование QVariant
Отправлено: labview от Август 23, 2010, 22:03
Работает! Только я не совсем понимаю что мне, после того как я передал данные, делать с ненужным мне обьектом.
Передавай его по значению, а не по указателю. Тогда объект разрушиться вместе с QVariant.


Вы не могли бы мне помочь, я не знаю как передать значение без указателя. Эта функция требует указатель, иначе к сожалению не компилируется.
Находится это в функции void MainWidget::send()

ЗЫ кнопка exit останавливает потоки, а крестик аппликацию (пока ещё не запрограммировал).


Название: Re: Использование QVariant
Отправлено: BRE от Август 23, 2010, 22:05
Вы не могли бы мне помочь, я не знаю как передать значение без указателя. Эта функция требует указатель, иначе к сожалению не компилируется.
Я тут набросал небольшой пример:
Код
C++ (Qt)
#include <QVariant>
#include <QDebug>
 
struct Type
{
   int         var1;
   QString     var2;
};
 
Q_DECLARE_METATYPE( Type );
 
void func( const QVariant &var )
{
   Type data;
   if( var.canConvert<Type>() )
       data = var.value<Type>();
 
   qDebug() << data.var1 << data.var2;
}
 
int main( int, char ** )
{
   Type data;
   data.var1 = 10;
   data.var2 = "Test";
 
#if 1
   QVariant var = qVariantFromValue( data );
#else
   QVariant var;
   var.setValue( data );
#endif
   qDebug() << var;
 
   func( var );
 
   return 0;
}
 


Название: Re: Использование QVariant
Отправлено: labview от Август 23, 2010, 22:16
По-моему понял, всё дело было в этой строке:
Код:
Q_DECLARE_METATYPE( Type );

вместо:
Код:
Q_DECLARE_METATYPE( Type *);

Спасибо огромное, на этом думаю мой трабл исчез.