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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Model-View + QGraphicsScene  (Прочитано 9470 раз)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« : Апрель 27, 2016, 12:42 »

Есть модель
Код:
 Base-----|---------|
             |             |
          Station     Station
               |       |         |
               |       |          |
         Device      Device   Device

Создаю абстрактный класс элемента модели
Код
C++ (Qt)
#include <QObject>
#include <QVariant>
#include <QIcon>
#include <QList>
#include <QString>
 
#include <QGraphicsScene>
 
class CommonElement: public QObject
{
   Q_OBJECT
 
public:
   explicit CommonElement(QObject*parent = 0);
   virtual ~CommonElement();
 
   virtual CommonElement*appendChild() = 0;
   virtual QVariant getIcon() = 0;
   virtual QVariant getHeaderData(int ) = 0;
   virtual void function() = 0;
   virtual int amountColumn() = 0;        
 
public:
   QString str;
   QGraphicsScene *scene;
};
 
Затем отдельно для каждого класса элемента
Base:
Код
C++ (Qt)
Base::Base(QObject *parent):
   CommonElement(parent)
{
   str = "Base";
 
//    scene = new QGraphicsScene(this);  ИЗ-ЗА ЭТОГО ПАДАЕТ ПРОГРАММА
//    scene->addText(str);                     !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
 
Base::~Base()
{
}
 
CommonElement* Base::appendChild()
{
   Station *station = new Station(this);
   return station;
}
 
QVariant Base::getIcon()
{
   static QIcon icon("C:/Qt/Qt5.2.1/Tools/QtCreator/bin/build-MyMTLYNX-Desktop_Qt_5_2_1_MinGW_32bit-Debug/image/database.png");
   return QVariant::fromValue<QIcon>(icon);
}
 
QVariant Base::getHeaderData(int section)
{
   switch(section)
   {
       case 0: return tr("Name");
       case 1: return tr("Count Device");
       case 2: return tr("Workset");
   }
   return QVariant();
}
 
int Base::amountColumn()
{
   return 3;
}
 
void Base::function()
{
   qDebug()<<"Base";
}
 
Station:
Код
C++ (Qt)
Station::Station(CommonElement *parent):
 CommonElement(parent)
{
   str = "MyStantion";
 
   //scene = new QGraphicsScene(this);
   //scene->addText(str);
}
 
Station::~Station()
{
}
 
CommonElement* Station::appendChild()
{
   Device *device = new Device(this);  
   return device;
}
 
QVariant Station::getIcon()
{
   static QIcon icon("C:/Qt/Qt5.2.1/Tools/QtCreator/bin/build-MyMTLYNX-Desktop_Qt_5_2_1_MinGW_32bit-Debug/image/station.png");
   return QVariant::fromValue<QIcon>(icon);
}
 
QVariant Station::getHeaderData(int section)
{
   switch(section)
   {
       case 0: return tr("Connection");
       case 1: return tr("Serial Number");
       case 2: return tr("Network Number");
       case 3: return tr("Type Device");
   }
   return QVariant();
}
 
int Station::amountColumn()
{
   return 4;
}
 
void Station::function()
{
   qDebug()<<"Station->str = " + str;
}
 
 

Device:
Код
C++ (Qt)
Device::Device(QObject *parent):
   CommonElement(parent)
{
   str = "MyDevice";
 
   //scene = new QGraphicsScene(this);
   //scene->addText(str);
}
 
Device::~Device()
{
}
 
CommonElement* Device::appendChild()
{
   return NULL;
}
 
QVariant Device::getIcon()
{
   static QIcon icon("C:/Qt/Qt5.2.1/Tools/QtCreator/bin/build-MyMTLYNX-Desktop_Qt_5_2_1_MinGW_32bit-Debug/image/device.png");
   return QVariant::fromValue<QIcon>(icon);
}
 
QVariant Device::getHeaderData(int section)
{
   switch(section)
   {
       case 0: return tr("Name");
       case 1: return tr("Description");
   }
 
   return QVariant();
}
 
int Device::amountColumn()
{
   return 2;
}
 
void Device::function()
{
   qDebug()<<"Device->str = " + str;
}
 

Хочу чтобы при нажатии на элемент модели
подгружалась картинка сцены во вьювер,
но к сожалению такого не происходит программа вылетает
не могу понять почему???
« Последнее редактирование: Апрель 27, 2016, 15:37 от demaker » Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #1 : Апрель 27, 2016, 12:51 »

Вот как выглядит окно

Слева общая модель - типа дерево
Справа модель - типа листа. При нажатии на элемент модели дерево модель листа обновляется для отображения элементов входящих в текущий выбранный элемент.
Внизу GraphicsView.
« Последнее редактирование: Апрель 27, 2016, 12:56 от demaker » Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #2 : Апрель 27, 2016, 12:58 »

Вот что показывает Debug при возникновении ошибки
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #3 : Апрель 27, 2016, 12:58 »

Если надо могу выслать весь проект Улыбающийся
Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #4 : Апрель 27, 2016, 13:46 »

Вот проект
Спасибо!
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Апрель 27, 2016, 15:13 »

1. Зачем для каждого элемента создавать отдельную сцену?
2. В QVariant Station::getIcon() и подобных используйте механизм ресурсов, а не иконки по непонятному пути.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #6 : Апрель 27, 2016, 15:26 »

1. Зачем для каждого элемента создавать отдельную сцену?
2. В QVariant Station::getIcon() и подобных используйте механизм ресурсов, а не иконки по непонятному пути.

1.после того как будет выбран элемент модели, подгружается сцена этого элемента с отрисовкой того количества элементов сколько этот выбранный элемент в себя включает.

2.К сожалению я не понял что Вы имели ввиду Непонимающий
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Апрель 27, 2016, 15:36 »

я про это

Код:
QVariant Device::getIcon()
{
    static QIcon icon("C:/Qt/Qt5.2.1/Tools/QtCreator/bin/build-MyMTLYNX-Desktop_Qt_5_2_1_MinGW_32bit-Debug/image/device.png");
    return QVariant::fromValue<QIcon>(icon);
}

Положите все иконки в ресурсы и замените первую строчку на что то типа
static QIcon icon(":/icons/myDeviceIcon");

Иначе при перенесении проги на др. машину пропадут иконки.

По поводу сцены - ее надо убрать из самих девайсов и сделать частью окна-превью (связав с QGraphicsView).
При вызове превью уже будете на сцену кидать то, что хотите отобразить.
« Последнее редактирование: Апрель 27, 2016, 15:40 от Racheengel » Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #8 : Апрель 27, 2016, 15:46 »

я про это

Код:
QVariant Device::getIcon()
{
    static QIcon icon("C:/Qt/Qt5.2.1/Tools/QtCreator/bin/build-MyMTLYNX-Desktop_Qt_5_2_1_MinGW_32bit-Debug/image/device.png");
    return QVariant::fromValue<QIcon>(icon);
}

Положите все иконки в ресурсы и замените первую строчку на что то типа
static QIcon icon(":/icons/myDeviceIcon");

Иначе при перенесении проги на др. машину пропадут иконки.


Переделал спасибо  Улыбающийся

По поводу сцены - ее надо убрать из самих девайсов и сделать частью окна-превью (связав с QGraphicsView).
При вызове превью уже будете на сцену кидать то, что хотите отобразить.

Т.е нужно создать объект который будет формировать сцену и выдавать на нее указатель при клике на элемент модели, я Вас правильно понял.

« Последнее редактирование: Апрель 27, 2016, 17:10 от demaker » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #9 : Апрель 27, 2016, 16:03 »

Сцена - должна быть частью модели? Что-то в ней будет храниться важное?
Или она только для отображения служит?

Если второе, то сделайте функцию в CommonElement типа
void ShowOnScene(QGraphicsScene* scene)
и пусть ее вьювер вызывает, когда юзер на соотв. элемент модели кликнет.
И эта функция будет уже менять сцену.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #10 : Апрель 27, 2016, 16:27 »

Сцена - должна быть частью модели? Что-то в ней будет храниться важное?
Или она только для отображения служит?

У нас есть модель
элемент-модели может быть как parent так и child.
при нажатии на этот элемент на сцене отображаются все его дочерние элементы.
Отображаются т.е имеется ввиду рисуются квадратики или ...

И при нажатии на сцене на любой дочерний элемент, мы должны перейти соответственно на его сцену и отрисовать все дочерние элементы, а также селектор в treeview должен перейти на этот элемент.

Получается при создании Элемента модели в ней должен создаваться объеты типа
Код:
QGraphicsObject и QGraphicsScene 
или нет?

Если да, то когда я пишу код создания сцены в элементе-модели, то программа у меня падает Непонимающий
« Последнее редактирование: Апрель 27, 2016, 17:08 от demaker » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #11 : Апрель 27, 2016, 18:00 »

Ваши элементы - это наследники QGraphicsObject.
А сцена - это то, что их компонует.
Создавайте для каждого элемента отдельный QGraphicsObject и пакуйте их на сцену, которая связана с вьювером. Кликнул юзер на элемент - очищаете сцену и выводите на нее содержимое выбранного элемента.
Как то так.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #12 : Апрель 28, 2016, 11:19 »

Сделал как Вы сказали
Код
C++ (Qt)
class CommonElement;
class CommonGraphicsObject : public QGraphicsObject
{
   Q_OBJECT
 
public:
   explicit CommonGraphicsObject(CommonElement *element,QGraphicsObject *parent = 0);
   virtual ~CommonGraphicsObject();
 
   virtual QRectF boundingRect() const = 0;
   virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) = 0;
   virtual CommonElement *getModelElement() = 0;
 
public:
   CommonElement *commonelement;
};
 

