crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в QGraphicsView Линейка
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
ufna Дата 25.8.2010, 13:39
  Писалось это в далеком (для меня) 2007ом, поэтому решение совершенно не оптимальное. Пока времени оформить в полноценный класс нет, в текущей реализации пару параметров нужно заменить ручками так, как может Ваше приложение.

В моем приложении !!SCENE_SIZE - это размер того прямоугольника, который всегда центрирован в окне, т.е. сцены "за ним" для вьюхи нет. Это можно заменить размером сцены, тогда будет именно для всей сцены.

!!ZOOM в коде - думаю совершенно ясно - это насколько сцена вся наша отмасштабирована.

Сейчас отметки начинаются так же, как на скрине выше - от центра по горизонтали и от LT угла по вертикали.

В принципе, код прозрачен, сложного ничего нет - кому нужно, немного допилите под свои нужды. Время будет, переделаю в полноценный по управлению класс для использования (т.к. для нормальной линейки нужно и нормальное управление положением точек, DPI, учет положения виджетов, "умное" определение толщины скроллов и т.п.).

Ах, да - !!DOTS_PER_SM - это количество точек в сантиметре при зуме в 1.0, т.е. настройка dpi через сантиметры.

Может еще что забыл вырезать, в общем если какие вопросы - отвечу. У меня этот класс еще и за создание и упарвление направляющими отвечает, я его подрезал чтобы не мешало.


a_control_line.h
//-----------------------------------------------------------------------------
// File: a_control_line.h
//
// Desc:
//-----------------------------------------------------------------------------

#ifndef A_CONTROL_LINE_H
#define A_CONTROL_LINE_H

#include <QWidget>
#include <QPixmap>
#include <QGraphicsView>

//--------------------------------------------------------------------------------------
// Name: cControlLine
// Desc:
//--------------------------------------------------------------------------------------
class cControlLine
    : public QWidget
{
    Q_OBJECT

public:
    cControlLine(QGraphicsView* controlledView, bool isHorizontal = true, QWidget *parent = 0);
    ~cControlLine() {}

    virtual void paint(QPainter *) {}
    bool preferImage() const { return m_prefer_image; }

private:
    void paintToStatic(QPainter * paint = 0);

public slots:
    void setPreferImage(bool pi) { m_prefer_image = pi; }
    void updateMe() { updated = false; update(); }

protected:
    void paintEvent(QPaintEvent *);
    void changeEvent(QEvent *event );
    void resizeEvent( QResizeEvent * event );

private:
    QPixmap m_tile;
    QImage *static_image;
    QGraphicsView *pView;

    bool updated;
    bool m_horizontal;
    bool m_prefer_image;

};

#endif


a_control_line.cpp
//-----------------------------------------------------------------------------
// File: a_control_line.cpp
//
// Desc:
//-----------------------------------------------------------------------------

#include "a_control_line.h"

#include <QBrush>
#include <QMenu>
#include <QPainter>
#include <QPainterPath>
#include <QPixmapCache>
#include <QScrollBar>
#include <QtEvents>

extern QPixmap cached(const QString &img);

//--------------------------------------------------------------------------------------
// cControlLine class constructor
//--------------------------------------------------------------------------------------
cControlLine::cControlLine(QGraphicsView* controlledView, bool isHorizontal, QWidget *parent)
    : pView(controlledView), m_horizontal(isHorizontal), QWidget(parent), m_prefer_image(true)
{
    m_tile = QPixmap(100, 100);
    m_tile.fill(Qt::white);

    static_image = 0;
    updated = false;

    if( m_horizontal )
        setFixedHeight(20);
    else
        setFixedWidth(20);
}

//--------------------------------------------------------------------------------------
void cControlLine::paintEvent(QPaintEvent *e)
{
    QPainter painter;
    if (preferImage()) {
        if( (!updated) || (!static_image) ){
            paintToStatic(&painter);
        }
        painter.begin(this);
        painter.setClipRect(e->rect());
        painter.drawImage(e->rect(), *static_image, e->rect());
        painter.end();
    }
    else {
        painter.begin(this);
        painter.fillRect(0, 0, width(), height(), QBrush(Qt::black));
        painter.end();
    }
}

