Qt如何把QPainter绘图对象作为参数传递给业务类,由业务类完成绘图操作?

ooolinux 2018-05-15 10:29:40
Qt如何把QPainter绘图对象作为参数传递给业务类,由业务类完成绘图操作?
比如在窗体类中new一个业务类,把QPainter绘图对象作为业务类构造函数的参数传递进去,在业务类的多个成员函数中完成不同的绘图操作,大概要怎么弄?
...全文
3025 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2018-08-07
  • 打赏
  • 举报
回复
最近看到类似这样的问题:如何用QPainter对象动态画图(比如根据采集的数据画动态折线图)?
ooolinux 2018-05-25
  • 打赏
  • 举报
回复
引用 18 楼 u010165006 的回复:
[quote=引用 17 楼 DelphiGuy 的回复:] 就是写若干个绘制函数,然后有一个全局函数指针,在按钮事件中把函数指针赋值为某个绘制函数,paintEvent中通过函数指针调用绘制函数。
明白意思了,问题是函数是业务类的成员函数,函数指针怎么弄?[/quote] 想到C++ Builder的__closure上去了~
ooolinux 2018-05-25
  • 打赏
  • 举报
回复
引用 25 楼 u012532263 的回复:
把painter的指针当做参数传递给需要函数就好啦
看前面某楼~
决战小树林 2018-05-25
  • 打赏
  • 举报
回复
把painter的指针当做参数传递给需要函数就好啦
ooolinux 2018-05-18
  • 打赏
  • 举报
回复
我那个程序改成整个刷新重绘了,CPU占有率降低到0,偶尔1。 C++ Builder 6.0的版本,因为编译选项未优化,还是用默认编译成i386指令集,还有每次都是擦除一个对象再重绘(相当于多绘制一倍),进程占用CPU为1%~3%。 这样看Qt Widgets的图形性能不差。
ooolinux 2018-05-18
  • 打赏
  • 举报
