Russian Qt Forum
Ноябрь 25, 2024, 15:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Перенос виджета в пределах окна с помощью мыши  (Прочитано 11546 раз)
PulSar.CE3194694
Гость
« : Январь 27, 2013, 11:33 »

Добрый день.
Как перенести виджет по экрану с зажатой ЛКМ? Смотрел примеры Drag and Drop, лабуда какая-то, ничего не понял как делать.
Записан
Bepec
Гость
« Ответ #1 : Январь 27, 2013, 11:37 »

Отлавливаем нажатие, далее ловим движения мыши. Куда мышь - туда и виджет.
Записан
PulSar.CE3194694
Гость
« Ответ #2 : Январь 27, 2013, 11:53 »

А пример можно?
Код:
void MyWidget::mousePressEvent(QMouseEvent *e)
 {
     if (e->button() == Qt::LeftButton)
     {
         this->move(e->globalPos());
     }
 }
Так не работает.
Записан
iroln
Гость
« Ответ #3 : Январь 27, 2013, 13:08 »

Надо менять позицию виджета в mouseMoveEvent же! Вы же мышь двигаете. В mousePressEvent нужно запоминать координаты, а в mouseMoveEvent использовать смещение, вычитая из запомненных текущие.

Как то так (это просто пример того, как надо делать, сами его допилите, +/- там и т.п.):

Код
void MyWidget::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton)
    {
        this->posPrev = e->globalPos();
    }
}
 
void MyWidget::mouseMoveEvent(QMouseEvent *e)
{
    QPoint dt = QPoint(this->posPrev - e->globalPos());
    this->move(this->pos()-dt);
 
    this->posPrev = e->globalPos();
}

Вот пример на Python, который точно работает. Улыбающийся

Код
Python
class MyWidget(QWidget):
 
   def __init__(self, parent=None):
       super(MyWidget, self).__init__(parent)
       self.prevPos = QPoint(0, 0)
 
   def mousePressEvent(self, event):
       self.prevPos = event.globalPos()
 
   def mouseMoveEvent(self, event):
       dt = self.prevPos - event.globalPos()
       self.move(self.pos()-dt)
       self.prevPos = event.globalPos()
 
« Последнее редактирование: Январь 27, 2013, 15:00 от iroln » Записан
LEO
Гость
« Ответ #4 : Январь 27, 2013, 18:57 »

посмотри примеры в примере, может найдешь что тебе надо
...QtSDK\Examples\4.7\draganddrop
Записан
PulSar.CE3194694
Гость
« Ответ #5 : Январь 27, 2013, 19:36 »

посмотри примеры в примере, может найдешь что тебе надо
...QtSDK\Examples\4.7\draganddrop
Так смотрел уже, лабуда какая-то... Какие-то мимы, пиксмапы и прочее. Не прозрачно как-то.
А вот предыдущая схема прозрачная и работает. Но только один раз. После того, как один раз перетащил виджет, больше его подцепить мышью не могу. И все виджеты, которые на нем, становятся недосягаемыми (мои лейблы не хотят больше редактироваться)
Записан
iroln
Гость
« Ответ #6 : Январь 27, 2013, 21:29 »

Так смотрел уже, лабуда какая-то... Какие-то мимы, пиксмапы и прочее...
Ну так по уму всегда чуть сложнее, зато надёжнее и вернее! Улыбающийся
Чего у вас там не получается? Можете показать минимальный проект, который можно скомпилировать и запустить?
Записан
PulSar.CE3194694
Гость
« Ответ #7 : Январь 28, 2013, 07:27 »

Попытаюсь разобраться.
Нет, все работает, оказывается, что виджет, который пытаюсь перенести не является виджетом верхнего уровня, и когда его перетаскиваю в другую часть экрана, он начинает закрываться другим прозрачным виджетом более высокого уровня.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Январь 28, 2013, 10:44 »

он начинает закрываться другим прозрачным виджетом более высокого уровня.
Нужно поднимать виджет через raise().
Вот работающий пример:
Код
C++ (Qt)
#include <QApplication>
#include <QToolButton>
#include <QScrollArea>
#include <QMouseEvent>
 
class Button : public QToolButton
{
public:
Button( const QString& s, QWidget* parent = 0 )
: QToolButton( parent )
{
setText( s );
setMouseTracking( true );
}
 
protected:
void mouseMoveEvent( QMouseEvent* e )
{
if( drag_pos_ != QPoint() )
{
move( pos() + ( e->globalPos() - drag_pos_ ) );
drag_pos_ = e->globalPos();
}
}
void mousePressEvent( QMouseEvent* e )
{
raise();
drag_pos_ = e->globalPos();
setCursor( QCursor( Qt::SizeAllCursor ) );
}
void mouseReleaseEvent( QMouseEvent* e )
{
drag_pos_ = QPoint();
unsetCursor();
}
private:
QPoint drag_pos_;
};
 
 
int main( int argc, char** argv )
{
QApplication app( argc, argv );
QScrollArea w;
 
Button b1( "Drag me", w.viewport() );
b1.move( 10, 10 );
 
Button b2( "Drag me", w.viewport() );
b1.move( 40, 40 );
 
w.show();
return app.exec();
}
 
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Январь 28, 2013, 10:53 »

Код
C++ (Qt)
move( pos() + ( e->globalPos() - drag_pos_ ) );
drag_pos_ = e->globalPos();
 
А если юзверь увлекся и вынес виджет за пределы parent'а - как потом его достать?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #10 : Январь 28, 2013, 10:56 »

А если юзверь увлекся и вынес виджет за пределы parent'а - как потом его достать?
Тут 2 варианта: либо запрещать двигать за пределы окна, либо организовать прокрутку.
« Последнее редактирование: Январь 28, 2013, 11:05 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #11 : Январь 28, 2013, 22:40 »

Код
C++ (Qt)
move( pos() + ( e->globalPos() - drag_pos_ ) );
drag_pos_ = e->globalPos();
 
А если юзверь увлекся и вынес виджет за пределы parent'а - как потом его достать?
Используй опыт 1С-а. Его редактор диалогов окном самого виджета не ограничивается.
ПС. Очень удобно. Можно "стащить" неиспользуемые контролы без развязывания зависимостей за экран и забыть про них...
Особенно удобно ЭТО при компоновке/перекомпоновке виджетов - стаскиваешь вниз формы, а потом по одному закидываешь на свои места..
« Последнее редактирование: Январь 28, 2013, 22:43 от panAlexey » Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
PulSar.CE3194694
Гость
« Ответ #12 : Январь 29, 2013, 07:24 »

А если по науке делать, то какое решение все же вернее: через Qdrag или MouseEvent'ы?
Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #13 : Январь 29, 2013, 11:12 »

А если по науке делать, то какое решение все же вернее: через Qdrag или MouseEvent'ы?
В данном случае через моус-эвенты наверное. Тебе же таскать в пределах формы прийдется.
Надо видеть размер объекта и как вписываются.
ПС. к верхнему посту: нельза в 1С-ном редакторе перетащить контрол вверх или влево за границу. Вниз и вправо - можно.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
iroln
Гость
« Ответ #14 : Январь 29, 2013, 17:41 »

Используй опыт 1С-а. Его редактор диалогов окном самого виджета не ограничивается.
ПС. Очень удобно. Можно "стащить" неиспользуемые контролы без развязывания зависимостей за экран и забыть про них...
Особенно удобно ЭТО при компоновке/перекомпоновке виджетов - стаскиваешь вниз формы, а потом по одному закидываешь на свои места..
Да что там далеко ходить? Qt Designer же так работает! Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.216 секунд. Запросов: 23.