今天重新研究Qt窗体绘图和图片显示
(1)窗体的背景上绘制线段和区域
(2)窗体背景显示图片以及图片缩放
(3)无边框窗体显示以及无边框窗体的移动
(4)自定义widget形状
(1) 在窗体上执行绘制线段和区域等操作
图1
![](https://img-blog.csdn.net/20150124095230229?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXlfZnJpZW5kX3NoaXA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![]()
有时候需要在窗体的背景上绘制一些直线或者对某个区域进行填充等操作,下面就详细说明这一操作的过程
在窗体重绘制是通过void test::paintEvent(QPaintEvent *pevent)方法进行重绘的,只是这个方法仅仅重新绘制
窗体的中心区域,图1是一个对窗体背景进行填充的一个图片,另外test窗体上还放置了一个QLabel,内容是"i am label 1"
看了效果图,我们在来分析这个实现过程.由于是要对窗体test的背景进行重绘,text窗体类是继承自class test : public QMainWindow,
默认状态下,test窗体调用基类QMainWindow的虚函数paintEvent进行重绘test窗体的中心区域,我们要改变test的中心区域,就需要
重新实现paintEvent方法,先将void paintEvent(QPaintEvent *)添加到test类的成员函数 ,
private:
virtual void paintEvent ( QPaintEvent * ) ;
具体代码如下:
void test::paintEvent(QPaintEvent *pevent)
{
QPainter painter(this);
QPen pen; //画笔
pen.setColor(QColor(255,0,0));
QBrush brush(QColor(255,0,0)); //画刷
painter.setPen(pen); //添加画笔
painter.setBrush(brush); //添加画刷
painter.drawRect(0,0,this->width(),this->height()); //绘制矩形
<span style="white-space:pre"> </span>painter.drawLine(0,0,30,30);
}
(2)窗体背景显示图片以及图片缩放
下面在看怎么把图片显示到窗体背景上
图2
![](https://img-blog.csdn.net/20150124100652000?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXlfZnJpZW5kX3NoaXA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
使用QPixmap
void test::paintEvent(QPaintEvent *pevent)
{
QPainter painter(this);
QPixmap *pixmap=new QPixmap(":test/Resources/shili2.png"); //注意是/而不是\
painter.drawPixmap(pixmap->rect(),*pixmap);
}
使用QImage
void test::paintEvent(QPaintEvent *pevent)
{
QPainter painter(this);
QImage *pimage=new QImage(":test/Resources/shili2.png");
painter.drawImage(pimage->rect(),*pimage);
}
如果需要设置窗体背景的透明程度,我们在test的构造函数中这样处理
test::test(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
this->setAttribute(Qt::WA_TranslucentBackground, true);//使能透明
this->setWindowOpacity(0.5);//设置透明度
}
如果需要对QPixmap进行缩放显示的话可以这样
</pre><pre name="code" class="cpp">void test::paintEvent(QPaintEvent *pevent)
{
QPainter painter(this);
QPixmap *pixmap=new QPixmap(":test/Resources/shili2.png"); //注意是
qDebug()<<"\npixmap w and h "<<pixmap->width()<<" "<<pixmap->height()<<"\n";
QPixmap pixmap2;
pixmap2=pixmap->scaled(pixmap->width()/2,pixmap->height()/2,Qt::IgnoreAspectRatio);
qDebug()<<"\npixmap w and h "<<pixmap2.width()<<" "<<pixmap2.height()<<"\n";
painter.drawPixmap(pixmap2.rect(),pixmap2);
}
需要说明的是Qt中的scaled函数不是对对象本身进行缩放操作,也就是说这里pixmap->scaled不是对pixmap本身进行操作,
调用scaled后,pixmap本身不会改变,scaled返回一个缩放后的pixmap,同样QImage也有scaled方法,可以进行缩放操作
(3)无边框窗体显示以及无边框窗体的移动
在说明一下怎么让test窗体无边框窗口没有标题栏,默认拖拽窗体是没法移动窗口的,也就是不显示最大
化最小化这栏内容,这个做法很简单,这属于test的窗体属性那么我们可以在构造函数中指定窗体的属性,具体做法是修改ui生
成的构造函数声明部分的默认参数,生成的是这样:
public:
test(QWidget *parent = 0, Qt::WFlags flags = 0);
我们只需要修改成
public:
test(QWidget *parent = 0, Qt::WFlags flags =Qt::FramelessWindowHint);
修改后重新编译运行,截图如图3
图3
![](https://img-blog.csdn.net/20150124105749564?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXlfZnJpZW5kX3NoaXA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
使用Qt::WFlags flags =Qt::FramelessWindowHint标志,会导致这个窗体不能移动,但还可以调节大小
实现无边框窗体的移动:
实现无边框窗体拖拽移动需要重写重写 mousePressEvent() 和 mouseMoveEvent() 虚函数.
示例代码如下,没有进行测试过
void test::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
*dragPos_ = event->globalPos() - frameGeometry().topLeft();
event->accept();
}
}
void test::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton)
{
move(event->globalPos() - *dragPos_);
event->accept();
}
}
(4)自定义widget形状
自定义widget形状
widget类有个setMask方法,进行设置widget 显示的边界:void QWidget::setMask ( const QBitmap & bitmap )对QLabel的显示边界设定可以这样,
对 QPixmap获取QBitmap,可以使用QBitmap QPixmap::mask () const
<span style="white-space:pre"> </span>QLabel topLevelLabel;
<span style="white-space:pre"> </span>QPixmap pixmap(":/images/tux.png");
<span style="white-space:pre"> </span>topLevelLabel.setPixmap(pixmap);
<span style="white-space:pre"> </span>topLevelLabel.setMask(pixmap.mask());