crossplatform.ru

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

3 страниц V  < 1 2 3  
Ответить в данную темуНачать новую тему
> Масштабирование с помощью колесика мышки, ?
AD
  опции профиля:
сообщение 9.7.2008, 15:40
Сообщение #21


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Вот так вот :) Искал пример использования двоичных файлов, а натолкнулся на пример, который может помочь решить проблему масштабироваиия! :)
%QTDIR%examples\threads\mandelbrot
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 11.7.2008, 11:50
Сообщение #22


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Век живи, век учись! Вот так выглядит код, который заставляет правильно работать масштабирование: :)
class PlotSettings
{
public:
    double minX;
    double maxX;
    int numXTicks;
    double minY;
    double maxY;
    int numYTicks;

protected:
    static void adjustAxis(double& min, double& max, int& numTicks);

public:
    PlotSettings();
    void scroll(int dx, int dy);
    void scale(double delta_x, double delta_y);
    void adjust();
    double spanX() const { return fabs(maxX - minX); }
    double spanY() const { return fabs(maxY - minY); }
};


/// Увеличение/уменьшение значения minX, maxX, minY, maxY на интервал между 2-мя отметками
void PlotSettings::scale(double delta_x, double delta_y)
{
    if((minX == maxX || minY == maxY) && delta_x < 0 && delta_y < 0) return;

    double stepX = spanX() / numXTicks;
    minX -= delta_x * stepX;
    maxX += delta_x * stepX;

    double stepY = spanY() / numYTicks;
    minY -= delta_y * stepY;
    maxY += delta_y * stepY;
}



/// Класс для отображения параметров по времени или по расстоянию
class GraphicDisplay : public QDialog, public Ui::GraphicDisplayClass
{
    Q_OBJECT

private:
    QMap<int, QVector<QPointF>> curveMap;       ///< список всех изображаемых кривых
    ParamPlotSettings settings;                    ///< настройка для определения масштаба
    QRubberBand* rubber;                        ///< "резиновая лента"
    QPoint origin;                                ///< начальные координаты выделяемой области
    bool rubberBandIsShown;                        ///< флажок попадания курсора в "резиновую ленту"
    QPen myPen;                                    ///< карандаш для рисования линий определенной жирности и цвета
    enum { MARGIN = 10 };

