Russian Qt Forum
Октябрь 13, 2024, 13:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование QVariant  (Прочитано 9144 раз)
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);
        }
    }
}

Прога вылетает, скажите плиз где я ошибся?
Записан
BRE
Гость
« Ответ #1 : Август 23, 2010, 19:50 »

Я про указатель, который никуда не указывает...
Код
C++ (Qt)
void MainWidget::send()
{
   PortOpenParamsType *Parameters;
   ...
}
 
« Последнее редактирование: Август 23, 2010, 19:59 от BRE » Записан
labview
Гость
« Ответ #2 : Август 23, 2010, 19:55 »

Хорошо, я заменил одну строку, или что то друге имелось в виду? Прога ведёт себя так же.

Код:
    Parameters->IPAdress.fromAscii("IP Adress example");
Записан
BRE
Гость
« Ответ #3 : Август 23, 2010, 20:00 »

Хорошо, я заменил одну строку, или что то друге имелось в виду? Прога ведёт себя так же.
Я про указатель, который никуда не указывает...
Код
C++ (Qt)
void MainWidget::send()
{
   PortOpenParamsType *Parameters;
   ...
}
 
Записан
labview
Гость
« Ответ #4 : Август 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);
}
Записан
BRE
Гость
« Ответ #5 : Август 23, 2010, 20:08 »

Сейчас ты помещаешь указатель на структуру Parameters в переменную QVariant, переменная Parameters выделена на стеке и после выхода из метода send() будет разрушена.
Т.е. ты передаешь указатель на структуру, которая будет тут же разрушена.
Может в этом дело, может еще в чем.
Отлаживай.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #6 : Август 23, 2010, 20:09 »

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

---
упс.. опередил
Записан

ArchLinux x86_64 / Win10 64 bit
BRE
Гость
« Ответ #7 : Август 23, 2010, 20:11 »

1. А у нас что, QVariant умеет работать с пользовательскими данными? типо структура, объект класса и т.п. ? О_о
А разве нет?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Август 23, 2010, 20:13 »

упс... понял, что преждевременно вбросил.  Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
labview
Гость
« Ответ #9 : Август 23, 2010, 20:45 »

Работает! Только я не совсем понимаю что мне, после того как я передал данные, делать с ненужным мне обьектом.
Записан
BRE
Гость
« Ответ #10 : Август 23, 2010, 20:47 »

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

Работает! Только я не совсем понимаю что мне, после того как я передал данные, делать с ненужным мне обьектом.
Передавай его по значению, а не по указателю. Тогда объект разрушиться вместе с QVariant.


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

ЗЫ кнопка exit останавливает потоки, а крестик аппликацию (пока ещё не запрограммировал).
Записан
BRE
Гость
« Ответ #12 : Август 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;
}
 
Записан
labview
Гость
« Ответ #13 : Август 23, 2010, 22:16 »

По-моему понял, всё дело было в этой строке:
Код:
Q_DECLARE_METATYPE( Type );

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

Спасибо огромное, на этом думаю мой трабл исчез.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.101 секунд. Запросов: 23.