• 24445阅读
  • 42回复

[提问]如何在QLabel上显示一块画布呢? [复制链接]

上一主题 下一主题
离线liangzw
 
只看楼主 倒序阅读 楼主  发表于: 2011-08-31
各位高手,小弟初学QT,请问如何在QLabel显示一块画布呢?或者如何在一个对话框上显示一块新的画布?在线等~~
无限感激啊!!
离线roywillow

只看该作者 1楼 发表于: 2011-08-31
请问这里所说的画布是什么?
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线liangzw
只看该作者 2楼 发表于: 2011-08-31
回 1楼(roywillow) 的帖子
这样定义的一个画布
image = QImage(960,450,QImage::Format_RGB32);
backColor = qRgb(255,0,0);
image.fill(backColor);

我是想在一个对话框上画图的,请问还有什么其他的方法吗?
离线roywillow

只看该作者 3楼 发表于: 2011-08-31
就是一个QImage嘛
我记得QLabel只能显示QPixmap,把QImage转换成QPixmap然后显示就可以了
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线liangzw
只看该作者 4楼 发表于: 2011-08-31
回 3楼(roywillow) 的帖子
你好,可以说说说怎样转换吗?刚学QT没多久,很多东西还不是很会。。。。无限感谢啊
离线roywillow

只看该作者 5楼 发表于: 2011-08-31
QPixmap QPixmap::fromImage ( const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor ) [static]

文档中讲的很清楚的
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线jdwx

只看该作者 6楼 发表于: 2011-08-31
class xxxx : public QLabel
{
protected:
void paintEvent(QPaintEvent *);//就在这里画图。
}
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 7楼 发表于: 2011-08-31

两位高手,搞了很久还是不行。把代码贴下来,恳请指点指点

这是我的头文件
#ifndef DIALOG_H
#define DIALOG_H
#include <QWidget>
#include <QDialog>
#include "paintarea.h"
#include "win_qextserialport.h"
#include "qextserialport.h"
namespace Ui {
    class Dialog;
}
class Dialog : public QDialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
      QImage image; //QImage 类对象,用于在其上绘图
    QRgb backColor; //QRgb 颜色对象,存储image 的背景色

private slots:
    void on_pushButton_2_clicked();

private:
    Ui::Dialog *ui;
    Win_QextSerialPort  *myCom;
};
#endif // DIALOG_H

这是执行文件
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    image = QImage(960,450,QImage::Format_RGB32); // 画布的初始化大小设为960*450,使用32 位颜色
    backColor = qRgb(0,0,0); //画布初始化背景色使用白色
    image.fill(backColor);
      //按我的理解应该是在ui->QLabel这里添加画布上去,但是不知道怎样添加了。
  }
Dialog::~Dialog()
{
    delete ui;
}
离线morriszy

只看该作者 8楼 发表于: 2011-08-31
回 7楼(liangzw) 的帖子
用COM口是干嘛的呀,跟下位机通讯吗?
VS2010+Qt4.7.0
离线jdwx

只看该作者 9楼 发表于: 2011-08-31
回 7楼(liangzw) 的帖子
还没弄明白你要做什么?改背景颜色,背景图片还是画图?
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 10楼 发表于: 2011-08-31
回复楼上两位仁兄,我用QT设计师画了一个很大的对话框,要在对话框指定某一区域上画图,这是就是要求,而我的想法就是在要画图的那个区域里放了一个QLabel,然后在QLabel上画图,但是没实现。请问这种情况如何在QLabel上画图呢。。或者还有什么方案可以满足这个要求的呢?
PS:那个COM口是跟下位机通信的。
离线roywillow

只看该作者 11楼 发表于: 2011-08-31
如果你真想“绘图”,重载paintEvent应该是免不了的
不过你用QLabel也是个方法
那个QImage可以用QPixmap的fromImage转换为QPixmap,然后QLabel又有setPixmap函数可调用,应该就是这个流程了
至于怎么在QImage上绘图,自己应该了解一些了吧
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线abcdlcq