//--------------------------------------------------------------------------------------
void cControlLine::paintToStatic(QPainter *painter)
{
    if( static_image )
        delete static_image;

    static_image = new QImage(width(), height(), QImage::Format_RGB32);

    painter->begin(static_image);

    painter->setRenderHint(QPainter::Antialiasing);
    painter->setRenderHint(QPainter::SmoothPixmapTransform);

    painter->save();
    painter->drawTiledPixmap(rect(), m_tile);
  
    QLinearGradient linearGradient(0,0,width(),height());

    linearGradient.setColorAt(0.0, Qt::white);

    if( this->isEnabled() ) {
        //linearGradient.setColorAt(0.5, Qt::lightGray);
    }
    else
        linearGradient.setColorAt(0.5, QColor(225, 225, 225));

    linearGradient.setColorAt(1.0, Qt::white);

    painter->setPen(Qt::NoPen);
    painter->setBrush(linearGradient);

    painter->drawRect(0,0,width(),height());

    painter->restore();

    painter->save();
    // HORIZONTAL
    //----------------------------------------------------------------------------------
    if( m_horizontal ) {
        int posX = 0;
        if( !pView->horizontalScrollBar()->isVisible() ) {
            posX = width()/2;
            if( pView->verticalScrollBar()->isVisible() )
                    posX -= 9;      // Нужно правильно изменить значение ширины этого скроллбара
        }
        else
            posX = ( !!SCENE_SIZE.width() * !!ZOOM ) / 2
                     - pView->horizontalScrollBar()->value();

        painter->setRenderHint(QPainter::Antialiasing, false);

        if( this->isEnabled() )
            painter->setPen(QPen(QColor(28, 175, 255, 255), 1));
        else
            painter->setPen(QPen(QColor(94, 198, 255, 225), 1));

        painter->setBrush(Qt::NoBrush);

        painter->drawLine(0, height()-1, width()-1, height()-1);
        painter->drawLine(posX, 4, posX, height()-1);

        int perCm = !!DOTS_PER_SM;
        int dimsR = (width()-posX) / perCm * 4 / !!ZOOM;

        // LINES
        //----------------------------------------------------------------------------------
        for( int i = 1; i <= dimsR; i++ ) {
            if( i % 2 == 1 )
                painter->drawLine(posX+i*perCm/2*!!ZOOM, 15,
                                                      posX+i*perCm/2*!!ZOOM, height()-1);
            else if( i % 10 == 0 )
                painter->drawLine(posX+i*perCm/2*!!ZOOM, 4,
                                                      posX+i*perCm/2*!!ZOOM, height()-1);
            else
                painter->drawLine(posX+i*perCm/2*!!ZOOM, 13,
                                                      posX+i*perCm/2*!!ZOOM, height()-1);
        }

        int dimsL = posX / perCm * 4 / !!ZOOM;
        for( int i = 1; i <= dimsL; i++ ) {
            if( i % 2 == 1 )
                painter->drawLine(posX-i*perCm/2*!!ZOOM, 15,
                                                      posX-i*perCm/2*!!ZOOM, height()-1);
            else if( i % 10 == 0 )
                painter->drawLine(posX-i*perCm/2*!!ZOOM, 4,
                                                      posX-i*perCm/2*!!ZOOM, height()-1);
            else
                painter->drawLine(posX-i*perCm/2*!!ZOOM, 13,
                                                      posX-i*perCm/2*!!ZOOM, height()-1);
        }

        // TEXTS
        //----------------------------------------------------------------------------------
        painter->save();

        if( this->isEnabled() )
            painter->setPen(Qt::black);
        else
            painter->setPen(Qt::darkGray);

        painter->drawText(posX+2, 12, "0");

        for( int i = 1; i <= dimsR; i++ )
            if( i % 5 == 0 )
                painter->drawText(posX+i*perCm*!!ZOOM+2, 12, QString("%1").arg(i*10) );

        for( int i = 1; i <= dimsL; i++ )
            if( i % 5 == 0 )
                painter->drawText(posX-i*perCm*!!ZOOM+2, 12, QString("%1").arg(i*10) );

        painter->restore();
    }
    // VERTICAL
    //----------------------------------------------------------------------------------
    else {
        int posY = 0;
        if( !pView->verticalScrollBar()->isVisible() )
            posY = ( height()-!!SCENE_SIZE.height() * !!ZOOM ) / 2;
        else
            posY -= pView->verticalScrollBar()->value();

        painter->setRenderHint(QPainter::Antialiasing, false);

        if( this->isEnabled() )
            painter->setPen(QPen(QColor(28, 175, 255, 255), 1));//255, 100, 30, 255), 1));
        else
            painter->setPen(QPen(QColor(94, 198, 255, 225), 1));

        painter->setBrush(Qt::NoBrush);

        painter->drawLine(width()-1, 0, width()-1, height()-1);
        painter->drawLine(4, posY, width()-1, posY);

        int perCm = !!DOTS_PER_SM;
        int dimsD = (height()-posY) / perCm * 4 / !!ZOOM;
        // LINES
        //----------------------------------------------------------------------------------
        for( int i = 1; i <= dimsD; i++ ) {
            if( i % 2 == 1 )
                painter->drawLine(15, posY+i*perCm/2*!!ZOOM,
                                                      width()-1, posY+i*perCm/2*!!ZOOM);
            else if( i % 10 == 0 )
                painter->drawLine(4, posY+i*perCm/2*!!ZOOM,
                                                      width()-1, posY+i*perCm/2*!!ZOOM);
            else
                painter->drawLine(13, posY+i*perCm/2*!!ZOOM,
                                                      width()-1, posY+i*perCm/2*!!ZOOM);
        }

        int dimsU = posY / perCm * 4 / !!ZOOM;
        for( int i = 1; i <= dimsU; i++ ) {
            if( i % 2 == 1 )
                painter->drawLine(15, posY-i*perCm/2*!!ZOOM,
                                                      width()-1, posY-i*perCm/2*!!ZOOM);
            else if( i % 10 == 0 )
                painter->drawLine(4, posY-i*perCm/2*!!ZOOM,
                                                      width()-1, posY-i*perCm/2*!!ZOOM);
            else
                painter->drawLine(13, posY-i*perCm/2*!!ZOOM,
                                                      width()-1, posY-i*perCm/2*!!ZOOM);
        }

        // TEXTS
        //----------------------------------------------------------------------------------
        painter->save();

        if( this->isEnabled() )
            painter->setPen(Qt::black);
        else
            painter->setPen(Qt::darkGray);

        painter->drawText( 0, posY-18, width()-1, 20, Qt::AlignRight | Qt::AlignBottom , "0");

        for( int i = 1; i <= dimsD; i++ )
            if( i % 5 == 0 )
                painter->drawText(0, posY+i*perCm*!!ZOOM-18, width()-1, 20, Qt::AlignRight | Qt::AlignBottom, QString("%1").arg(i*10) );

        for( int i = 1; i <= dimsU; i++ )
            if( i % 5 == 0 )
                painter->drawText(0, posY-i*perCm*!!ZOOM-18, width()-1, 20, Qt::AlignRight | Qt::AlignBottom, QString("%1").arg(i*10) );

        painter->restore();
    }
    painter->restore();

    updated = true;
    painter->end();
}

