我在强制重绘/更新我的 Qt 小部件时遇到了麻烦(它扩展了QGraphicsView
类)。我想要的是绘制一个矩形选择框,当用户按下并移动鼠标时,它将突出显示目标选择区域。
基本工作流程:
- MousePressEvent 设置
making_selection_box
标志,并存储起点(工作)。 - MouseMoveEvent 检查显示是否需要更新。如果是这样,它会尝试这样做(不工作)。
- MouseReleaseEvent 句柄获取结果选择框并相应地处理它。
making_selection_box
被重置。应更新屏幕以删除选择框工件(不工作)。
被覆盖的 mouseMoveEvent:
void QSchematic::mouseMoveEvent(QMouseEvent *event)
{
if(making_selection_box)
{
// get selection box
qDebug() << "updating selection box";
curr_selection_end = event->pos();
repaint(box(drag_select_start, curr_selection_end));
}
// propogate event
QGraphicsView::mouseMoveEvent(event);
}
我重写的paintEvent:
void QSchematic::paintEvent(QPaintEvent *event)
{
qDebug() << "paintEvent";
if(making_selection_box)
{
qDebug() << "drawing selection box";
QPainter painter(viewport());
painter.setPen(Qt::black);
painter.drawRect(box(drag_select_start, curr_selection_end));
painter.end();
}
// propogate event
QGraphicsView::paintEvent(event);
}
Box 只是我编写的一个小辅助函数,用于为不同的选择框起点/终点创建正确的 QRect。
static QRect box(const QPoint& p1, const QPoint &p2)
{
int min_x = p1.x();
int min_y = p1.y();
int max_x = p2.x();
int max_y = p2.y();
if(max_x < min_x)
{
max_x = min_x;
min_x = p2.x();
}
if(max_y < min_x)
{
max_y = min_y;
min_y = p2.y();
}
return QRect(min_x, min_y, max_x - min_x, max_y - min_y);
}
我已经验证当用户按下按钮并移动鼠标时,mouseMoveEvent 被正确触发。
我还验证了当我执行各种标准操作(例如调整窗口大小、最小化/最大化它等)时系统正在调用paintEvent。
我已经验证了我用来绘制小部件的方法可以与其他 paintEvent 触发器一起正常工作,我只是无法在我的代码中触发重绘。
我也尝试过使用update()
方法而不是强制更新repaint()
,但没有运气。
作为旁注,我是否要以错误/困难的方式创建此选择框功能?有没有更好的方法来获得选择框而无需手动实现鼠标侦听器和绘制代码?
我正在使用 Visual Studio 2010 MSVC 编译器在 Windows 7 x64 上使用 Qt 4.8.4 进行测试。