只看该作者 12楼 发表于: 2011-09-01
还得setAutoFillBackground( true )吧
离线jdwx

只看该作者 13楼 发表于: 2011-09-01
回 10楼(liangzw) 的帖子
画图就俩方案:
自己写控件类,在里面的paintevent画。
用现成控件,安装事件监视器。
Qt不像MFC,什么时候都能画图,Qt画图受限制,还不能在屏幕,桌面上画图。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 14楼 发表于: 2011-09-01
回 13楼(jdwx) 的帖子
感谢几位大侠的指教,我直接在paintEvent里用drawImage这个函数把前面定义的image画出来了。。不过现有个新问题,在一个对象里定义一个QList的容器,并赋值。但是在另一个对象里读不到QList容器的值,例如我在paint对象定义了QList <double> list,用list.append*(xx)赋值xx.然后在dialog对象里定义area=new paint;  用一个double类型的y=area->list.,但是y的值还是为0,链表里的值怎样在不同的对象传递呢?
PS:在dialog的头文件的声明 paint *area
离线liangzw
只看该作者 15楼 发表于: 2011-09-01
回 13楼(jdwx) 的帖子
那个赋值打多了一个*号,应该是list.append(xx)
离线jdwx

只看该作者 16楼 发表于: 2011-09-01
回 14楼(liangzw) 的帖子
基础问题,看看STL的书籍。
list里储存很多数据,把它想成数组(list不是数组,QVector类似数组)比较好理解
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线roywillow

只看该作者 17楼 发表于: 2011-09-01
QList记得不是链表,QLinkedList才是
看你的意思好像是希望访问另一个对象的成员?把那个成员声明为public或者提供一个public成员函数来返回这个成员值就好了吧
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线liangzw
只看该作者 18楼 发表于: 2011-09-01
回 17楼(roywillow) 的帖子
你好,这个QList<double> list;我是在一个对象声明为public的,并且在这个对象的执行函数赋了几个值,然后我在另一个对象里这样调用
QList<double> workData;
QMutableListIterator<double> i(area->list);    
while(i.hasNext())
    {
       workData.append(i.next());
    }
但是workData却没赋到值,而且这个循环也没进入。应该怎样调用另一个对象的QList呢?
补充一下,那个area是声明继承要调用的对象的了
离线jdwx

只看该作者 19楼 发表于: 2011-09-02
class area
{
public:
area();
QList<double> *arealist();
private:
QList<double> mylist;
};
QList<double> *area::arealist()
{
return &mylist;
}

#include "area.h"
class draw
{
public:
draw();
protected:
void paintEvent();
}
void draw::paintEvent()
{
area myarea;
for(int i=0;i<myarea.arealist()->count;i++)
     double d=myarea.arealist().at(i);//取list的数据
}





发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 20楼 发表于: 2011-09-05
回 19楼(jdwx) 的帖子
大侠,我按你的方法试过了总是报错,我想把那个QList的容器类定义为全局变量,但是试了很多方法在另一个对象读QList的值还是为零。全局变量应该是怎样声明和调用的呢?
离线jdwx

只看该作者 21楼 发表于: 2011-09-06
回 20楼(liangzw) 的帖子
会好用的。
附件: list.rar (5 K) 下载次数:3
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 22楼 发表于: 2011-09-06
回 21楼(jdwx) 的帖子
你好,真的非常感谢你在百忙中还特意写一个例子。。不过我有几点不明白,那个dialog一定要通过mainwindow来调用CList里面的函数吗?
我按照你的方法试了,直接把这部分的代码放在dialog的构造函数里,程序运行的时候一按进入dialog就死机了,还有我QList容器是在CList里面的一些函数里面赋值的,不是在构造函数赋值,我试过在构造函数赋值的话在另一个对象是可以读到值,在对象中的函数赋值的就读不到
离线liangzw
只看该作者 23楼 发表于: 2011-09-06
回 21楼(jdwx) 的帖子
补充一下,我是把这些代码
MainWindow *mainwindow = (MainWindow*)parentWidget();
    for(int i= 0;i<mainwindow->doubleList()->listData()->count();i++)
    {
        ui->listWidget->addItem(QString::number(mainwindow->doubleList()->listData()->at(i)));
    }
