crossplatform.ru

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


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

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

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


Последние 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 Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 16:52