QT之事件过滤器的应用

最近自写一个自用的软件,随便玩玩,现在将一个经验分享给大家。

1 效果预览

2 实现

1)鼠标滑入边框高亮

原理:当鼠标移入时设置焦点并绘制边框,当鼠标移出时移除焦点,并绘制透明边框。

方法:利用事件过滤器,监听鼠标移入与移出事件来设置焦点;利用paintevent绘制边框

a) 注册事件过滤器

BirthDayInfoFrm::BirthDayInfoFrm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::BirthDayInfoFrm)
{
    ui->setupUi(this);

    this->setFocusPolicy(Qt::ClickFocus);
    installEventFilter(this);
}

b)实现事件过滤方法

protected:
    bool eventFilter(QObject *watched, QEvent *event);
bool BirthDayInfoFrm::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::Enter)
    {
        //设置焦点
        setFocus();
    }
    else if(event->type() == QEvent::Leave)
    {
        //移除焦点
        focusNextPrevChild(true);
    }

    return QWidget::eventFilter(watched, event);
}

c) 利用paintevent绘制边框

protected:
    bool eventFilter(QObject *watched, QEvent *event);
    void paintEvent(QPaintEvent *);
    void drawBorder(QPainter *painter);
void BirthDayInfoFrm::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);
    //绘制边框
    drawBorder(&painter);
}

void BirthDayInfoFrm::drawBorder(QPainter *painter)
{
    painter->save();
    QPen pen;
    pen.setWidth(2);
    pen.setColor(hasFocus() ? QColor(0, 255, 200) : QColor(255, 255, 255, 0));
    painter->setPen(pen);
    painter->drawRect(rect());
    painter->restore();
}

注意:在界面中的布局控制中 ,上、下、左、右的边距不要设置为0

2)实现图形头像

将图片绘制成图形到QPixmap,现将QPixmap设置到QLabel,设置QLabel的鼠标悬浮样式及QLabel边框样式。

a)QLabel设置圆形图片

void BirthDayInfoFrm::setPic()
{
    ui->picLabel->setPixmap(PixmapToRoundV2(qApp->applicationDirPath() + "/pic/yz.jpg", (ui->picLabel->width() / 2) -  2));
}

QPixmap BirthDayInfoFrm::PixmapToRound(QString src, int radius)
{
    QPixmap pixmapa(src);
    QPixmap pixmap(radius * 2, radius * 2);
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    QPainterPath path;
    path.addEllipse(1, 1, radius * 2, radius * 2);
    painter.setClipPath(path);
    painter.drawPixmap(1, 1, radius * 2, radius * 2, pixmapa);
    return pixmap;
}

b)QLabel设置圆形边框样式及悬浮高亮

void BirthDayInfoFrm::setPic()
{
    ui->picLabel->setPixmap(PixmapToRoundV2(qApp->applicationDirPath() + "/pic/yz.jpg", (ui->picLabel->width() / 2) -  2));
    ui->picLabel->setStyleSheet(QString("QLabel:hover{ "
                                        "border-width: 2px; "
                                        "border-style: solid; "
                                        "border-radius:%0px; "
                                        "border-color:rgb(0, 177, 252); }").arg((ui->picLabel->width() / 2) -  2)
                                + QString("QLabel{"
                                          "border-width: 2px 2px 2px 2px;"
                                          "border-style: solid;"
                                          "border-color: rgb(255,255,255);"
                                          "border-radius:%0px;}").arg((ui->picLabel->width() / 2) -  2));
}

3)实现控件内的子控件的响应点击事件方法

a)子控件注册事件过滤器

ui->picLabel->installEventFilter(this);
ui->labName->installEventFilter(this);
ui->labClose->installEventFilter(this);

b)在事件过滤器中实现事件响应

bool BirthDayInfoFrm::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonDblClick)
    {
        if( watched == ui->picLabel)
        {
            qDebug() << "pic......";
        }
        else if( watched == ui->labName)
        {
            qDebug() << "name......";
        }

    }
    if (event->type() == QEvent::MouseButtonPress)
    {
        if( watched == ui->labClose)
        {
            qDebug() << "close......";
        }
    }

    if(event->type() == QEvent::Enter)
    {
        setFocus();
    }
    else if(event->type() == QEvent::Leave)
    {
        focusNextPrevChild(true);
    }

    return QWidget::eventFilter(watched, event);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值