Код
C++ (Qt)
DeviceGraphicsObject::DeviceGraphicsObject(Device *element,QGraphicsObject * parent):
   CommonGraphicsObject(element,parent)
{
   //device = element;
   commonelement = element;
}
 
DeviceGraphicsObject::~DeviceGraphicsObject()
{
 
}
 
QRectF DeviceGraphicsObject::boundingRect() const
{
   return QRectF(0,0,30,20);
}
 
void DeviceGraphicsObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
   QPen pen(Qt::black);
   painter->setBrush(Qt::yellow);
   painter->setPen(pen);
   painter->drawRect(0,0,30,20);
}
 
CommonElement *DeviceGraphicsObject::getModelElement()
{
   return commonelement;
}
 

Код
C++ (Qt)
StationGraphicsObject::StationGraphicsObject(Station *element, QGraphicsObject * parent):
   CommonGraphicsObject(element,parent)
{
   commonelement = element;
}
 
StationGraphicsObject::~StationGraphicsObject()
{
 
}
 
QRectF StationGraphicsObject::boundingRect() const
{
   return QRectF(0,0,30,20);
}
 
void StationGraphicsObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
   QPen pen(Qt::black);
   painter->setBrush(Qt::green);
   painter->setPen(pen);
   painter->drawRect(0,0,30,20);
}
 
