【问题标题】:why the line disappears after releasing the mouse cursor?为什么释放鼠标光标后线条消失?
【发布时间】:2019-06-26 09:43:36
【问题描述】:

我在包含图像 (QImage img) 的 QLabel 上绘画,但在释放鼠标光标后,绘画消失了。我认为paintevent 在标签上绘制而不是在图像 mPix 上如何绘制图像?这样即使我移除光标,绘图仍然存在

此后,如果有人有帮助我的想法,我想移动这些几何形状并通过光标调整它们的大小。

label.cpp:

void Label::mousePressEvent(QMouseEvent* event) {
    mousePressed = true;
    switch (_paintMode) {  
        case PaintLine: {
            mLine.setP1(event->pos());
            mLine.setP2(event->pos());
        }
        break;
        case PaintCirc: {
            mCirc.setTopLeft(event->pos());
            mCirc.setBottomRight(event->pos());
        }
    }
}

void Label::mouseMoveEvent (QMouseEvent* mouse_event) {
    if (mouse_event->type() == QEvent::MouseMove) {
        switch (_paintMode) { 
            case PaintLine: {
                mLine.setP2(mouse_event->pos());
            }
            break;
            case PaintCirc:{
                mCirc.setBottomRight(mouse_event->pos());
            }
        }
        update();
    }
}

void Label::paintEvent(QPaintEvent* event) {
    QLabel::paintEvent(event);
    QPainter painter(this);
    QPen pen(Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);

    painter.setPen(pen);
    if (mousePressed) {
        switch (_paintMode) {
            case PaintLine: {
                painter.drawLine(mLine);
            }
            break;
            case PaintCirc: {
                painter.drawEllipse(mCirc);
            }
        }
    }
}

void Label::mouseReleaseEvent(QMouseEvent*) {
    mousePressed = false;
}

Mainwindow.cpp:

void MainWindow::on_actionOpen_triggered() {
    mPix=QPixmap::fromImage(img);
    ui->label->setPixmap(mPix);
}

【问题讨论】:

  • 删除paintEvent 中的条件if(mousePressed) 以始终画线。
  • 不,他的意思是把if(mousePressed)paintEvent中去掉,这样即使不按鼠标也能画出几何图形。
  • 你想达到什么目的?你想画几条线吗?
  • 试想一下,当paintEvent被调用时,之前绘制的图像被清除了。现在您应该知道为什么当您释放鼠标时您的线消失了(参见 Romha Korev 的评论)。现在,如果您想绘制多条线,您可以在按下鼠标按钮时在容器中添加一条新线(例如QVector),然后在您的paintEvent 中绘制存储在容器中的每条线。
  • “然后绘制一个新的”不适用于每种类型只有一个成员。将它们添加到列表中。总是在绘制事件中绘制列表中的所有项目。

标签: c++ qt


【解决方案1】:

这里有一个最小的例子来说明我们所说的。

  • paintEvent 中不需要 mousePressed
  • 始终绘制所有内容。
  • 为多个元素使用一个列表

为了简洁起见,它只画了椭圆。

#include <vector>

#include <QtWidgets/QApplication> 
#include <QtWidgets/QWidget> 
#include <QtGui/QPainter> 
#include <QtGui/QMouseEvent> 

class Draw : public QWidget
{
public:
  Draw()
  : mMousePressed( false )
  , mCirc( nullptr ) {
  }

  void mousePressEvent( QMouseEvent* event ) {
    mCircs.emplace_back();
    mCirc = &mCircs.back();
    mCirc->setTopLeft( event->pos() );
    mCirc->setBottomRight( event->pos() );
    mMousePressed = true;
  }

  void mouseMoveEvent( QMouseEvent* event ) {
    if( mMousePressed && mCirc) {
      mCirc->setBottomRight( event->pos() );
    }
    update();
  }

  void mouseReleaseEvent( QMouseEvent* event ) {
    mMousePressed = false;
    mCirc = nullptr;
  }


  void paintEvent( QPaintEvent* event ) {
    QWidget::paintEvent( event );
    QPainter painter( this );
    QPen pen( Qt::red, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );

    painter.setPen( pen );
    for( auto const& circ : mCircs ) {
      painter.drawEllipse( circ );
    }
  }

private:
  std::vector<QRectF> mCircs;
  QRectF* mCirc;
  bool mMousePressed;
};

int main( int argc, char** argv) {
  QApplication app(argc, argv);

  Draw draw;
  draw.show();

  app.exec();
}

【讨论】:

  • 我在一个新项目中测试了代码,它可以工作,但是当我将它集成到我的旧代码中时,我点击了绘制圆圈的按钮,它显示程序已停止工作。
  • 问题可能是mouseMoveEvent 运行在一个初始化的指针上。我将编辑示例以使其更安全。
  • 没有看到你的代码我无能为力。你必须提出一个新问题。
  • 不要那样做。请撤消您的编辑并提出一个新问题。
  • 我创建了一个修改后的示例,该示例在 LeftButton 上创建一个 Line,在 Right 按钮上创建一个 Ellipse。你可以找到它here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 2016-11-10
  • 1970-01-01
相关资源
最近更新 更多