Qt中如何利用 png 图片来实现自定义形状的窗口

Qt中如何利用 png 图片来实现自定义形状的窗口  

转载

http://ggicci.blog.163.com/blog/static/21036409620129299159298/


  |举报|字号 订阅

  • Qt 中 QWidget::setMask() 的用法
  • 把 QWidget 自定义成各种形状,使用 png 透明图片作为窗体显示,效果如下

2012-10-29_1903

2012-10-29_1902 2012-10-29_1904 2012-10-29_1905


关键知识:
  1. Qt::WindowFlags 使窗口支持无边框 [From Qt Doc:This enum type is used to specify various window-system properties for the widget. They are fairly unusual but necessary in a few cases. Some of these flags depend on whether the underlying window manager supports them.]。使用 Qt::WindowFlags 可以实现一些不同类型的窗口,如:用 Qt::FramelessWindowHint 来实现无边框窗口,用 Qt::Popup 来实现弹出式的窗口,用 Qt::Tool 来实现工具窗口,用Qt::CustomizeWindowHint 来关闭窗口标题栏以及与 Qt::WindowCloseButton(添加关闭按钮),Qt::WindowMaximumButtonSize(添加最大化按钮)联用来建立只有关闭按钮和最大化按钮的窗口,用 Qt::WindowStaysOnTopHint 使窗口永远在最前端等。
  2. Qt::WidgetAttribute 使窗口支持透明背景以及在关闭后主动销毁。其它一些常用的 Attribute 有:Qt::WA_AcceptDrops 使 widget 支持拖拽操作,Qt::WA_MouseTracking 使 widget 及时响应鼠标移动事件(MouseMoveEvent)。
  3. Qt::setMask() 函数对窗口进行部分区域遮掩来实现各种形状的窗口。[From Qt Doc:Causes only the pixels of the widget for which bitmap has a corresponding 1 bit to be visible. If the region includes pixels outside the rect() of the widget, window system controls in that area may or may not be visible, depending on the platform.]。
  4. Qt::ContextMenuPolicy 来配置窗口的右键菜单方案。[From Qt Doc:This enum type defines the various policies a widget can have with respect to showing a context menu.]。
  5. paintEvent() 回调函数来对窗口进行绘制。
  6. 重写 mousePressEvent() 和 mouseMoveEvent() 函数来实现窗口的拖拽移动(无边框窗口没有标题栏,默认拖拽窗体是没法移动窗口的)。


部分代码解释:

main.cpp-------------------开始

#include <QtGui/QApplication>
#include "shapedwidget.h"
#include <QPoint>
#include <QDebug>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    ShapedWidget *widget = new ShapedWidget;
    widget->show();


    return a.exec();
}

#include "shapedwidget.h"
#include <QtGui>
#include <assert.h>
/** public: */
ShapedWidget::ShapedWidget(QWidget *parent) :
    QWidget(parent, Qt::FramelessWindowHint)
{
    initData();
    initVisualComponents();
    setupContextMenu();
    setAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_TranslucentBackground);
}


ShapedWidget::~ShapedWidget()
{
    delete dragPos_;
    delete backgroundPixmap_;
}


/** private slots: */
void ShapedWidget::changeSkin()
{
    QAction* source = qobject_cast<QAction*>(sender());
    backgroundPixmap_->load(source->data().toString());
    resize(backgroundPixmap_->width(), backgroundPixmap_->height());
    clearMask();
    setMask(backgroundPixmap_->mask());
    update();
}


/** private: */
void ShapedWidget::initData()
{
    dragPos_ = new QPoint;
    backgroundPixmap_ = new QPixmap(":/images/yoda.png");
}


void ShapedWidget::initVisualComponents()
{
    this->setObjectName(tr("Shaped Widget"));
    this->setWindowTitle(tr("Shaped widget using setMask() function"));
    this->resize(backgroundPixmap_->width(), backgroundPixmap_->height());
    this->setMask(backgroundPixmap_->mask());
}


