crossplatform.ru

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


  Ответ в Перемещение QFrame
Введите ваше имя
Подтвердите код

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

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


Последние 10 сообщений [ в обратном порядке ]
AD Дата 27.7.2009, 10:32
 
Цитата(BRE @ 27.7.2009, 11:17) *
Попробуй вычитать для:
* VLine - width() / 2
* HLine - height() / 2

Спасибо. В следующем варианте помогло полностью:
* VLine - width()
* HLine - height()
BRE Дата 27.7.2009, 10:17
 
Цитата(AD @ 27.7.2009, 11:14) *
Это "почти" состоит в том, что я из координаты вычитаю константу. У меня она равна 20. А есть возможность сделать без таких хаков? Заранее благодарен.

Попробуй вычитать для:
* VLine - width() / 2
* HLine - height() / 2
AD Дата 27.7.2009, 10:14
  Сделал вариант, который "почти" правильный! :)

/// Переопределение нажатия на лекую кнопку мыши
void VFFrame::mousePressEvent(QMouseEvent* events)
{
    QFrame::mousePressEvent(events);

    switch(events -> button())
    {
    case Qt::LeftButton:                ///< если нажата левая кнопка мыши
        _is_left_pressed = true;
    break;
    }

    if(!_is_left_pressed) return;

    QPoint gpos(events -> globalPos());
    QPoint pos((_graph) ? _graph -> mapFromGlobal(gpos) : ((_mgraph) ? _mgraph -> mapFromGlobal(gpos) : gpos));
    if(_vf_shape == QFrame::VLine)
        pos.setX(pos.x() - _DELTA_COORD),
        setGeometry(pos.x(), y(), width(), height());
    else if(_vf_shape == QFrame::HLine)
        pos.setY(pos.y() - _DELTA_COORD),
        setGeometry(x(), pos.y(), width(), height());
}

/// Передвижение визира вслед за мышью
void VFFrame::mouseMoveEvent(QMouseEvent* events)
{
    QFrame::mouseMoveEvent(events);
    if(!_is_left_pressed) return;

    QPoint gpos(events -> globalPos());
    QPoint pos((_graph) ? _graph -> mapFromGlobal(gpos) : ((_mgraph) ? _mgraph -> mapFromGlobal(gpos) : gpos));
    if(_vf_shape == QFrame::VLine)
        pos.setX(pos.x() - _DELTA_COORD),
        setGeometry(pos.x(), y(), width(), height());
    else if(_vf_shape == QFrame::HLine)
        pos.setY(pos.y() - _DELTA_COORD),
        setGeometry(x(), pos.y(), width(), height());
}

/// Отпускание кнопки мыши
void VFFrame::mouseReleaseEvent(QMouseEvent* events)
{
    QFrame::mouseReleaseEvent(events);
    if(!_is_left_pressed) return;

    _is_left_pressed = false;
    QPoint gpos(events -> globalPos());
    QPoint pos((_graph) ? _graph -> mapFromGlobal(gpos) : ((_mgraph) ? _mgraph -> mapFromGlobal(gpos) : gpos));
    if(_vf_shape == QFrame::VLine)
        pos.setX(pos.x() - _DELTA_COORD),
        setGeometry(pos.x(), y(), width(), height());
    else if(_vf_shape == QFrame::HLine)
        pos.setY(pos.y() - _DELTA_COORD),
        setGeometry(x(), pos.y(), width(), height());
    _is_viewfinder = false;
}


Это "почти" состоит в том, что я из координаты вычитаю константу. У меня она равна 20. А есть возможность сделать без таких хаков? Заранее благодарен.
AD Дата 24.7.2009, 17:59
 
Цитата(ufna @ 24.7.2009, 18:56) *
а если добавить к X просто некоторую константу?

Надо еще в функцию и нажатия внести. Этого еще не сделал. Сейчас все отрихтую, может быть, вообще больше ничего не понадобится.
ufna Дата 24.7.2009, 17:56
  а если добавить к X просто некоторую константу?
AD Дата 24.7.2009, 17:49
  Подсказанное решение практически полностью подходит. Ни слоты не нужны, ничего.
/// Передвижение визира вслед за мышью
void VFFrame::mouseMoveEvent(QMouseEvent* events)
{
    QFrame::mouseMoveEvent(events);

    QPoint gpos(events -> globalPos());
    QPoint pos(_graph -> mapFromGlobal(gpos));

    if(!_is_left_pressed) return;
    if(_vf_shape == QFrame::VLine)
        setGeometry(/*_move_point.x()*/pos.x(), y(), width(), height());
    else if(_vf_shape == QFrame::HLine)
        setGeometry(x(), /*_move_point.y()*/pos.y(), width(), height());
}


Единственное, все-таки курсор идет слегка левее визира. Но основная проблема, по сути, решена. Есть ли возможность попасть ровно под курсор?
ufna Дата 24.7.2009, 16:34
  не, просто хочется глянуть в динамике что происходит. В какой момент и что. Я словами плохо объясню что хочу увидеть )



