我从QWidget
创建了自己的课程,重新定义了paintEvent()
,mousePressEvent()
,mouseReleaseEvent()
和mouseMoveEvent()
。所有用于移动小部件的方法都超过其他小部件(黄色)。
当我在布局中创建我的小部件时,它看起来像这样:
但是,当我将黑色小部件移动到底部并将红色移动到顶部时,这样:
并调整窗口大小,所有小部件都刷新到对齐位置:
但我想,当我将一个小部件移动到另一个小部件时,小部件应该在新的位置对齐布局,如下所示:
我应该重新定义哪个功能呢?
P.S。
There is一段代码,可以在布局中移动小部件位置(更改其索引),但我不知道如何找出他们的(x,y)位置来计算布局中的新索引。我想,我可以在resizeEvent()
中完成。
但是当事件发出时,位置已经变为旧的。 (比如在移动1张照片之前),我需要移动后的位置(比如在secon图片上)。如何在对齐之前获取小部件的位置?
或者如何通过拖放鼠标来改变布局中窗口小部件的顺序?
答案 0 :(得分:0)
我编写自己的小部件,然后重新定义以下方法:mouseReleaseEvent(), paintEvent(), mousePressEvent(), mouseMoveEvent()
。在mousePressEvent()
中,我在图中保持旧的X和Y位置以及鼠标位置。然后在mouseMoveEvent()
中,我计算是否最小化鼠标移动距离并将窗口小部件移动到新位置(它不会在布局中移动窗口小部件索引)。在它之后,如果发出mouseReleaseEvent()
,我只计算移动小部件的新索引并更改和更新父布局。如果窗口小部件的移动小于高度,则布局只会更新而不更改窗口小部件索引。
void SimpleWidget::mouseMoveEvent(QMouseEvent *event)
{
if (!(event->buttons() & Qt::LeftButton))
return;
if (!IsMinimumDistanceRiched(event))
{
return;
}
int y = event->globalY() - mouseClickY + oldY;
int BottomBorder = parentWidget->geometry().height() - this->geometry().height();
if(y < 0) y = 0;
else if(y > BottomBorder) y = BottomBorder;
move(oldX, y);
}
void SimpleWidget::mousePressEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton)
dragStartPosition = event->pos();
oldX = this->geometry().x();
oldY = this->geometry().y();
mouseClickX = event->globalX();
mouseClickY = event->globalY();
}
bool SimpleWidget::IsMinimumDistanceRiched(QMouseEvent *event)
{
return (event->pos() - dragStartPosition).manhattanLength() >= QApplication::startDragDistance();
}
bool SimpleWidget::moveInLayout(QWidget *widget, MoveDirection direction)
{
QVBoxLayout* myLayout = qobject_cast<QVBoxLayout*>(widget->parentWidget()->layout());
const int index = myLayout->indexOf(widget);
if (direction == MoveUp && index == 0)
{
return false;
}
if (direction == MoveDown && index == myLayout->count()-1 )
{
return false;
}
const int newIndex = direction == MoveUp ? index - 1 : index + 1;
myLayout->removeWidget(widget);
myLayout->insertWidget(newIndex , widget);
return true;
}
void SimpleWidget::paintEvent(QPaintEvent *)
{
QStyleOption o;
o.initFrom(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
}
void SimpleWidget::mouseReleaseEvent(QMouseEvent *)
{
int y = geometry().y();
MoveDirection direct;
int offset;
if(oldY > y)
{
offset = oldY - y;
direct = MoveUp;
}
else if(oldY < y)
{
offset = y - oldY;
direct = MoveDown;
}
int count = offset/height();
for(int i = 0; i < count; i++)
{
moveInLayout(this, direct);
}
update();
QVBoxLayout* myLayout = qobject_cast<QVBoxLayout*>(this->parentWidget->layout());
myLayout->update();
this->saveGeometry();
}