void ShapedWidget::setupContextMenu()
{
    setContextMenuPolicy(Qt::ActionsContextMenu);
    QAction *act_yoda = new QAction(QIcon(":/images/yoda.png"), tr("Yoda"), this);
    act_yoda->setData(tr(":/images/yoda.png"));
    QAction *act_rabbit = new QAction(QIcon(":/images/rabbit.png"), tr("Rabbit"), this);
    act_rabbit->setData(tr(":/images/rabbit.png"));
    QAction *act_cyclops = new QAction(QIcon(":/images/cyclops.png"), tr("Cyclops"), this);
    act_cyclops->setData(tr(":/images/cyclops.png"));
    QAction *act_star_beast = new QAction(QIcon(":/images/star_beast.png"), tr("Star Beast"), this);
    act_star_beast->setData(tr(":/images/star_beast.png"));


    QAction *act_quit = new QAction(tr("&Quit"), this);
    addAction(act_yoda);
    addAction(act_rabbit);
    addAction(act_cyclops);
    addAction(act_star_beast);
    addAction(act_quit);


    connect(act_yoda, SIGNAL(triggered()), this, SLOT(changeSkin()));
    connect(act_rabbit, SIGNAL(triggered()), this, SLOT(changeSkin()));
    connect(act_cyclops, SIGNAL(triggered()), this, SLOT(changeSkin()));
    connect(act_star_beast, SIGNAL(triggered()), this, SLOT(changeSkin()));
    connect(act_quit, SIGNAL(triggered()), this, SLOT(close()));
}




/** protected: */
void ShapedWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        *dragPos_ = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    }
}


void ShapedWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() & Qt::LeftButton)
    {
        move(event->globalPos() - *dragPos_);
        event->accept();
    }
}


void ShapedWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.fillRect(0, 0, backgroundPixmap_->width(), backgroundPixmap_->height(), *backgroundPixmap_);
}


#ifndef SHAPEDWIDGET_H
#define SHAPEDWIDGET_H


#include <QWidget>
class QPoint;
class QPixmap;
class ShapedWidget : public QWidget
{
    Q_OBJECT
public:
    explicit ShapedWidget(QWidget *parent = 0);    
    ~ShapedWidget();


private slots:
    void changeSkin();


protected:
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void paintEvent(QPaintEvent *);


private:
    void initData();
    void initVisualComponents();
    void setupContextMenu();


    QPoint*     dragPos_;
    QPixmap*    backgroundPixmap_;
};


#endif // SHAPEDWIDGET_H


Qt添加GIF图片实现自定义尺寸,你可以使用QImage和QPixmap类来处理图像。以下是一个简单的步骤说明: 1. 首先,确保已经包含所需的库头文件: ```cpp #include <QImageReader> #include <QPixmap> ``` 2. 加载GIF图片: ```cpp QImageReader gifReader("path_to_your_gif_file.gif"); ``` 请替换`"path_to_your_gif_file.gif"`为你的GIF图片的实际路径。 3. 如果你想支持透明度(对于GIF来说通常是有透明背景的),你需要确保GIF已经被正确地读取进来: ```cpp bool isAnimated = gifReader.is Animated(); if (isAnimated) { gifReader.setFormat(QImage::Format_Grayscale8); } else { gifReader.setFormat(QImage::Format_RGB32); } ``` 这一步非常重要,因为它设置了正确的像素格式以便正确显示GIF动画或静态图像。 4. 创建QPixmap对象,加载图像: ```cpp QPixmap pixmap; pixmap.loadFromImage(gifReader.read()); ``` 5. 调整大小: ```cpp // 假设你想调整到宽度和高度分别为newWidth和newHeight int newWidth = ...; // 用户指定的新宽度 int newHeight = ...; // 用户指定的新高度 QSize newSize(newWidth, newHeight); pixmap = pixmap.scaled(newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); ``` 这里使用了`scaled()`函数,它可以根据新的尺寸保持原始图像的比例,并进行平滑缩放。 6. 显示调整后的图像: ```cpp // 将调整后的QPixmap显示在一个 QLabel 或者 QWidget 上 yourWidget->setPixmap(pixmap); ``` 或者如果你直接想保存成新尺寸的图片,可以这样做: ```cpp QImage scaledImage = pixmap.toImage().scaled(newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); QFile destFile("output_scaled_image.png"); destFile.open(QIODevice::WriteOnly | QIODevice::Truncate); scaledImage.save(&destFile, "PNG"); destFile.close(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值