кстати, на прог орге совет дали сводящийся вот к чему - в визире ты узнаешь глобальные координаты, затем - переводишь их в систему координат график дисплея. Хотя мне кажется тут ненмого в другом дело.

я бы советовал перевести управление движением с визира на дисплей, воспользовавшись переменной-стейтом нажат/не нажат в визире.

я сии визиры делаю вообще не отдельными виджетами, а объектами дисплея через QRect и ручную отрисовку. Там тогда все становится очень простым, точным и удобным.



P.S. - я оба форума не особо разделяю, тему видел в обоих, ответил просто в том, в который зашел когда было время посмотреть подробнее :)
AD Дата 24.7.2009, 16:19
  вот рисунок визира:
[attachment=719:uti.JPG]
AD Дата 24.7.2009, 9:01
  Буду рад за любой совет. Уже полторы недели с этим мучаюсь!
AD Дата 23.7.2009, 17:37
  Попробовал решить указанную выше проблему слотов-сигналов. Не очень удалось. Не могу понять, как мне выйти на нужную координату:
viewfinder
/// Класс для переопределения виджета каждого визира
class VFFrame: public QFrame
{
    Q_OBJECT

private:
    QPoint _move_point;            ///< точка целеуказания, куда необходимо двигать

signals:
    void moveVF();

public:
    void setMovePoint(const QPoint& pnt) { _move_point = pnt; }
};

/// Передвижение визира вслед за мышью
void VFFrame::mouseMoveEvent(QMouseEvent* events)
{
    QFrame::mouseMoveEvent(events);

    emit moveVF();

    if(!_is_left_pressed) return;
    if(_vf_shape == QFrame::VLine)
        setGeometry(_move_point.x(), y(), width(), height());
    else if(_vf_shape == QFrame::HLine)
        setGeometry(x(), _move_point.y(), width(), height());
}

/// Отпускание кнопки мыши
void VFFrame::mouseReleaseEvent(QMouseEvent* events)
{
    QFrame::mouseReleaseEvent(events);

    emit moveVF();

    if(!_is_left_pressed) return;
    _is_left_pressed = false;
    if(_vf_shape == QFrame::VLine)
        setGeometry(_move_point.x(), y(), width(), height());
    else if(_vf_shape == QFrame::HLine)
        setGeometry(x(), _move_point.y(), width(), height());
    _is_viewfinder = false;
}

/// Изменение размеров окна
void VFFrame::resizeEvent(QResizeEvent* events)
{
    if(_vf_shape == QFrame::VLine)
        setGeometry(x(), 0, 16, parentWidget() -> height());
    else if(_vf_shape == QFrame::HLine)
        setGeometry(0, y(), parentWidget() -> width(), 16);
}

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

private:
        QList<VFFrame*> viewfinderList;    ///< список всех визиров
    QPoint _move_pointVF;        ///< точка, куда следует перемещаться визир
        void connectViewfinder();
    void disconnectViewfinder();

private slots:
    void setMovePoint();
};

/// Проверка на попадание фокуса на визир
bool GraphicDisplay::isViewfinder(const QPoint& pos)
{
    foreach(VFFrame* pf, viewfinderList)
        if(pf -> isViewfinder())
        {
            _move_pointVF = pos;
            return true;
        }
    return false;
}

/// Подсоединение сигнала
void GraphicDisplay::connectViewfinder()
{
    foreach(VFFrame* pf, viewfinderList)
        if(pf -> isViewfinder())
        {
            connect(pf, SIGNAL(moveVF()), this, SLOT(setMovePoint()));
            break;
        }
}

/// Разъединение сигнала
void GraphicDisplay::disconnectViewfinder()
{
    foreach(VFFrame* pf, viewfinderList)
        if(pf -> isViewfinder())
        {
            disconnect(pf, SIGNAL(moveVF()), this, SLOT(setMovePoint()));
            break;
        }
}

/// Нажатие на кнопку - рисование "резиновой ленты"
void GraphicDisplay::mousePressEvent(QMouseEvent* events)
{
    QWidget::mousePressEvent(events);

    if(isViewfinder(events -> pos())) { connectViewfinder(); return; }
// ....................................
}

/// Переопределение функции передвижения мыши
void GraphicDisplay::mouseMoveEvent(QMouseEvent* events)
{
    if(isViewfinder(events -> pos())) return;

        // .............................................
}

/// Возвращение прежнего вида курсору и изменение масштаба
void GraphicDisplay::mouseReleaseEvent(QMouseEvent* events)
{
    if(isViewfinder(events -> pos()))
    { disconnectViewfinder(); return; }

// ....................................................................
}


Смысл в том, что во время движения в координату _move_point записывается предыдущее значение, т.к. движение мыша функций GraphicDisplay попадает позже, чем в движение мыша функций VFFrame. Как все-таки добиться эффекта, чтобы в функцию setMovePoint класса VFFrame передавалось значение events -> pos() класса GraphicDisplay?
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 12.7.2025, 21:48