回复
引用 22 楼 DelphiGuy 的回复:
如果要多个绘制叠加,可以用掩码的方法: void CustomDrawing::Draw() { if (DrawType & 1) Draw1(); if (DrawType & 2) Draw2(); // DrawType的每一位代表要不要绘制某个效果 }
这样应该可以,回去试试。 不过我原来的一个程序是用擦除重绘的,如果改成整个刷新重绘也可以,还省了擦除的步骤。 最近都无力思考了,只能改改原来的程序
  • 打赏
  • 举报
回复
如果要多个绘制叠加,可以用掩码的方法: void CustomDrawing::Draw() { if (DrawType & 1) Draw1(); if (DrawType & 2) Draw2(); // DrawType的每一位代表要不要绘制某个效果 }
  • 打赏
  • 举报
回复
class CustomDrawing { private: void Draw1() {printf("CustomDrawing 1\n");}; void Draw2() {printf("CustomDrawing 2\n");}; public: int DrawType; void Draw(); } test; void CustomDrawing::Draw() { if (DrawType == 1) Draw1(); else if (DrawType == 2) Draw2(); } void paintEvent() { //... test.Draw(); } 只需要在按钮事件中设置DrawType即可,可以不用函数指针了(用函数指针可以避免Draw中的分支判断,如果分支多的话会好一些)。
ooolinux 2018-05-18
  • 打赏
  • 举报
回复
现在的问题是,我的绘图效果是需要叠加上去的,drawB的绘制效果要叠加到drawA的绘制效果之上,而楼上的代码是update()以后就整个刷新重绘了。 不知道有没有办法?
ooolinux 2018-05-18
  • 打赏
  • 举报
回复
用成员函数指针可以的,测试代码: testpaint.h
#ifndef TESTPAINT_H
#define TESTPAINT_H

#include <QPainter>

class TestPaint
{
public:
    TestPaint();
    void drawA(QPainter &painter);
    void drawB(QPainter &painter);
};

#endif // TESTPAINT_H
testpaint.cpp
#include "testpaint.h"

TestPaint::TestPaint()
{

}

void TestPaint::drawA(QPainter &painter)
{
    painter.setPen(QPen(Qt::red,5));
    painter.drawLine(0,0,100,100);
}

void TestPaint::drawB(QPainter &painter)
{
    painter.setPen(QPen(Qt::blue,5));
    painter.drawEllipse(0,0,100,100);
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include "testpaint.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Dialog *ui;
    TestPaint *testPaint;
    void (TestPaint::*pfun)(QPainter &painter);
    void paintEvent(QPaintEvent *event);
};

#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    testPaint=new TestPaint();
    pfun=NULL;
}

Dialog::~Dialog()
{
    delete ui;
    delete testPaint;
}

void Dialog::on_pushButton_clicked()
{
    pfun=TestPaint::drawA;
    update();
}

void Dialog::on_pushButton_2_clicked()
{
    pfun=TestPaint::drawB;
    update();
}

void Dialog::paintEvent(QPaintEvent *event)
{
    if(pfun)
    {
        QPainter painter(this);
        (testPaint->*pfun)(painter);
        pfun=NULL;
    }
}
ooolinux 2018-05-18
  • 打赏
  • 举报
回复
引用 17 楼 DelphiGuy 的回复:
就是写若干个绘制函数,然后有一个全局函数指针,在按钮事件中把函数指针赋值为某个绘制函数,paintEvent中通过函数指针调用绘制函数。
明白意思了,问题是函数是业务类的成员函数,函数指针怎么弄?
  • 打赏
  • 举报
回复
就是写若干个绘制函数,然后有一个全局函数指针,在按钮事件中把函数指针赋值为某个绘制函数,paintEvent中通过函数指针调用绘制函数。
ooolinux 2018-05-17
  • 打赏
  • 举报
回复
引用 13 楼 DelphiGuy 的回复:
那只好每个业务对象的绘制成员函数用一个成员函数指针,如果不要求同时绘制,也可以一个函数指针切换
用函数指针的方式没明白该怎么弄。
ooolinux 2018-05-17
  • 打赏
  • 举报
回复
引用 14 楼 huo5896324 的回复:
[quote=引用 5 楼 u010165006 的回复:] [quote=引用 4 楼 huo5896324 的回复:] 就把 painter(this),这个painter传到你的pushbutton里面去,在pushbutton里调这个painter的draw函数就可以绘制在this上面了
通常是这样认为的,但是Qt比较特殊,百度到的信息: —————— 其实吧在QWidget系你只能在paintEvent中做绘图的工作,其他地方都不行。 All painting on a widget must happen in the paintEvent() function, and you are trying to paint outside of it - that won't work. —————— 测试代码: void MainWindow::on_pushButton_clicked() { QPainter painter(this); painter.setPen(QPen(Qt::red,5)); painter.drawLine(0,0,100,100); } [/quote] 确实是这样。不过你那种方式为什么要用定时器,定时重绘呢?你不是按钮按一下才需要重绘?在按钮槽函数里重绘不就可以了?[/quote] 用定时器是为了测试大量绘制。
huo5896324 2018-05-17
  • 打赏
  • 举报
回复
引用 5 楼 u010165006 的回复:
[quote=引用 4 楼 huo5896324 的回复:] 就把 painter(this),这个painter传到你的pushbutton里面去,在pushbutton里调这个painter的draw函数就可以绘制在this上面了
通常是这样认为的,但是Qt比较特殊,百度到的信息: —————— 其实吧在QWidget系你只能在paintEvent中做绘图的工作,其他地方都不行。 All painting on a widget must happen in the paintEvent() function, and you are trying to paint outside of it - that won't work. —————— 测试代码: void MainWindow::on_pushButton_clicked() { QPainter painter(this); painter.setPen(QPen(Qt::red,5)); painter.drawLine(0,0,100,100); } [/quote] 确实是这样。不过你那种方式为什么要用定时器,定时重绘呢?你不是按钮按一下才需要重绘?在按钮槽函数里重绘不就可以了?
  • 打赏
  • 举报
回复
那只好每个业务对象的绘制成员函数用一个成员函数指针,如果不要求同时绘制,也可以一个函数指针切换
ooolinux 2018-05-17
  • 打赏
  • 举报
回复
引用 10 楼 DelphiGuy 的回复:
也许可以把特殊绘制独立为一个函数,然后用一个函数指针指向它,在paintEvent()中检测: void (*CustomDrawing)(); CustomDrawing = xxx; paintEvent()中:
那相当于在paintEvent函数中以QPainter(this)为参数直接调用业务类的绘图成员函数吗? 我的流程是,按窗体某个按钮,调用业务对象drawA成员函数,按另一个按钮,调用drawB成员函数,感到不好弄。
  • 打赏
  • 举报
回复
if (CustomDrawing) CustomDrawing();
  • 打赏
  • 举报
回复
也许可以把特殊绘制独立为一个函数,然后用一个函数指针指向它,在paintEvent()中检测: void (*CustomDrawing)(); CustomDrawing = xxx; paintEvent()中:
ooolinux 2018-05-17
  • 打赏
  • 举报
回复
不知道直接绘制到QPainter(this)对象上性能会不会好点, 问题还是Qt如何把QPainter(this)绘图对象作为参数传递给业务类,由业务类完成绘图操作?
加载更多回复(7)

16,203

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