Поиск:

Ответ в темуСоздание новой темы Создание опроса
> не работает прокрутка в классе QGraphicsView, не работает прокрутка в классе QGraphics 
:(
    Опции темы
olegkuzn
Дата 17.12.2015, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

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



Здравствуйте знатоки Qt.
У меня проблема - не работает прокрутка в QGraphicsView. 
Прокрутка вообще не реагирует ни на что.
Выкладываю сразу проект.
Постарался все подробно расписать в комментариях.
Код

// main.cpp - тут все понятно
#include "MainWindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow win;
    win.show();
    return a.exec();
}

Код

// MainWindow.h - описание главного окна системы
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include "centralwidget.h"
#include "linelayout.h"


class MainWindow : public QMainWindow
{
public:
    MainWindow(QWidget* parent = 0);

private:
    CentralWidget* m_pCentralWidget;
    LineLayout*    m_pLayout;

    QGraphicsView*   m_pView;
    QGraphicsScene*  m_pScene;

    HorizLinear*  m_pHoriz;
    QWidget*      m_pCentral;
};
#endif // MAINWINDOW_H

Код

// MainWindow.cpp - реализация главного окна системы
#include "MainWindow.h"
#include <QScrollBar>

MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
{
    m_pHoriz   = new HorizLinear(this); // создаем класс горизонтальной линейки
    m_pScene = new QGraphicsScene(QRectF(0,0,2000,2000),this);
    m_pView  = new QGraphicsView( m_pScene, this); // создаем класс вида сцены
    m_pView->centerOn(0,0);

    // создаем класс центрального виджета главного окна
    m_pCentralWidget = new CentralWidget(m_pHoriz, m_pView);

    setCentralWidget(m_pCentralWidget);
    setWindowTitle("Диаграмма");
    setGeometry(100,100,700,500);
}

Код

// файл centralwidget.h описание центрального виджета главного окна
#ifndef CENTRALWIDGET_H
#define CENTRALWIDGET_H

#include <QWidget>
#include "Linear.h"
#include "linelayout.h"
#include <QGraphicsView>
// класс центрального виджета для  главного окна (MainWindow)
class CentralWidget : public QWidget
{
    Q_OBJECT

public:
    CentralWidget(HorizLinear* pHoriz, QGraphicsView*  pCentral, QWidget* pParent = 0);
    ~CentralWidget();
private:
    LineLayout*   m_pLayout;
};

#endif // CENTRALWIDGET_H

Код

// файл centralwidget.cpp реализация центрального виджета главного окна
#include "centralwidget.h"
#include <QScrollBar>

CentralWidget::CentralWidget(HorizLinear *pHoriz, QGraphicsView* pCentral, QWidget *pParent)
             : QWidget(pParent)
{
    m_pLayout = new LineLayout(this);

    // добавляем элементы в пользовательский Layout
    m_pLayout->addWidget(pHoriz ,  LineLayout::Horline);
    m_pLayout->addWidget(pCentral, LineLayout::Center );

    // создаем соединение линеки прокрутки объекта класса QGraphicsView со слотом объекта класса HorizLinear
    // (который почему-то не отрабатывает)
    connect(pCentral->horizontalScrollBar(),SIGNAL(valueChanged(int)),pHoriz,SLOT(slotScrollBarValue(int)));

    setLayout(m_pLayout);
}

CentralWidget::~CentralWidget()
{

}

Код

// linelayout.h - содержит описание класса пользовательского layout используемого в классе CentralWidget
#ifndef LINELAYOUT_H
#define LINELAYOUT_H
#include <QLayout>
#include "Linear.h"

// класс компоновщика виджетов
class LineLayout : public QLayout
{
    Q_OBJECT

public:
    enum Pos { Horline = 1, Center = 3 };

    LineLayout(QWidget* parent = 0);

    virtual void addItem(QLayoutItem* item);
    void addWidget(QWidget *w, Pos position);

    virtual QLayoutItem* itemAt(int index) const;
    virtual int          count() const;
    virtual QLayoutItem* takeAt(int index);
    virtual QSize    sizeHint() const;
    Qt::Orientations expandingDirections() const;

