如何在Qt5的QImage顶部绘制点

如何在Qt5的QImage顶部绘制点,qt,qt5,Qt,Qt5,我对Qt是相当陌生的,我完全被困在这一点上。我唯一的选择就是求助于专家。我设计了一个GUI,可以将图像加载到QMainWindow上的Qlabel中。然后我想在图像本身上画多个点。然而,似乎正在发生的事情是,点被画在图像的后面,我不知道如何在图像的顶部画点 我的代码: main.cpp int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return

我对Qt是相当陌生的,我完全被困在这一点上。我唯一的选择就是求助于专家。我设计了一个GUI,可以将图像加载到QMainWindow上的Qlabel中。然后我想在图像本身上画多个点。然而,似乎正在发生的事情是,点被画在图像的后面,我不知道如何在图像的顶部画点

我的代码:

main.cpp

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
   w.show();

   return a.exec();
} 
主窗口

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>

//Declaring the external Variables
extern QString name;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:

void on_actionOpen_triggered();
void on_actionDraw_2_triggered();
void on_actionCreate_2_triggered();
void mousePressEvent(QMouseEvent* event);
void paintEvent(QPaintEvent* e);

private:
Ui::MainWindow *ui;


};

#endif // MAINWINDOW_H
\ifndef主窗口
#定义主窗口
#包括
#包括
//声明外部变量
外部QString名称;
名称空间用户界面{
类主窗口;
}
类主窗口:公共QMainWindow
{
Q_对象
公众:
显式主窗口(QWidget*parent=0);
~main窗口();
专用插槽:
操作打开时无效已触发();
在动作绘制时无效已触发();
在_action上无效创建_2_触发();
作废鼠标压力事件(QMouseEvent*事件);
无效油漆事件(QPaintEvent*e);
私人:
Ui::MainWindow*Ui;
};
#endif//main窗口
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "createdialog.h"
#include <QMouseEvent>
#include <qpainter.h>
#include <QFileDialog>
#include <QLabel>
#include <Qimage>
#include <QPaintDevice>
#include <QDebug>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/config.hpp>
#include "iostream"

using namespace std;

QString fileName;
QString name;
int drawFlag=0;
int paintFlag=0;
int xCord = 0;      //mouse click x location
int yCord = 0;      //mouse click y loaction

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
 ui->setupUi(this);
}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::on_actionOpen_triggered()
{
//Opening a dialog box to search for the images
QFileDialog dialog(this);
dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg)"));
dialog.setViewMode(QFileDialog::Detail);
fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                   "C:/", tr("Images (*.png *.xpm *.jpg)"));

//Pulling just the file name out of the file path
    std::string filename = fileName.toStdString();
    boost::filesystem::path p(filename);
    name = QString::fromStdString(p.stem().string());

//Checking to see if the file name is empty
if (!fileName.isEmpty()) {
    QImage img(fileName);
    int width = img.width();
    int height = img.height();
    MainWindow::showMaximized();
    ui->label->setGeometry(0,0,width,height);       //Setting the label to the size of the image
    ui->label->setPixmap(QPixmap::fromImage(img));  //Inserting the image into the label

}
    else{
       ui->label->setText("Error");
}

}

void MainWindow::mousePressEvent(QMouseEvent* event)
 {
  //If the draw flag is set record mouse press events
  if(drawFlag==1){
    if(event->button() == Qt::LeftButton){
        xCord = event->x();
        yCord = event->y();
        std::cout << "x-location: " << xCord << endl;
        std::cout << "y-location: " << yCord << endl;
        paintFlag=1;
        update();

    }
  }
}
void MainWindow::paintEvent(QPaintEvent* e)
{
  QMainWindow::paintEvent(e);
  //When the paint flag is set then paint
  if(paintFlag==1){
    QPainter painter(this);
    QPen paintpen(Qt::red);
    paintpen.setWidth(10);
    QPoint p1;
    p1.setX(xCord);
    p1.setY(yCord);
    painter.setPen(paintpen);
    painter.drawPoint(p1);
  }
}

void MainWindow::on_actionDraw_2_triggered()
{
drawFlag=1;

}
#包括“mainwindow.h”
#包括“ui_main window.h”
#包括“createdialog.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“iostream”
使用名称空间std;
QString文件名;
QString名称;
int-drawFlag=0;
int paintFlag=0;
int xCord=0//鼠标单击x位置
int-yCord=0//鼠标点击y形摆动
主窗口::主窗口(QWidget*父窗口):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
}
MainWindow::~MainWindow()
{
删除用户界面;
}
void main window::on_action打开_触发()
{
//打开对话框以搜索图像
QFileDialog对话框(此对话框);
setNameFilter(tr(“图像(*.png*.xpm*.jpg)”);
setViewMode(QFileDialog::Detail);
fileName=QFileDialog::getOpenFileName(这个,tr(“打开文件”),
“C:/”,tr(“图像(*.png*.xpm*.jpg)”);
//仅从文件路径中提取文件名
std::string filename=filename.toStdString();
boost::filesystem::path p(文件名);
name=QString::fromStdString(p.stem().string());
//正在检查文件名是否为空
如果(!fileName.isEmpty()){
QImage img(文件名);
int width=img.width();
内部高度=内部高度();
主窗口::显示最大化();
ui->label->setGeometry(0,0,宽度,高度);//将标签设置为图像的大小
ui->label->setPixmap(QPixmap::fromImage(img));//将图像插入标签
}
否则{
用户界面->标签->设置文本(“错误”);
}
}
void主窗口::MousePresseEvent(QMouseEvent*事件)
{
//如果设置了draw标志,则记录鼠标按下事件
如果(drawFlag==1){
如果(事件->按钮()==Qt::LeftButton){
xCord=event->x();
yCord=event->y();

std::cout在绘制子窗口小部件之前绘制主窗口。绘制主窗口实际上只是绘制灰色背景

这意味着您的
MainWindow::paintEvent()
调用基类实现(
QMainWindow::paintEvent()
)来绘制灰色背景,然后在灰色背景之上绘制一个点`返回,Qt在其上绘制所有子窗口小部件,包括标签,从而在灰色背景和点上绘制

可能的解决办法:

  • 调用
    QLabel::setPixmap()
    之前,在QImage上绘制点-
    QPainter
    也可以在
    QImage上绘制点,而不仅仅是在
    QWidget


  • 子类
    QLabel
    (将其命名为LabelWithPointOnTop)并重写子类中的
    paintEvent()
    ,然后将子类的实例而不是
    QLabel
    放入布局中

  • 感谢您的回复,但我对实现仍然有点困惑。我不确定在调用Qlabel::setPixmap()之前如何在QImage上指出要点能否也给出一个潜在解决方案2的示例。我理解您的示例代码1,但在实现它时,它仍然不起作用。谢谢!这是一个关于如何子类化QLabel的示例(请参见第一个答案):然而,您还需要将QLabel子类集成到您的UI文件中,这是一个完全不同的主题。好的。我有点了解子类,但可以将QLabel子类化为QMainWindow。我在QMainWindow中执行所有这些操作,因为我在UI顶部有不同的选项卡选项,其中一个是draw,以便可以在主窗口上的图像上绘制。该示例应该有效。在绘制点之前,您为画家设置了笔宽和颜色,对吗?
    QImage image("path/to/image/img.png");
    QPainter painter(&image);
    QPen pen;
    pen.setWidth(20);
    pen.setColor(Qt::red);
    painter.setPen(pen);
    painter.drawPoint(5,5);
    painter.end();
    label->setPixmap(QPixmap::fromImage(image));