CommonElement *StationGraphicsObject::getModelElement()
{
   return commonelement;
}
 

Обработка сигнала при клике на TreeView
Код
C++ (Qt)
void MainWindow::clickedTreeView(QModelIndex index)
{
   if(index.isValid())
   {
       currentModelIndex = index;
       currentElement = reinterpret_cast<CommonElement*>(currentModelIndex.internalPointer());
       listmodel->setRoot(currentModelIndex);
       setPathLabel(currentElement);
       listview->loadHeaderLine(currentElement);
 
       //загрузка отображения при клике
       graphicsScene->clear();
       if(!currentElement->children().isEmpty()){
           qDebug()<<"No Empty";
           for(int i = 0; i < currentElement->children().size(); i++){              
               CommonElement *ce = (CommonElement*)(currentElement->children().at(i));
               CommonGraphicsObject *cgo = ce->getGraphicsObject();
               cgo->setPos(10+(cgo->boundingRect().width() + 5)*i,10); //!!!!!но почему-то программа вылетает при  
                                                                                               //!!!!! установки координат и
               graphicsScene->addItem(cgo);                                      //!!!!!при добавлении объекта на сцену  
           }
           graphicsView->setScene(graphicsScene);
       }
   }
}
 

Скажите может я что-то делаю не правильно Непонимающий
« Последнее редактирование: Апрель 28, 2016, 11:27 от demaker » Записан
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #13 : Апрель 28, 2016, 12:11 »

Прошу прощнеия

Код:
scene->clear();

удаляет все объекты со сцены
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #14 : Апрель 28, 2016, 14:00 »

так заработало то или как?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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