PDA

View Full Version : How to make my application screen-border stick



Fenix Voltres
27th February 2010, 13:41
I want my application to stick to the borders of screen when I move it - I mean when it's not further than 5px from the edge it should stick to it. (i. e. Winamp has it). How to achieve this? I can't do it in moveEvent, because of possible infinite recursion (it doesn't work, anyway :P) , overloading 'move' method doesn't work either.

wysota
27th February 2010, 13:45
You can do it in moveEvent() :) Recursion won't be infinite if you provide a stop condition.

Fenix Voltres
27th February 2010, 13:54
OK, but it works not exactly as I want - when moving my app it doesn't stick (I mean "real-time" stick), and it changes it's position when Im dropping it - I would like my app to "real time" stick, if you know what I mean. :) Do I have to reimplement paintEvent(), or what?
Thanks for quick answer. :)

aamer4yu
27th February 2010, 19:08
OK, but it works not exactly as I want - when moving my app it doesn't stick (I mean "real-time" stick), and it changes it's position when Im dropping it
If you keep your app real time sticky to the corner, how would the user feel he has moved the window a certain distance ?
I guess the above working is fair enough.

been_1990
28th February 2010, 02:20
If your window is a frameless windows(via Qt::FramelessWindowHint) you can easily manage that in "real-time".
Following the "Analog-Clock" example, you can move the window by sub-classing both mousePressEvent() and mouseMoveEvent().
Here is a sample app that does just that:

Widget.cpp:


Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowFlags(Qt::FramelessWindowHint);
filter = new EventFilter(this);
ui->widget->installEventFilter(filter);
move(300,0);
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(filter->canMove)
{
if (event->buttons() & Qt::LeftButton)
{
if(event->globalY() < 100){
qDebug() << "click move" << event->globalY();
move(event->globalPos() - dragPosition);
}else{
move(event->globalX() - dragPosition.x(),100);
}
event->accept();
}
}

}
void Widget::mousePressEvent(QMouseEvent *event)
{
qDebug() << "click away" << filter->canMove;
if (event->button() == Qt::LeftButton) {
dragPosition = event->globalPos() - frameGeometry().topLeft();
event->accept();
}
}


Widget.h:

#include "eventFilter.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();

protected:
void changeEvent(QEvent *e);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);

private:
Ui::Widget *ui;
QPoint dragPosition;
EventFilter *filter;
};

eventFilter.h:

class EventFilter : public QWidget
{
Q_OBJECT

public:
EventFilter(QWidget *parent){
//
canMove = false;
}
bool canMove;

private:
QPoint dragPosition;

protected:
bool eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress ){
canMove = true;
}
else if(event->type() ==QEvent::MouseMove){
canMove = true;
}else{
canMove = false;
}
return QObject::eventFilter(obj, event);
}
};

Keep in mind that if the user somehow moves your window(Windows can do that sometimes when it crashes or goes slow), you won't be able to move it back to the border until you restart your app. But if you check on moveEvent(), you can send it back if that ever happens...
Hope you find it useful. :cool:

wysota
28th February 2010, 14:35
OK, but it works not exactly as I want - when moving my app it doesn't stick (I mean "real-time" stick), and it changes it's position when Im dropping it - I would like my app to "real time" stick, if you know what I mean. :)

Your system delivers move events only when the move is complete. It's either that or reconfigure/reimplement your system to deliver move events on the fly (it's often called "opaque moving" but whether it will work here depends on how it is implemented) or do your own moving (which will probably slow down your application). WinAmp probably does the latter.