//--------------------------------------------------------------------------------------
void cControlLine::changeEvent( QEvent *event )
{    
    if( event->type() == QEvent::EnabledChange ) {
        updated = false;
        update();
    }
}

//--------------------------------------------------------------------------------------
void cControlLine::resizeEvent( QResizeEvent * event )
{
    QWidget::resizeEvent( event );
    updateMe();
}

FantasyOr Дата 25.8.2010, 12:42
 
Цитата(ufna @ 23.8.2010, 12:08) *
если как здесь устраивает, могу код сбросить.

это чисто виджет с двумя состояниями - вертикальный или горизонтальный. Далее - привязка к какой точки сцены (где у нас 0 будет), и обработка скроллбара и мастшабирования.


устраивает еще как! =)

красивое приложение, мне бы так... ^_^'


ufna,
shairovav( враг кошек )gmail.com
Litkevich Yuriy Дата 23.8.2010, 14:44
 
Цитата(ufna @ 23.8.2010, 15:08) *
если как здесь устраивает, могу код сбросить.
да, интересная линейка
ufna Дата 23.8.2010, 11:08
  если как здесь устраивает, могу код сбросить.

это чисто виджет с двумя состояниями - вертикальный или горизонтальный. Далее - привязка к какой точки сцены (где у нас 0 будет), и обработка скроллбара и мастшабирования.
FantasyOr Дата 23.8.2010, 10:24
  единственная линейка, которая упоминается вместе с QGraphicsView, это линейка прокрутки. может и куча, да вот никто не делится =)
kwisp Дата 23.8.2010, 10:15
  FantasyOr,
по-моему способов много.
я бы поискал готовое. их этих линеек уже куча 100%.
FantasyOr Дата 23.8.2010, 10:04
  Здравствуйте.
Подскажите пожалуйста, как лучше сделать линейку для рисовалки? примерно как в Paint.NET или в Word.
пока возникает только идея ставить еще 2 QGraphicsView либо QFrame слева и сверху и на них рисовать.
Спасибо.
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 19.2.2020, 7:58