直接放在我的dialog的构造函数里
离线liangzw
只看该作者 24楼 发表于: 2011-09-06
回 23楼(liangzw) 的帖子
感觉说的有点乱了,可以加我QQ276112029吗,论坛上说不清楚,还恳多多指教啊
离线jdwx

只看该作者 25楼 发表于: 2011-09-06
估计是你的某些代码有问题,经测试没有问题。
附件: list.rar (5 K) 下载次数:3
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线jdwx

只看该作者 26楼 发表于: 2011-09-06
那个dialog一定要通过mainwindow来调用CList里面的函数吗?
答:因为clist在mainwindow里,必须通过mainwindow。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 27楼 发表于: 2011-09-07
你好,这两幅图就是我所有的文件,list在paintarea里引用,并且是在paintarea里的一些函数里面赋值的,然后mainwindow引用paintarea,从mainwindow里进入dialog,按你的方法,那在dialog就直接引用paintarea,但是我这样试了读出来的值还是零。
PS:list是跟你的完全一样的,paintarea引用list的方法也是跟你用mainwindow引用list一样的,然后dialog引用paintarea也是跟你用dialog引用mainwindow一样的。
请问我的问题在哪里呢?万分感谢
离线jdwx

只看该作者 28楼 发表于: 2011-09-07
回 27楼(liangzw) 的帖子
(那在dialog就直接引用paintarea)
把这段代码贴出来,分析分析。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 29楼 发表于: 2011-09-07
list 的函数跟你给的一样,paintarea引用list,paintarea.h的头文件声明list的也是跟你在mainwindow的一样,在paintarea中给list赋值的代码如下

void PaintArea::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton) //如果鼠标左键释放
    {
if(isDrawing)
     {
     paint(image);
    isfirst=false;
    QRect rect(Margin, Margin,
            image.width()- 2 * Margin, image.height() - 2 * Margin);//参数分别代表上、左、宽、高,构造一个矩形
     if (!rect.isValid())
      return;
     switch(curShape)///判断图形的类型,然后保存数据
     {
     case None:
         {
             break;
         }
     case Line:
         {
        list.listData()->push_back(lastPoint.x());list.listData()->push_back(lastPoint.y());    /在这里给list赋值
             break;
         }
     case Ellipse:
         {
            list.listData()->push_back(lastPoint.x());list.listData()->push_back(lastPoint.y());    /在这里给list赋值
             break;
         }
     case Arc:
       {
         //pp.drawArc(x,y,w,h,90*16,100*16);
     break;
        }
     }
        for(int i=0;i<list.listData()->count();++i)   //这里有数据打印出来,证明list里面有值
        {
            qDebug()<<list.listData()->at(i);
            qDebug()<<"---list output";
        }
   }
  }
然后从mainwindow进入dialog,代码如下
void MainWindow::on_actionGo_triggered()
{
   Dialog dia;
   dia.exec();
}

在dialog调用paintarea的函数如下
先在dialog头文件的public声明
PaintArea *area;
再在dialog的构造函数这样调用

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);  
    area = new PaintArea;
    qDebug()<<"out list num";
    qDebug()<<area->doubleList()->listData()->count();
}结果一进入dialog打印出来的list值始终为零
你觉得是哪里的问题呢?
离线liangzw
只看该作者 30楼 发表于: 2011-09-07
回 28楼(jdwx) 的帖子
我把大概的代码贴出来了。。你觉得问题在哪里呢?
真的非常的感谢你了
离线liangzw
只看该作者 31楼 发表于: 2011-09-07
回 28楼(jdwx) 的帖子
忘记了一点,paintare引用list的函数也是跟你的一样的,
在paintarea.h的public声明
CList *doubleList();
在private的声明
CList list;
在paintarea.cpp的函数也是一样
CList *PaintArea::doubleList()
{
    return &list;
}
离线jdwx

