c++ - 如何在 QPixmap 图像中绘制一个点?

标签 c++ image qt user-interface qtgui

我有一个项目,我想在 QPixmap 内的图像中绘制一个点。该点将通过鼠标单击 QLabel 来绘制。我创建了一个 eventFilter() 对应于鼠标点击。当我用鼠标单击时,会调用这些 eventFilter 并在图像中绘制一个点,但我的代码不起作用。我尝试了许多其他选项,例如子类化 QLabel,但也没有用。

有时我的编译器会显示这些错误消息:

QPainter::begin: Paint device returned engine == 0, type: 2
QPainter::setPen: Painter not active
QPainter::drawPoints: Painter not active
QPainter::end: Painter not active, aborted

但我不明白,因为 Qt 文档说允许在 paintEvent 之外使用 QPainter,只需与 QPixmap 一起使用。

下面是我的代码以及启动 QPainter 的方法。

bool mainwindow::eventFilter(QObject* watched, QEvent* event) {
if ( watched != ui->labelScreen )
    return false;
if ( event->type() != QEvent::MouseButtonPress )
    return false;
const QMouseEvent* const me = static_cast<const QMouseEvent*>( event );
//might want to check the buttons here
const QPoint p = me->pos(); //...or ->globalPos();

ui->label_Xget->setNum(this->xReal);
ui->label_Yget->setNum(this->yReal);

///////////////////////////////////

QPixmap pix;
pix.fromImage(QImage::fromData("C:/Users/Syn/Pictures/imagem137.jpg"));

QPainter *painter = new QPainter(&pix);

painter->setPen(Qt::red);
painter->drawPoint(p.x(), p.y());
ui->labelScreen->setPixmap(pix);
painter->end();

///////////////////////////////////


return false;
}

有人可以帮我解决这个问题吗?谢谢。

最佳答案

错误消息不是来自您的编译器,它们发生在运行时,您无法确定上面引用的代码是否是它们的原因。

有几个问题:

  1. QPixmap::fromImage 是一个返回像素图的静态方法。您忽略了它的返回值。正确的使用方法是:

    // C++11
    auto pix = QPixmap::fromImage(QImage{"filename"});
    // C++98
    QPixmap pix(QPixmap::fromImage(QImage("filename")));
    
  2. 您可以将文件名直接传递给QPixmap 构造函数:

    // C++11
    QPixmap pix{"filename"};
    // C++98
    QPixmap pix("filename");
    
  3. 您正在泄漏 painter 实例。你应该避免任何动态内存分配,除非你真的需要它。此外,按值存储 ui - 这样更便宜。

  4. 在事件处理程序中执行任何阻塞 I/O(例如读取文件)是一个非常糟糕的主意。将像素图预加载并存储为 MainWindow 类的成员。

因此(在 C++11 中):

界面

template <class F>
class MainWindow : public QMainWindow {
  QPixmap m_clickPixmap;
  Ui::MainWindow ui;
  bool eventFilter(QObject*, QEvent*) override;
public:
  MainWindow(QWidget * parent = nullptr);
};

实现

void loadImage(const QString & fileName, QObject * context, F && functor) {
  QtConcurrent::run([=]{
    QImage img{fileName};
    if (img.isNull()) return;
    QTimer::singleShot(0, context, functor, img);
  });
}

MainWindow::MainWindow(QWidget * parent) :
  QMainWindow{parent}
{
  loadImage("C:/Users/Syn/Pictures/imagem137.jpg", this, [this](const QImage & img){
    m_clickPixmap = QPixmap::fromImage(img);
  });
  ui.setupUi(this);
}

bool MainWindow::eventFilter(QObject* watched, QEvent* event) {
  if ( watched != ui.labelScreen )
    return false;
  if ( event->type() != QEvent::MouseButtonPress )
    return false;
  auto const me = static_cast<const QMouseEvent*>(event);
  auto const p = me->pos(); //...or ->globalPos();       
  ui.label_Xget->setNum(this->xReal);
  ui.label_Yget->setNum(this->yReal);

  auto pix{m_clickPixmap};
  QPainter painter(&pix);
  painter.setPen(Qt::red);
  painter.drawPoint(p.x(), p.y());
  painter.end(); // probably not needed
  ui.labelScreen->setPixmap(pix);
  return false;
}

关于c++ - 如何在 QPixmap 图像中绘制一个点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38905317/

相关文章:

c++ - 未能包含 C++ REST 卡萨布兰卡

c++ - 为什么 `e.what()` 打印 "bad allocation"?

c++ - 使用配置文件时,Boost Log 不显示严重性或按严重性过滤

CSS响应式图像技术之谜

html - 如何使用 css 从中心而不是顶部/底部/侧面对齐任意大小的图像

c++ - 寻找类似Windows Paint的Qt开源项目

c++ - openPersistentEditor 中的 QSortFilterProxyModel

c++ - 我如何在单独的头文件中的结构中定义一个 char* 数组?

image - 如何使用 wget 从网站下载所有图像?

c++ - 无法使用我的 QAbstractItemModel 派生类让 QColumnView 显示多行数据