Поиск:

Ответ в темуСоздание новой темы Создание опроса
> рисование в MainWindow, ООП, MVC, архитектура App, доступ к переменной из другого класса 
:(
    Опции темы
Aurus
Дата 20.6.2012, 06:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 14.8.2005
Где: Новосибирск

Репутация: нет
Всего: 0



Запутался с классами, кого откуда наследовать. Задача: загрузка данных в модель->расчитывается график-> отображается график; если данные поменялись-> пересчитать график->перерисовать график.

Есть несколько классов: 
MyModel:QAbstractTableModel (с данными)
myWindow:QMainWindow (рисование, отображение) - рисование надо убрать.
Predict (расчёты графика из данных) 
Plot (пересчёт координат) - рисование надо добавить. 

Сейчас имею примерно следующее:
Код

myWindow::myWindow(QWidget *parent) : QMainWindow(parent){
    setupUi(this);
        // создаю объект модели и получаю оттуда данные в вектор.
        tableModel=new MyModel(source,this);
        tableView->setModel(tableModel);
        QVector<QPointF> points;
        for(int n=0; n< tableModel->getValues().size(); ++n){
            points.append(tableModel->getValues().at(n));
        }
        //создаю объект класса Pedict чтобы получить рассчитанные данные
        Predict *predict = new Predict(this);
        QList th;
        th.append(predict->GradDesc(points));
        QVector<QPointF> hx(predict->Hypothesis(points,th));
    //рисование
    ...
    QPixmap *pm =new QPixmap(500,500);
    pm->fill(Qt::white);
    QPainter *p = new QPainter(pm);
    p->drawLine(...);
        QLabel *label = new QLabel;
        label->setPixmap(*pm);
    //устанавливаю свой рисунок на CentralWidget
        QWidget *mainWidget = new QWidget(this);
        QGridLayout *gridLayout = new QGridLayout(mainWidget);
            gridLayout->addWidget(label,1,1,1,5);
            gridLayout->addWidget(textLabel,2,1,1,5);
            ...
        setCentralWidget(mainWidget);
}

Всё хорошо,но перерисовать график в случае изменения данных в модели не имею. Подумал рисовать в классе Plot на QLabel(из класса myWindow). Попробывал создать QLabel в mywindow.ui, рисовать на нём в классе Plot, выводить label вклассе  myWindow
Код

plot.h: class Plot : public QObject, public Ui::myWindow // чтобы иметь доступ к QLabel из mywindow.ui

plot.cpp:
Plot::Plot(...)
{
    QPixmap *pm =new QPixmap(500,500);
    QPainter *p = new QPainter(pm);
    p->drawLine(...);
 qDebug()<<"hello1"; //выводит
    label->setPixmap(*pm);
 qDebug()<<"hello2"; //уже не выводит
}

Код

mywindow.h: class myWindow : public QMainWindow, public Ui::myWindow

mywindow.cpp:
myWindow::myWindow(QWidget *parent) : QMainWindow(parent){
        setupUi(this);
        // создаю объект модели и получаю оттуда данные в вектор.
        tableModel=new MyModel(source,this);
        tableView->setModel(tableModel);
        QVector<QPointF> points;
        for(int n=0; n< tableModel->getValues().size(); ++n){
            points.append(tableModel->getValues().at(n));
        }
        //создаю объект класса Pedict чтобы получить рассчитанные данные
        Predict *predict = new Predict(this);
        QList th;
        th.append(predict->GradDesc(points));
        QVector<QPointF> hx(predict->Hypothesis(points,th));
    //рисование
    Plot *pl =  new Plot(hx, points, 0);
    
    //устанавливаю свой рисунок на CentralWidget
        QWidget *mainWidget = new QWidget(this);
        QGridLayout *gridLayout = new QGridLayout(mainWidget);
            gridLayout->addWidget(label,1,1,1,5);
            gridLayout->addWidget(textLabel,2,1,1,5);
            ...
        setCentralWidget(mainWidget);
}

К сожалению, мое решение заканчивается: The program has unexpectedly finished.
(предположительно ошибка в классе Plot в строчке label->setPixmap(*pm);)

Это сообщение отредактировал(а) Aurus - 20.6.2012, 06:28
PM MAIL ICQ   Вверх
math64
Дата 20.6.2012, 07:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Посмотри itemviews/chart из примеров Qt, класс PieView - там по модели рисуется диагамма. Аналогично можно рисовать и график.
Никакой Pixmap при изменении данных создавать не нужно - всё рисуется непосредственно в PieView::paintEvent(), в твоём случае
Код

class Plot : public QAbstractItemView
{
    Q_OBJECT
public:
    Plot(QWidget* parent = 0);

protected slots:
    // В этих слотах обрабатываешь изменения данных
    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
    void rowsInserted(const QModelIndex &parent, int start, int end);
    void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);

protected:
    // Здесь делаешь отрисовку графика
    void paintEvent(QPaintEvent *event);
    // Обрабатываешь изменения размеров графика
    void resizeEvent(QResizeEvent *event);
    // При необходимости перегружаешь другие методы QAbstractItemView
}


