Qt实现一个类似qq的公共信息提示框(非模态,单例模式)

Qt实现一个类似qq的公共信息提示框

需求要点:
  • 单例模式
  • 半透明
  • 自动消失 与消失动画
实现思路:
  • 首先在实现单例模式的时候,需要注意处理的问题:私有化构造方法和复制方法。然后给出一个调用接口get_instance
  • widget支持半透明
问题处理:
// 如果这个QWidget直接show,是有背景色的,但是如果放到一个父Widget中时,它就没有了效果。添加如下代码后就可以了:
this->setAutoFillBackground(true);
//但结果表明没有效果 所以我直接使用的下面的方法
this->setWindowOpacity(0.8); 
//问题在于使用这个设置是整个窗口都透明了,其中的文字也被透明了。

 
//为什么这个地方一定要使用内联函数呢??
static info_widget_t* instance() { return self_; };  

//cpp中一定 要将静态变量实例化,不然会报错
info_widget_t* info_widget_t::self_ = NULL;

//无边窗口,并且不在任务栏显示程序多的窗口图标
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
代码实现:
//.hpp
#pragma once
#include <QToolButton>
#include <QLabel>
#include <QDialog>
#include <QApplication>
#include <QMainWindow>
#include <QStyle>
#include <QTimer>
#include <QObject>
#define msg_widget (static_cast<info_widget_t *>(info_widget_t::get_instance()))

class info_widget_t : public QWidget {
	Q_OBJECT
private:
	int main_toolbar_height = 90;
	QLabel* lbl_msg_info_;
	QToolButton* btn_close_;
	QTimer* tm_end_;
public:
	void show_info(QString);	
private:
	static info_widget_t* self_ ;
	info_widget_t();
	info_widget_t(const info_widget_t&) {}
	void hide();
	QPoint get_show_pos();
public:
	static info_widget_t* get_instance()
	{
		if (self_ == NULL) {
			self_ = new info_widget_t();
		}
		return self_;
	};
	static void release()
	{
		if (self_ != NULL)
		{
			delete self_;
			self_ = NULL;
		}
	}
Q_SIGNALS:
	void sig_show_info(QString);

private Q_SLOTS:
	void slot_show_info(QString);	
};
//.cpp
#include "info_widget.hpp"

info_widget_t* info_widget_t::self_ = NULL; //

info_widget_t::info_widget_t() {
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    this->resize(300, 20);

    QPalette palette;
    QColor color(51, 51, 51);
    palette.setBrush(this->backgroundRole(), color);
    this->setPalette(palette);
    this->setAutoFillBackground(true);
    this->setWindowOpacity(0.8);// 设置透明

    lbl_msg_info_ = new QLabel(this);
    lbl_msg_info_->setStyleSheet("color: #ffffff;");
    lbl_msg_info_->setGeometry(QRect(30, 0, width() - 60, height()));
    lbl_msg_info_->setAlignment(Qt::AlignCenter);

    tm_end_ = new QTimer();
    QObject::connect(tm_end_, &QTimer::timeout, [this]() {
        this->hide();
        });
    
    QObject::connect(this, SIGNAL(sig_show_info(QString)), this, SLOT(slot_show_info(QString)),Qt::QueuedConnection);
}

void info_widget_t::show_info(QString msg)
{
    emit sig_show_info(msg); //这个地方发信号是为了 避免非UI线程中穿件窗口报错
}

QPoint info_widget_t::get_show_pos()
{
    QMainWindow* mainWindow = nullptr;
    foreach(QWidget * w, qApp->topLevelWidgets()) {
        if (QMainWindow* mainWidget = qobject_cast<QMainWindow*>(w))
            mainWindow = mainWidget;
    }
    QPoint mainPoint = mainWindow->pos();

    int y = mainPoint.y() + main_toolbar_height;
    int x = mainPoint.x() + ((mainWindow->width() - this->width()) / 2) ;
    return QPoint(x,y);
}

void info_widget_t::hide() {
    std::double_t opacity = 0.8;
    //关闭的时候 通过透明度试下慢慢消失的效果
    for (int i = 0; i < 80; i++)
    {
        opacity = opacity - 0.01;
        this->setWindowOpacity(opacity);
        _sleep(10);
    }
    this->close();
}

void info_widget_t::slot_show_info(QString msg) {
    this->setWindowOpacity(0.8);
    lbl_msg_info_->setText(msg);
    this->move(get_show_pos());
    this->show();
    tm_end_->start(5000);
}
遗留问题
  • 多线程的安全问题还没有处理
  • 多消息的等待处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值