    void setGeometry(const QRect &rect);

    QSize minimumSize();

private:

    QLayoutItem* m_pHoriz;
    QLayoutItem* m_pCentral;

    int m_nIndent;
};
#endif // LINELAYOUT_H

Код

// linelayout.cpp - содержит реализацию класса пользовательского layout используемого в классе CentralWidget
#include "linelayout.h"
LineLayout::LineLayout( QWidget *parent)
          : QLayout(parent)
          , m_nIndent(30)
{
    setSpacing(0);
    setMargin(0);
}

void LineLayout::addItem(QLayoutItem *item)
{
    // данная ф-ция не используется
    Q_UNUSED(item);
    return;
}
// добавление виджета в пользовательский Layout
void LineLayout::addWidget(QWidget *w, Pos position)
{
    QLayoutItem* item = new QWidgetItem(w);
    switch(position)
    {
    case(Horline) : m_pHoriz   = item; break;
    case(Center ) : m_pCentral = item; break;
    }
}

QLayoutItem* LineLayout::itemAt(int index) const
{
    switch(index)
    {
    case(1)  : return m_pHoriz ;
    case(3)  : return m_pCentral;
    }
    return 0;
}

int LineLayout::count() const
{
    return 2;
}

QLayoutItem* LineLayout::takeAt(int index)
{
    if(index < 0 || index >= count())
        return 0;
    return itemAt(index);
}

QSize LineLayout::sizeHint() const
{
    return QSize(m_nIndent*3,m_nIndent*3);
}

QSize LineLayout::minimumSize()
{
    return QSize(m_nIndent*3,m_nIndent*3);
}

Qt::Orientations LineLayout::expandingDirections() const
{
    return Qt::Horizontal | Qt::Vertical;
}

void LineLayout::setGeometry(const QRect &rect)
{
    m_pHoriz->setGeometry(QRect(  0,         0,    rect.width(),               m_nIndent));
    m_pCentral->setGeometry(QRect(0, m_nIndent,    rect.width(), rect.height()-m_nIndent));
}

Код

// linear.h описание класс "линейки" используемой в центральном виджете
#ifndef LINEAR_H
#define LINEAR_H
#include <QWidget>
#include <QPaintEvent>

// класс горизонтальной линейки
class HorizLinear : public QWidget
{
    Q_OBJECT
public:
    HorizLinear( QWidget* parent = 0); // конструктор

public slots:
    void slotScrollBarValue(int a); // слот реагирования на изменение полосы прокрутки

protected:
    virtual void paintEvent(QPaintEvent *event);  // событие перерисовки объекта
};

#endif // LINEAR_H

Код

// linear.cpp реализация класса "линейки" используемой в центральном виджете
#include "Linear.h"
#include <QPainter>
#include <QDebug>

//================================================================
//  реализация класса горизонтальной линейки
HorizLinear::HorizLinear(QWidget *parent)
           : QWidget(parent)
{}

// этот код работает нормально и к вопросу не имеет никакого значения
void HorizLinear::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    int nHeight1 = height()*0.67;
    int nHeight2 = height();
    int nHeight3 = height()*0.5;

    int offSet  = 4;
    int counter = 1;

    QString str;
    painter.drawLine(0,0,0,nHeight2);
    painter.setFont(QFont("Arial",6,QFont::Normal));
    for(int i = offSet; i < width(); i+=4)
    {
        if(counter%10 == 0)
        {
            painter.drawLine(i,0,i,nHeight2);
            str.setNum(counter/10);
            painter.drawText(i+2,8,str);
        }
        else if(counter%5 == 0)
            painter.drawLine(i,nHeight3,i,nHeight2);
        else
            painter.drawLine(i,nHeight1,i,nHeight2);

        counter++;
    }
}

// просто хотим проверить вызов слота
void HorizLinear::slotScrollBarValue(int a)
{
    qDebug() << "slotScrollBarValue" << a;
}


З.Ы. Не нашел значка прикрепления файла.
Можно ли как-нибудь выложить архив проекта