    QPainter painter;                            ///< рисовальщик
    QVector<QPointF> data;                        ///< вектор загружаемой кривой

private:
    void drawGrid(QPainter* painter);
    void drawCurves(QPainter* painter);
    void drawLegend(QPainter* painter, QRect& rect, int& k, int id);
    QPointF initXY(double& sx, double& sy);

protected:
    void paintEvent(QPaintEvent* events);
    void keyPressEvent(QKeyEvent* events);
    void wheelEvent(QWheelEvent* events);
    void mousePressEvent(QMouseEvent* events);
    void mouseMoveEvent(QMouseEvent* events);
    void mouseReleaseEvent(QMouseEvent* events);
    void resizeEvent(QResizeEvent* events) { QDialog::resizeEvent(events); update(); }
    void closeEvent(QCloseEvent* events) { QDialog::closeEvent(events); }
    void showEvent(QShowEvent* events) { QDialog::showEvent(events); }

public:
    GraphicDisplay(QWidget *parent = 0);
    GraphicDisplay(QWidget *parent, ParamPlotSettings& st);
    ~GraphicDisplay();
    void zoom(double delta) { settings.scale(delta, delta); settings.adjust(); update(); }
    void setPlotSettings(const ParamPlotSettings& sts) { settings = sts; settings.adjust(); update(); }


/// Изменение масштаба при движении колесика
void GraphicDisplay::wheelEvent(QWheelEvent* events)
{
    int numDegrees = events -> delta() / 8;
    double numTicks = numDegrees / 15.0;

    zoom(numTicks);
    update();
}

/// Нажатие на кнопки клавиатуры
void GraphicDisplay::keyPressEvent(QKeyEvent* events)
{
    switch(events -> key())
    {
    case Qt::Key_Plus:
        zoom(1.0);
    break;
    case Qt::Key_Minus:
        zoom(-1.0);
    break;
    case Qt::Key_Left:
        settings.scroll(-1, 0);
        update();
    break;
    case Qt::Key_Right:
        settings.scroll(1, 0);
        update();
    break;
    case Qt::Key_Up:
        settings.scroll(0, 1);
        update();
    break;
    case Qt::Key_Down:
        settings.scroll(0, -1);
        update();
    break;
    default:
        QWidget::keyPressEvent(events);
    }
}

/// Отрисовка сетки
void GraphicDisplay::drawGrid(QPainter* painter)
{
    QRect rect(paramsDisplay -> rect());
    if(!rect.isValid()) return;
    
    QRect boundString;
    int _max = max(settings.numXTicks, settings.numYTicks);
    for(int i=0, j=0, k=0; i<=_max; ++i, ++j, ++k)
    {
        if(j <= settings.numXTicks)                ///< отрисовка по оси X
        {
            int x = rect.left() + (j * (rect.width() - 1) / settings.numXTicks);
            double label = settings.minX + (j * settings.spanX() / settings.numXTicks);
            QString s_label = round(label);

            painter -> setPen(Qt::black);
            painter -> drawLine(x, rect.top(), x, rect.bottom());
            if(j != settings.numXTicks)
            {
                int flags = Qt::AlignHCenter | Qt::AlignTop;
                boundString = painter -> boundingRect(boundString, flags, s_label);
                painter -> drawText(x - (boundString.width() + 5), rect.bottom() - (boundString.height() + 5),
                                    boundString.width(), boundString.height(), flags, s_label);
            }
        }
        if(k <= settings.numYTicks)                ///< отрисовка по оси Y
        {
            int y = rect.bottom() - (k * (rect.height() - 1) / settings.numYTicks);
            double label = settings.minY + (k * settings.spanY() / settings.numYTicks);
            QString s_label = round(label);

            painter -> setPen(Qt::black);
            painter -> drawLine(rect.left(), y, rect.right(), y);
            if(k != settings.numYTicks)
            {
                int flags = Qt::AlignRight | Qt::AlignTop;
                boundString = painter -> boundingRect(boundString, flags, s_label);
                painter -> drawText(rect.left() + 5, y - boundString.height(),
                            boundString.width(), boundString.height(), flags, s_label);
            }
        }
    }
    painter -> drawRect(rect.adjusted(0, 0, -1, -1));
}

/// Отрисовка легенды
void GraphicDisplay::drawLegend(QPainter* painter, QRect& rect, int& k, int id)
{
    QString pname = fact_prm[id].param_name;
    QString dimension = fact_prm[id].dimension;
    myPen.setWidth(1);
    painter -> drawLine(QLineF(QPointF(rect.right()  - 45, rect.top() + 25 * k),
                               QPointF(rect.right()  - 65, rect.top() + 25 * k)));
    painter -> setPen(Qt::black);
    int flags = Qt::AlignCenter;
    QRect boundString = painter -> boundingRect(boundString, flags, pname);
    painter -> drawText(QPointF(rect.right() - (boundString.width() + 7), rect.top() + 25 * k), pname);
    boundString = painter -> boundingRect(boundString, flags, dimension);
    painter -> drawText(QPointF(rect.right() - (boundString.width() + 7),
                        rect.bottom() - 2 * boundString.height()), dimension);
    ++k;
}

/// Инициализация координат
QPointF GraphicDisplay::initXY(double& sx, double& sy)
{
    QRect rect(paramsDisplay -> rect());
    double dx, dy;
    dx = sx - settings.minX;
    dy = sy - settings.minY;
    double x = rect.left() + (dx * (rect.width() - 1) / settings.spanX());;
    double y = rect.bottom() - (dy * (rect.height() - 1) / settings.spanY());

    return QPointF(x, y);
}

/// Отрисовка графика
void GraphicDisplay::drawCurves(QPainter* painter)
{
    QRect rect(paramsDisplay -> rect());
    if(!rect.isValid())    return;

    painter -> setClipRect(rect.adjusted(1, 1, -1, -1));
    QMapIterator<int, QVector<QPointF>> iter(curveMap);
    int k = 1;
    while(iter.hasNext())
    {
        iter.next();

        int id = iter.key();
        TP_PARAM ty = fact_prm[id].type;
        if(settings.win_type != ty) continue;

        const QVector<QPointF> &data = iter.value();
        QPolygonF polyline(data.count());
        for(int j=0; j<data.count(); ++j)
        {
            double x = data[j].x();
            double y = data[j].y();
            polyline[j] = initXY(x, y);
        }
        QString color = fact_prm[id].param_color.name();
        QPen oldPen = painter -> pen();
        myPen.setColor(fact_prm[id].param_color);
        painter -> setPen(myPen);
        painter -> drawPolyline(polyline);
        int width = myPen.width();
        
        drawLegend(painter, rect, k, id);

        painter -> setPen(oldPen);
    }
}


Практически месяц я парился с этим - но в итоге решение проблемы есть! УРА, уряяяяяяяяяя...
Можете поздравить! :))))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 11.7.2008, 11:54
Сообщение #23


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Молодец, осилил наконец. :)

Упрямства тебе не занимать, так держать!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 11.7.2008, 12:04
Сообщение #24


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(ViGOur @ 11.7.2008, 12:54) *
Молодец, осилил наконец. :)

Упрямства тебе не занимать, так держать!

Может упорства? ;) :blush2:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 11.7.2008, 13:06
Сообщение #25


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(AD @ 11.7.2008, 13:04) *
Может упорства?
И его тоже. ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V  < 1 2 3
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


5 чел. читают эту тему (гостей: 5, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 30.11.2024, 0:28