精华内容
下载资源
问答
  • 因为事件过滤器的影响 无法直接使用QPainter控件上实现画图操作,需使用eventFilter函数进行修改
  • Qt使用QPainter在控件上绘图

    千次阅读 2020-06-15 17:54:53
    Qt使用QPainter在控件上绘图 因为Qt存在事件过滤机制,事件过滤器会将子控件上的绘图事件过滤,因此无法控件上使用QPainter进行绘图 如果需要控件上使用QPainter,同样需要事件过滤器 事件过滤器 事件过滤...

    Qt使用QPainter在子控件上绘图

    因为Qt存在事件过滤机制,事件过滤器会将子控件上的绘图事件过滤,因此无法在子控件上使用QPainter进行绘图

    如果需要在子控件上使用QPainter,同样需要事件过滤器

    事件过滤器

    事件过滤器与其他部件不同,它不是一个类,只是由两个函数组成的一种操作
    用来完成一个部件对其他部件的事件监视,这两个函数分别是installEventFilter()和eventFilter(QObject *obj, QEvent *ev),都是QObject类中的函数

    使用步骤:
    • 安装事件过滤器: ui->paint_widget(子控件名,可更换为需要使用的控件)->installEventFilter(this);
    • 实现在过滤器中指定的操作

    事件过滤器的实现(具体代码):

    bool MainWindow::eventFilter(QObject *watched, QEvent *event)
    {
        if(watched == ui->paint_widget && event->type() == QEvent::Paint)
        {
            showPaint(); //响应函数
        }
        return QWidget::eventFilter(watched,event);
    }
    
    //实现响应函数
    void MainWindow::showPaint()
    {
        QPainter painter(ui->paint_widget);
        painter.setPen(Qt::gray);
        painter.setBrush(Qt::green);
        painter.drawRect(10,10,200,200);
    }
    
    展开全文
  • Qt中在控件上绘图

    千次阅读 2020-08-17 21:55:47
    Qt的要当前类对应的窗口上绘图一般需要重写paintEvent函数,但是Qt的事件过滤器默认是把父窗口下子控件的绘图事件给过滤了的,因此重写父窗口的paintEvent函数是无法控件上进行绘图的,下面举一个例子。...

    1.总述

    Qt的要在当前类对应的窗口上绘图一般需要重写paintEvent函数,但是Qt的事件过滤器默认是把父窗口下子控件的绘图事件给过滤了的,因此重写父窗口的paintEvent函数是无法在子控件上进行绘图的,下面举一个例子。

     

    复制代码

     1 void MainWindow::myDraw(QLabel * label)
     2 {
     3     QPainter painter(label);
     4     painter.setPen(Qt::gray);
     5     painter.setBrush(Qt::green);
     6     painter.drawRect(10,10,20,20);
     7 }
     8 
     9 void MainWindow::paintEvent(QPaintEvent *)
    10 {
    11     myDraw(ui->label);
    12     myDraw(ui->label_2);
    13 }

    复制代码

    如上所示,重写MainWindow的paintEvent(QPaintEvent *)函数,然后在里面对子控件绘图是没有用的。

    2.解决方案

    还是以上面的例子为例。

    法一

    自己定义一个Mylabel类继承于QLabel,然后在这个类中重写paintEvent(QPaintEvent *)函数,并在里面绘图。然后在ui界面中把对应的QLabel提升为Mylabel。这种方式不是很灵活,因此不多介绍,详见https://blog.csdn.net/seanwang_25/article/details/18667871。

    法二

    在介绍法二之前,先补充一下qt中的事件机制,qt程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始 Qt 的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件(鼠标事件,键盘事件,绘图事件等)。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件先传给事件过滤器:

    virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );

    在事件过滤器中可以对感兴趣的事件进行处理或屏蔽,令函数返回 true,不感兴趣的事件继续转发,令函数返回 false或者交给父类处理

    通过事件过滤器的事件将交给事件分发器:

    virtual  bool QObject::event(QEvent *e)

    event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler),比如paintEvent(QPaintEvent *ev),mouseMoveEvent(QMouseEvent *ev).....

    法二的实现思想:

    使用事件过滤器,在子控件的绘图事件被过滤前对子控件的绘图事件进行处理。下面的示例代码实现了点击界面上的画图按钮进行画图,点击清除按钮不进行画图。

    复制代码

     1 //mainwindow.cpp
     2 #include "mainwindow.h"
     3 #include "ui_mainwindow.h"
     4 #include<QPushButton>
     5 #include<QPaintEvent>
     6 #include<QPainter>
     7 #include<QPen>
     8 #include<QColor>
     9 #include<QString>
    10 #include<QDebug>
    11 #include<QFont>
    12 #include<QPixmap>
    13 #include<QVector>
    14 MainWindow::MainWindow(QWidget *parent) :
    15     QMainWindow(parent),
    16     ui(new Ui::MainWindow)
    17 {
    18     ui->setupUi(this);
    19     labels.push_back(ui->label);
    20     labels.push_back(ui->label_2);
    21     ui->label->installEventFilter(this);//在label上安装事件过滤器,this指针指定当事件发生时调用当前类中的事件过滤器进行处理
    22     ui->label_2->installEventFilter(this);//在label_2上安装事件过滤器
    23     connect(ui->pushButton,&QPushButton::clicked,this,[&]()
    24     {
    25         flag =1;
    26         update();//手动产生绘图事件
    27     });
    28     connect(ui->pushButton_2,&QPushButton::clicked,this,[&]()
    29     {
    30         flag =0;
    31         update();//手动产生绘图事件
    32     });
    33 }
    34 
    35 MainWindow::~MainWindow()
    36 {
    37     delete ui;
    38 }
    39 
    40 void MainWindow::myDraw(QLabel * label)
    41 {
    42     QPainter painter(label);
    43     painter.setPen(Qt::gray);
    44     painter.setBrush(Qt::green);
    45     painter.drawRect(10,10,20,20);
    46 }
    47 
    48 //void MainWindow::paintEvent(QPaintEvent *)
    49 //{
    50 //    myDraw(ui->label);
    51 //    myDraw(ui->label_2);
    52 //}
    53 
    54 bool MainWindow::eventFilter(QObject *watched, QEvent *event)
    55 {
    56     if(watched == ui->label && event->type() == QEvent::Paint)//发生绘图事件,且是在label上发生的
    57     {
    58             if(flag == 1)//标志位为1才在label上绘图,否者不绘图
    59             {
    60                 myDraw(ui->label);
    61                 return true;
    62             }
    63             else
    64                 return false;
    65     }
    66     else if(watched == ui->label_2 && event->type() == QEvent::Paint)
    67     {
    68             if(flag == 1)
    69             {
    70                 myDraw(ui->label_2);
    71                 return true;
    72             }
    73             else
    74                 return false;
    75     }
    76     else
    77         return QMainWindow::eventFilter(watched,event);//其它绘图事件交给父类处理
    78 }

    复制代码

    上述写法还是有一个不方便的地方,就是当控件很多的时候,要对每一个控件都单独的像第21行和第22行那样单独的安装事件过滤器。因此可以向QApplication或者QCoreApplication添加事件过滤器,这样就相当于当前应用程序下所有的控件都安装了事件过滤器。

    复制代码

     1 //main.cpp
     2 #include "mainwindow.h"
     3 #include <QApplication>
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8     MainWindow w;
     9     w.show();
    10     a.installEventFilter(&w);//给整个应用程序安装事件过滤器
    11     return a.exec();
    12 }

    复制代码

     

    复制代码

     1 //mainwindow.cpp
     2 #include "mainwindow.h"
     3 #include "ui_mainwindow.h"
     4 #include<QPushButton>
     5 #include<QPaintEvent>
     6 #include<QPainter>
     7 #include<QPen>
     8 #include<QColor>
     9 #include<QString>
    10 #include<QDebug>
    11 #include<QFont>
    12 #include<QPixmap>
    13 #include<QVector>
    14 MainWindow::MainWindow(QWidget *parent) :
    15     QMainWindow(parent),
    16     ui(new Ui::MainWindow)
    17 {
    18     ui->setupUi(this);
    19     labels.push_back(ui->label);
    20     labels.push_back(ui->label_2);
    21     //ui->label->installEventFilter(this);//在label上安装事件过滤器,this指针指定当事件发生时调用当前类中的事件过滤器进行处理
    22     //ui->label_2->installEventFilter(this);//在label_2上安装事件过滤器
    23     connect(ui->pushButton,&QPushButton::clicked,this,[&]()
    24     {
    25         flag =1;
    26         update();//产生绘图事件
    27     });
    28     connect(ui->pushButton_2,&QPushButton::clicked,this,[&]()
    29     {
    30         flag =0;
    31         update();//产生绘图事件
    32     });
    33 }
    34 
    35 MainWindow::~MainWindow()
    36 {
    37     delete ui;
    38 }
    39 
    40 void MainWindow::myDraw(QLabel * label)
    41 {
    42     QPainter painter(label);
    43     painter.setPen(Qt::gray);
    44     painter.setBrush(Qt::green);
    45     painter.drawRect(10,10,20,20);
    46 }
    47 
    48 //void MainWindow::paintEvent(QPaintEvent *)
    49 //{
    50 //    myDraw(ui->label);
    51 //    myDraw(ui->label_2);
    52 //}
    53 
    54 bool MainWindow::eventFilter(QObject *watched, QEvent *event)
    55 {
    56     if(event->type() == QEvent::Paint)//绘图事件
    57     {
    58         if(flag == 1)//标志位为1才在label上绘图,否者不绘图
    59         {
    60             for(QVector<QLabel *>::iterator it=labels.begin();it!=labels.end();it++)
    61             {
    62                 if(watched == *it)//限制条件,只处理label上的绘图事件
    63                 {
    64                     myDraw(*it);
    65                     return true;//返回true表示处理完成该事件,否者该事件还会继续向下转发
    66                 }
    67             }
    68             return QMainWindow::eventFilter(watched,event);//其它绘图事件交给父类处理
    69         }
    70         else
    71             return QMainWindow::eventFilter(watched,event);//其它绘图事件交给父类处理
    72 
    73     }else
    74         return QMainWindow::eventFilter(watched,event);
    75     
    76 }

    复制代码

    展开全文
  • 环境:QT5.5.1+MinGW+windows8.1 这个主要是讲如何其他控件画图。 有关画图的其他常用的api都我上一篇一里面记录下来,主要是供我自己记忆哈哈哈哈。 ...

    环境:QT5.5.1+MinGW+windows8.1

    此篇主要是讲如何在其他控件上画图

    有关画图的其他常用的api都在我上篇里面有记录,主要是供我自己记忆哈哈哈哈。所以东西都是我自己验证可以使用后才截屏上来的,放心使用~

    为了方便整个界面的布局,我选择将图案画在控件widget中。

    方式一:重写paintEvent()函数

    paintEvent()画的图案只能在其所在的类中显示,所以新建一个类,在新类里面画好之后,实例化一个新类的对象,并将其添加到子控件上。这就是整个思路,接下来就贴图显示操作步骤。

    1.创建项目。

    我选择的基类是mainwindows。

    2.添加新的类。

    我给新类取的名字是PainterGragh,这个名字自由取,无限制,尽量直观简单。在paintergragh.h中添加了绘图事件的声明,代码如下:

    #ifndef PAINTERGRAGH_H
    #define PAINTERGRAGH_H
    
    #include <QWidget>
    
    class PainterGragh : public QWidget
    {
        Q_OBJECT
    public:
        explicit PainterGragh(QWidget *parent = 0);
    
        void paintEvent(QPaintEvent *);
    
    signals:
    
    public slots:
    };
    
    #endif // PAINTERGRAGH_H
    

    另外,此类继承的类要与你添加图案的控件类要一致。详细点说:下图是我要添加图案的控件,它的类是QWidget,新类PainterGragh继承的类是QWidget,二者需一致。在这里插入图片描述

    3.在paintergragh.c中的paintEvent()画图

    在这里我就简单的画个矩形和文字演示一下。

    void PainterGragh::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        //设置画笔颜色
        QPen pen(QColor(0,0,127));
        //设置笔宽度
        pen.setWidth(1);
        //给画家拿笔
        painter.setPen(pen);
        //画字体
        painter.drawText(QRect(10,20,200,50),Qt::AlignCenter,"控件上的图案");
        painter.drawRect(QRect(0,0,100,100));
    }
    

    4.在mainwindows.cpp中添加新类实例

        PainterGragh *drawWidget = new PainterGragh(ui->widget);
        drawWidget->setGeometry(0,0,200,200);
    

    然后编译一下就可以看到结果了,我将widget上了个绿黄色用以区分中心控件。结果正常,按钮可以忽略掉。
    在这里插入图片描述

    方式二:使用事件过滤器

    在控件上的操作传给event去分发的过程中将事件拦截掉,不去显示在主界面上,显示在你想要它显示的控件上。这个方式比方式一代码上稍微简单一点,不需要创建新的类。

    1.创建项目。

    我选择的基类是mainwindows。

    2.安装过滤器

    先在mainwindows.h中声明时间过滤器,代码如下

        //事件过滤器
        bool eventFilter(QObject *, QEvent *);
    

    在mainwindows.cpp中的构造函数中安装,代码如下

        //通过父窗口给控件安装事件过滤器
        ui->widget->installEventFilter(this);    
    

    3.重写函数

    在mainwindows.cpp中的eventFilter()下重写函数,更简单了,哈哈,只画了一个圆演示。代码如下

    //重写事件过滤器
    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
    //父类与子类的类型转换,我以为要加,结果发现不加也没问题,
    //难道父类可以兼容子类?不太懂,有懂得小伙伴可以为我答疑,感谢~
    //    QWidget *wi = static_cast<QWidget *>(obj);
        //如果在对象widget中有绘画的事件发生
        if(obj == ui->widget && event->type() == QEvent::Paint)
        {
            //在widget上画图
            QPainter painter(ui->widget);
            painter.drawEllipse(QPoint(20,20),20,20);
        }
        //其他的交给父类去处理
        return QWidget::eventFilter(obj,event);  
    }
    

    编译运行的结果如下,依旧忽略按钮。
    在这里插入图片描述
    综上,两种方式都可以在你想要的控件上画图,任你选。如果这两个方式有什么问题可以评论,我看到会回复的,大家一起讨论~

    展开全文
  • 学习Qt使用Painter绘图时,只能其所在的类里进行操作,本文介绍怎么控件上实现使用Painter绘图功能。ui-&gt;frame-&gt;installEventFilter(this); //安装事件过滤器到窗口//事件过滤器 bool ...

    在学习Qt使用Painter在绘图时,只能在其所在的类里进行操作,本文介绍怎么在子控件上实现使用Painter绘图功能。

    ui->frame->installEventFilter(this);        //安装事件过滤器到窗口
    //事件过滤器
    bool Widget::eventFilter(QObject *watched, QEvent *event){
        if(watched == ui->frame && event->type() == QEvent::Paint){//在frame上画图
            Painter();
        }else{}
        return QWidget::eventFilter(watched,event);     //将事件传递给父类
    }
    即可实现


    例程参考:https://download.csdn.net/download/qq_28091109/10406299

    展开全文
  • 最近学校安排写一个五子棋的网络游戏,QLabel上使用 .setPixmap() 绘制了棋盘,然后用 QPainter.drawPixmap() 棋盘上绘制棋子,遇到棋子无法显示棋盘上的问题,查阅很多资料没有问题,后来自己写了个实验程序...
  • QT使用QPainter在ui子控件中绘图

    万次阅读 2016-05-17 17:25:26
    本文介绍一下怎么实现ui的子控件中用QPainter实现绘图。以QLabel为例: 1.QT工程新建一个类PaintLabel,继承自QLabel。 //paintlabel.h文件#ifndef PAINTLABEL_H #define PAINTLABEL_H #include class ...
  • qt任意控件画图

    千次阅读 2017-10-28 21:17:37
    http://blog.csdn.net/z609932088/article/details/50952086
  • QTableWidget里面有很多单元格,我想画条线把任意2个单元格连接起来。画矩形,根据 4个单元格比如A(2,3),B(5,3),C(2,10),D(5,10)括号里面数字为对应的行列值,画出一个矩形,并填充颜色。
  • 我需要QwtPlot上画图,但是图片总是没有显示坐标轴上,我找了资料,有的说直接把控件名替代QPainter(this)的this,还有的说这个类下面重载paintEvent(QPainterEvent *event);函数,但是我两个都试过了,还是不...
  • QPainterQWidget上执行绘图操作,它是一个绘图工具,为大部分图形界面提供了高度优化的函数,绘制操作QWidget.paintEvent()完成。绘制方法必须放在QtGui.QPainter对象的begin() 和end()之间。 一、QPainter...
  • 本资源为QPainter绘制基础图形(二),利用鼠标拖动绘制。
  • QtWidgets进行 1、qt窗口代码 from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(401, 318) self.stackedWidget ...
  • Qt中QPainter基本绘图

    2020-08-21 22:45:16
    QWidget 派系的只能paintEvent进行重绘;如果你想要很好的交互功能的话推荐QGraphicsView框架,自定义Item的绘制paint函数;如果你想利用线程绘制的话,你可以创建个QPixmap或者QImage,然后把图片当画布...
  • PyQt5一般可以通过QPainter、QPen、QBrush这三个类来实现绘图功能,另外QPixmap也可以被看作为绘图类,因其图像的呈现方式本质上来说也是通过绘图的方式将本地的图片进行呈现。 二、QpainterQPainter...
  • Qt 在控件上面绘图 label,pushbutton。。。。。 1、构建一个新类来调用该控件的绘图函数,新类重写 paintEvent(QPaintEvent *) ▶构建: class DrawGraphLab : public QLabel { Q_OBJECT public: explicit ...
  • Qt子部件上画图(QFrame)实现

    热门讨论 2014-01-14 13:46:16
    用过滤器的方式,实现Frame和Widget子部件上画图,很有启发性!
  • QT 实现QLabel上画图

    2018-04-12 20:49:00
    paintevent()函数,通常需要设置QPainter对象,创建QPainter对象的同时需要指定绘图设备,即继承自QPainterDevice的子类作为绘图设备,绘制出来的图形将这个设备上进行显示,Qt一共提供了4个这样的类,分别是...
  • Qt之图形(QPainter的基本绘图)

    千次阅读 2017-12-04 21:17:35
    简述Qt 提供了强大的 2D 绘图系统,可以使用相同的 API 屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。 QPainter 用于执行绘图操作,其提供的 API GUI 或 QImage、...
  • 文章目录前言上一篇:[QPainter之绘制鼠标路径(画笔工具)](https://editor.csdn.net/md/?articleId=116173563)一、程序示例二、重要步骤修改画图方式 —— 重构思想1.拖入控件2.构造函数初始化变量3.重写事件函数...
  • Qt 在控件上面绘图 label,pushbutton。。。。。 以下提供两种方法: 1、构建一个新类来调用该控件的绘图函数,新类重写 paintEvent(QPaintEvent *) ▶构建: class DrawGraphLab : public QLabel { Q_OBJECT ...
  • [QT]子窗口或者控件中绘图

    千次阅读 2018-01-30 22:04:00
    子窗口绘图,有2种方法: 1.重写子窗口的控件类(即继承该类,并重载...(注:使用QPainter画图时,只能指定所属为当前类的引用Qpainter painter = new QPainter(this),所以应重写paintEvent()) 填写...
  • painter在控件上绘图无反应(eventFilter的使用)1、为控件安装事件过滤器2、头文件添加绘制函数和事件过滤函数3、函数实现4、效果如下 1、为控件安装事件过滤器 ui->lblImage->installEventFilter(this);...
  • 2、QDialog窗体显示QWidget部件 【效果图】 【资源】 //img.jbzj.com/file_images/article/201710/brick.png//img.jbzj.com/file_images/article/201710/qt-logo.png 【代码】 import sys from PyQt5.QtCore ...
  • Qt——QPainter画图

    2018-12-02 20:44:03
    QPainter painter(ui-&... //括号内设置画图位置 QPen pen; painter.setRenderHint(QPainter::Antialiasing, true); pen.setColor(Qt::gray); pen.setWidth(1); painter.setPen(pen); painter.drawLin...
  • 激活事件过滤器 ui->widgetGrid->installEventFilter(this); 重写函数eventFilter ...bool MainWindow::eventFilter(QObject *watched, QEvent *event... //筛选子控件 if(watched == ui->widgetGrid ) ...
  • 1、QPainter 常用方法 方法 描述 ...开始目标设备上绘制 ...起始角度和最终角度之间画弧 ...一个矩形内画一个...从图像文件提取 Pixmap 并将其显示指定位置 drawPolygon() 使用坐标数组绘制多边形 drawRe

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 482
精华内容 192
关键字:

qpainter在控件中画图