PM MAIL   Вверх
olegkuzn
Дата 18.12.2015, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

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



Хотел бы упростить этот страшный вопрос со страшными вставками страшного кода.
Скорее всего проблема заключается вот в чем :

Если объект класс QGraphicsView становится центральным виджетом главного окна то прокрутка нормально отрабатывает.
Код

MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
{
    // в данном случае прокрутка нормально отрабатывает
    
    m_pScene = new SimpleScene(this);
    m_pView  = new QGraphicsView(m_pScene, this);

    setCentralWidget(m_pView);
}


Но если объект класса QGraphicsView прикрепляется  сначала к центральному виджету а затем центральный виджет делается центральным виджетом главного окна то прокрутка перестает работать.
Код

MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
{
    // а сейчас прокрутка перестает работать

    m_pScene = new SimpleScene(this);
    m_pView  = new QGraphicsView(m_pScene, this);

    m_pCentral = new CentralWidget(m_pView, this);

    setCentralWidget(m_pCentral);
}


складывается ощущение что события мыши "застревают" на уровне центрального виджета.

Дополнительно выкладываю простейший код реализации центрального виджета.
Код

#include "centralwidget.h"
#include <QResizeEvent>

CentralWidget::CentralWidget(QGraphicsView* pView, QWidget *parent)
             : QWidget(parent)
             , m_pView(pView)
{

}

void CentralWidget::resizeEvent(QResizeEvent *resizeEvent)
{
    m_pView->resize(resizeEvent->size());
}


Подскажите как сделать прокрутку элемента QGraphicsView в центральном виджете. Цетральный виджет необходим. Он будет содержать несколько объектов со своим Layout-ом.

Заранее благодарен.


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


Эксперт
****


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

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



Зачем нужен центральный виджет - это понятно. А зачем тебе свой лейаут?
Нормальное использование:
Центальный виджет - сплиттер.
Первый виджет которого - QGraphicsView, а второй - содержит панель с остальными элементами.
Если нет необходимости двигать границу между виджетами, используется QBoxLayout.
По краям можно навешать QDockWidget, которые пользватель может перемещать и скрывать как ему захочется.
Также можно использовать QToolBar, куда кроме кнопок, можно поместить QComboBox.
Пользовательские настройки можно сохранять с помощью QSettings.
Всё достаточно гибко, ничего нестандартного не нужно.


Это сообщение отредактировал(а) math64 - 18.12.2015, 14:03
PM   Вверх
olegkuzn
Дата 18.12.2015, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

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



Помимо объекта QGraphicsView в центральном объекте будет содержаться большое количество объектов производных от QWidget типа линеек и т.п. Получился очень "страшный" QSplitter. К тому же размеры линеек не должны меняться самостоятельно а зависят от объекта QGraphicsView.
PM MAIL   Вверх
olegkuzn
Дата 18.12.2015, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

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



Нашел выход.
Код

#include "centralwidget.h"
#include <QResizeEvent>


CentralWidget::CentralWidget(QGraphicsView* pView, QWidget *parent)
             : QWidget(parent)
             , m_pView(pView)
{
    setAttribute(Qt::WA_TransparentForMouseEvents); // ВОТ ЭТОТ КОД НАДО ДОБАВИТЬ
}

void CentralWidget::resizeEvent(QResizeEvent *resizeEvent)
{
    m_pView->resize(resizeEvent->size());
}

Всем спасибо кто интересовался этой темой.

Добавлено через 15 секунд
Нашел выход.
Код

#include "centralwidget.h"
#include <QResizeEvent>


CentralWidget::CentralWidget(QGraphicsView* pView, QWidget *parent)
             : QWidget(parent)
             , m_pView(pView)
{
    setAttribute(Qt::WA_TransparentForMouseEvents); // ВОТ ЭТОТ КОД НАДО ДОБАВИТЬ
}

void CentralWidget::resizeEvent(QResizeEvent *resizeEvent)
{
    m_pView->resize(resizeEvent->size());
}

Всем спасибо кто интересовался этой темой.

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

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

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


 




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


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

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