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);
}
遗留问题