只看该作者 32楼 发表于: 2011-09-07
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);  
    area = new PaintArea;//问题在这里
    qDebug()<<"out list num";
    qDebug()<<area->doubleList()->listData()->count();

试试下面的代码:
Calss Dialog:publicQDialog  //dialog.h
{
public:
Dialog();
paintArea *area;
}
void MainWindow::on_actionGo_triggered()
{    
Dialog dia;
    dia.area=this->area;//假设paintarea是在mainwindow里定义的。
   dia.exec();
}
简单点说:要找到你存入数据的list,把它传到dialog里,而不是new一个新的。





发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线jdwx

只看该作者 33楼 发表于: 2011-09-07
还有画图,储存图形数据最好用QObject派生出需要的图形类,储存到 QObjectList里。
这是最通用的方法。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 34楼 发表于: 2011-09-07
回 32楼(jdwx) 的帖子
我按你的代码改过了,dialog构造函数中的area = new PaintArea;屏蔽了,但是一进入dialog程序就死了。还有什么方法可以找回存入数据的list呢。还是要在dialog引用mainwindow,通过mainwindow来引用paintarea呢?
离线jdwx

只看该作者 35楼 发表于: 2011-09-07
还是要在dialog引用mainwindow,通过mainwindow来引用paintarea
没错就要这么做。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线jdwx

只看该作者 36楼 发表于: 2011-09-07
回 34楼(liangzw) 的帖子
还是要在dialog引用mainwindow,通过mainwindow来引用paintarea
没错就要这么做。
附件: list.rar (5 K) 下载次数:5
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线liangzw
只看该作者 37楼 发表于: 2011-09-07
回 35楼(jdwx) 的帖子
我在mainwindow头文件的public又定义了一个
QList<double> mylist_2;
然后在mainwindow.cpp改成如下,
void MainWindow::on_actionGo_triggered()
{
    for(int i=0;i<area->doubleList()->listData()->count();++i)
    {
        mylist_2.push_back(area->doubleList()->listData()->at(i));
        qDebug()<<mylist_2.at(i);
    }
    Dialog dia(this);
       dia.exec();
}
然后在dialog这样调用
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);  
MainWindow *mainwindow = (MainWindow*)parentWidget();
qDebug()<<mainwindow->mylist_2.count();
}这样进入dialog能读到在paintarea给list赋的值,但是这样通过几个QList来传递值,这样数据会不会不安全啊?因为我这些数据要通过插补法再通过串口传输下位机的啊
离线liangzw
只看该作者 38楼 发表于: 2011-09-08
回 36楼(jdwx) 的帖子
刚才没看到你的附件,按你附件的方法,我直接把在dialog的头文件public哪里声明
PaintArea *area;
然后再dialog的构造函数里
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);  
  MainWindow *mainwindow = (MainWindow*)parentWidget();
     area=mainwindow->area;
     qDebug()<<area->doubleList()->count();
     for(int i=0;i<area->doubleList()->count();i=i+5)
     {
         title=quint32(area->doubleList()->at(i));
         x=area->doubleList()->at(i+1)*0.12;
         y=area->doubleList()->at(i+2)*0.12;
         x1=area->doubleList()->at(i+3)*0.12;
         y1=area->doubleList()->at(i+4)*0.12;

         paint(image,title,x,y,x1,y1);
       qDebug() <<title <<x <<y <<x1 <<y1;
     }
这样我就能把paintarea里画的图形还原出来了。。
真的非常感谢你的及时的指导,
离线liangzw
只看该作者 39楼 发表于: 2011-09-09
大侠,还麻烦您一下,这种效果在qt用什么方法实现呢

那些方格是拿来画图的,可以增加方格也可以减少方格,下边和右边的滚动条移动的时候两边坐标的数据一直在,而且他们的值随着移动而变,简单说就是一个X-Y轴的坐标,然后在这个系统上画图。
请问用什么技术可以实现这种效果呢。。。万分感谢啊
快速回复
限100 字节
 
上一个 下一个