Добавлено через 12 минут и 49 секунд
PS: в твоём коде главная ошибка - наследование Plot от Ui::myWindow - оно не даёт доступа к QLabel из mywindow.ui, а создаёт собственную неинициализированную QLabel. Ui::myWindow должен использоваться только в myWindow и лучше не наследовать myWindow от Ui::myWindow. а оставить Ui::myWindow* ui; как в настройках делается по умолчанию. При необходимости доступа к виджетам, созданным в дизайнере из других классов создаётся метод доступа:
Код

QLabel* myWindow::getLabel()
{
    return ui->label;
}

PM   Вверх
Aurus
Дата 21.6.2012, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 14.8.2005
Где: Новосибирск

Репутация: нет
Всего: 0



Цитата(math64 @ 20.6.2012,  07:39)
Посмотри itemviews/chart из примеров Qt, класс PieView - там по модели рисуется диагамма. Аналогично можно рисовать и график....

math64, спасибо за пример. Сижу теперь парюсь с QAbstractItemView, при наследовании надо переопределять 8 функций! сложно пока идёт с ними. 
Код

    QRect visualRect(const QModelIndex &index) const;
    void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
    QModelIndex indexAt(const QPoint &point) const;
    QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,Qt::KeyboardModifiers modifiers);
    int horizontalOffset() const;
    bool isIndexHidden(const QModelIndex &index) const;
    void setSelection(const QRect&, QItemSelectionModel::SelectionFlags command);
    QRegion visualRegionForSelection(const QItemSelection &selection) const;

PM MAIL ICQ   Вверх
math64
Дата 21.6.2012, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



visualRect() - оставить как PieView (вызывает itemRect() и учитывает полосы прокрутки)
scrollTo(), moveCursor(), horizontalOffset(), verticalOffset(), isIndexHidden(), setSelection(), visualRegionForSelection() - также
indexAt() - переписать самому. У меня для гистограммы:
Код

QModelIndex HistView::indexAt(const QPoint &point) const
{
    if (validItems == 0)
        return QModelIndex();
    int wx = point.x() + horizontalScrollBar()->value();
    int wy = point.y() + verticalScrollBar()->value();
    int listItem;
    if (wx < totalWidth) {
        if (wx < margin)
            return QModelIndex();
        listItem = int ((wx - margin) / columnWidth);
    } else {
        double itemHeight = QFontMetrics(viewOptions().font).height();
        listItem = int((wy - margin) / itemHeight);
    }
    int validRow = 0;
    for (int row = 0; row < model()->rowCount(rootIndex()); ++row) {
        QModelIndex index = model()->index(row, 1, rootIndex());
        if (model()->data(index).toDouble() > 0.0) {
            if (listItem == validRow)
                return model()->index(row, 0, rootIndex());
            validRow++;
        }
    }
    return QModelIndex();
}


PM   Вверх
Aurus
Дата 21.6.2012, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 14.8.2005
Где: Новосибирск

Репутация: нет
Всего: 0



Код

QModelIndex Plot::indexAt(const QPoint &point) const
{
    qDebug()<<"hello";
    return QModelIndex();
}

даже hello не выводит, её кто-нибудь вызывает? или мне её надо вызывать в конструкторе самому когда надо? 
В документации написано, что функция indexAt(); возвращает индекс записи, расположенной в точке point, в модели. smile 
PM MAIL ICQ   Вверх
math64
Дата 21.6.2012, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



indexAt() вызывается, например, из QAbstractItemView::mousePressedEvent() для определения куда пользоваетель нажал мышкой.
Если тебе в Plot нужно только нарисовать график - можешь использовать свою реализацию, тогда нажатия мыши будут игнорироваться.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.1204 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.