#include <QDateTime>
#include "QTimer"
#include "QAbstractItemModel"
class QVBoxLayout;
class GlodonTableView;
class QModelIndex;
class QLabel;
class QPropertyAnimation;
class ToolTipParam
{
public:
ToolTipParam() :
m_sizeMinTip(80, 60),
m_sizeMaxTip(0, 0),
m_sizeArrow(19, 9),
m_nRowHeight(20),
m_nTimeFadeOut(1000),
m_nTimeRemain(3000),
m_fontText(QFont("Microsoft YaHei", 12, QFont::Normal)),
m_colorText(Qt::black),
m_sizeIcon(16, 16),
m_pParentWidget(NULL),
m_strIconPath("xxx.png"),
m_strText(QString(""))
{
}
ToolTipParam & operator = (const ToolTipParam & param)
{
m_strIconPath = param.m_strIconPath;
m_nRowHeight = param.m_nRowHeight;
m_strText = param.m_strText;
m_fontText = param.m_fontText;
m_colorText = param.m_colorText;
m_nTimeRemain = param.m_nTimeRemain;
m_nTimeFadeOut = param.m_nTimeFadeOut;
m_sizeArrow = param.m_sizeArrow;
m_sizeMinTip = param.m_sizeMinTip;
m_sizeMaxTip = param.m_sizeMaxTip;
m_sizeIcon = param.m_sizeIcon;
m_pParentWidget = param.m_pParentWidget;
return *this;
}
QString m_strIconPath; // 图标路径
QSize m_sizeIcon; // 图标尺寸
QString m_strText; // 文字
QFont m_fontText; // 字体
QColor m_colorText; //文字颜色
int m_nRowHeight; // 文字行高
int m_nTimeRemain; // 停留时间(毫秒)
int m_nTimeFadeOut; // 淡出时间(毫秒)
QSize m_sizeArrow; // layout的外边距
QSize m_sizeMinTip; // tip控件的大小
QSize m_sizeMaxTip; // tip的换行大小
QWidget *m_pParentWidget; // 被指向的widget(父窗体)
};
class ToolTipWidget : public QWidget
{
Q_OBJECT
public:
static void showToolTip(QWidget * pParent, const QString &strShowText); //使用时直接调用这个接口就可以
static void tableViewShowToolTip(QWidget *pTableView, const QModelIndex& oIndex, const QString& strShowText, bool bIsTableView = false); //tableView可以直接调用该静态方法
static void closeTip(QWidget * pParent = nullptr); //关闭提示
virtual void ImmediateCloseTip(); // 立即关闭,并销毁
virtual QPoint calcPosOfpParentWidget(); //
bool isStartFadeOut(); // 判断是否开始渐变退出
void tipShowLocal(); //tip出现的位置,父窗体的上方
void startTimer(void); //
void initUI();
void initConnect();
QPainterPath buildRoundRectTip(); //画圆角提示框
void stopTime();
~ToolTipWidget();
protected:
virtual void showEvent(QShowEvent * pEvent);
virtual void paintEvent(QPaintEvent * pEvent);
virtual void mouseReleaseEvent(QMouseEvent *pEvent);
virtual bool eventFilter(QObject *pObj, QEvent *pEvent);
virtual void enterEvent(QEvent *pEvent);
virtual void leaveEvent(QEvent *pEvent);
private:
explicit ToolTipWidget(ToolTipParam & oTipParam, QWidget *pParent = nullptr, const QModelIndex oIndex = QModelIndex(), bool bIsShowTotalQty = false);
protected slots:
void slotCloseTimer();
void slotFadeout();
void slotMoveTimer();
private:
static ToolTipParam m_TipParam;
QLabel *m_pLabelIco; // 图标
QLabel *m_pLabelText; // 内容文字区
QVBoxLayout *m_pLayoutLeft;
QVBoxLayout *m_pLayoutRight;
QTimer *m_pTimerClose; // 关闭定时器
QTimer *m_pTimerMovePos; // 移动定时器
QPropertyAnimation *m_pAnimFadeOut; // 窗体逐渐消失效果
QPoint m_ptThisCenter;
bool m_bStartFadeOut;
static QDateTime m_CloseDataTime;
static QPointer<ToolTipWidget> m_QPointerTip;
QModelIndex m_oIndex;
bool m_bTableViewShow;
};
#include "QWidget"
#include "QRect"
#include "QBoxLayout"
#include "QLabel"
#include "QPropertyAnimation"
#include "QPainter"
#include "QLineEdit"
#include "QPointer"
#include "QApplication"
#include "QAbstractItemModel"
static const QString s_strLabelText = QString("<p style=\"line-height:%1px\">%2</p>");
QPointer<ToolTipWidget> ToolTipWidget::m_QPointerTip;
QDateTime ToolTipWidget::m_CloseDataTime = QDateTime::fromTime_t(0);
ToolTipParam ToolTipWidget::m_TipParam;
ToolTipWidget::ToolTipWidget(ToolTipParam & oTipParam, QWidget *pParent /*= nullptr*/,
const QModelIndex oIndex /*= QModelIndex()*/
, bool bIsShowTotalQty /*= false*/) :
m_pLabelIco(NULL),
m_pLabelText(NULL),
m_pTimerClose(NULL),
m_pAnimFadeOut(NULL),
m_bStartFadeOut(false),
m_oIndex(oIndex),
m_bTableViewShow(bIsShowTotalQty),
QWidget(pParent)
{
m_TipParam = oTipParam;
initUI();
installEventFilter(pParent);
initConnect();
}
ToolTipWidget::~ToolTipWidget()
{
}
void ToolTipWidget::mouseReleaseEvent(QMouseEvent *pEvent)
{
//点tip就直接让它关了
if (pEvent->button() == Qt::LeftButton)
{
closeTip();
}
}
void ToolTipWidget::paintEvent(QPaintEvent * pEvent)
{
QWidget::paintEvent(pEvent);
if (!m_TipParam.m_pParentWidget)
return;
m_ptThisCenter = m_TipParam.m_pParentWidget->mapToGlobal(m_TipParam.m_pParentWidget->rect().center());
QPainterPath path;
// 画圆角tip
path = this->buildRoundRectTip();
QPainter * painter = new QPainter(this);
painter->begin(this);
painter->setRenderHint(QPainter::Antialiasing); // 圆角处反锯齿,让其圆滑;
if (!m_bTableViewShow)
{
QColor c_CurColor = QColor(QString("255 255 255 255"));
painter->setPen(QPen(c_CurColor, 1, Qt::SolidLine));
painter->fillPath(path, QBrush(c_CurColor));
}
else
{
this->move(calcPosOfpParentWidget());
painter->setPen(QPen(QColor(199, 199, 199), 1, Qt::SolidLine));
painter->fillPath(path, QBrush(QColor(231, 231, 231)));
}
painter->drawPath(path);
painter->end();
}
bool ToolTipWidget::eventFilter(QObject *pObj, QEvent *pEvent)
{
auto eType = pEvent->type();
if (eType == QEvent::Hide)
{
this->hide();
}
if (eType == QEvent::Resize)
{
tipShowLocal();
}
if (eType == QEvent::Move)
{
tipShowLocal();
}
// 错误提示所在的控件隐藏时,错误提示直接销毁
if (pObj == m_TipParam.m_pParentWidget)
{
if (pEvent->type() == QEvent::Hide)
ImmediateCloseTip();
}
return QWidget::eventFilter(pObj, pEvent);
}
void ToolTipWidget::enterEvent(QEvent *pEvent)
{
if (m_pTimerClose) //鼠标悬停停止计时,窗体不消失
{
m_pTimerClose->stop();
}
QWidget::enterEvent(pEvent);
}
void ToolTipWidget::leaveEvent(QEvent *pEvent)
{
if (m_pTimerClose) //鼠标离开重新计时
{
m_pTimerClose->start(m_TipParam.m_nTimeRemain);
}
QWidget::leaveEvent(pEvent);
}
void ToolTipWidget::showEvent(QShowEvent * pEvent)
{
if (!m_TipParam.m_pParentWidget)
return;
if (!m_TipParam.m_sizeMinTip.isEmpty())
this->setMinimumSize(m_TipParam.m_sizeMinTip);
if (!m_TipParam.m_sizeMaxTip.isEmpty())
this->setMaximumSize(m_TipParam.m_sizeMaxTip);
QString strTemp = m_TipParam.m_strText;
QString sBody = s_strLabelText.arg(m_TipParam.m_nRowHeight).arg(m_TipParam.m_strText);
m_pLabelText->setText(sBody);
int nTitleWidth = m_pLabelText->fontMetrics().width(strTemp);
if (nTitleWidth < (this->maximumWidth() - 100))
{
m_pLayoutRight->setContentsMargins(0, 4, 15, 12);
m_pLabelText->setWordWrap(false);
m_pLabelText->adjustSize();
if (!m_bTableViewShow)
{
this->setFixedSize(m_pLabelText->width(), m_pLabelText->height() );
}
else
{
this->setFixedSize(m_pLabelText->width() , m_pLabelText->height());
}
}
else
{
m_pLayoutLeft->setContentsMargins(0, 2, 0, 0);
m_pLayoutRight->setContentsMargins(0, 4, 15, 12);
m_pLabelText->setMinimumWidth(this->maximumWidth());
this->setMinimumWidth(this->maximumWidth() );
m_pLabelText->adjustSize();
if (m_pLabelText->size().height() > 60)
{
adjustSize();
}
else
{
if (!m_bTableViewShow)
{
this->setFixedSize(m_pLabelText->width(), m_pLabelText->height());
}
else
{
this->setFixedSize(m_pLabelText->width(), m_pLabelText->height());
}
}
}
if (!m_bTableViewShow)
{
QPixmap pixIco;
pixIco.load(m_TipParam.m_strIconPath);
if (!m_TipParam.m_sizeIcon.isEmpty())
{
pixIco = pixIco.scaled(m_TipParam.m_sizeIcon.width(), m_TipParam.m_sizeIcon.height(), Qt::KeepAspectRatio);
}
m_pLabelIco->setPixmap(pixIco);
}
QWidget::showEvent(pEvent);
}
QPainterPath ToolTipWidget::buildRoundRectTip()
{
QPainterPath oPath;
if (!m_TipParam.m_sizeArrow.isValid() || !m_TipParam.m_pParentWidget)
{
return oPath;
}
int nHeight = m_TipParam.m_sizeArrow.height();
QRect oOuterRect = this->rect();
QRect oInnerRect;
if (!m_bTableViewShow)
{
oInnerRect = oOuterRect - QMargins(nHeight, nHeight, nHeight, nHeight);
oPath.addRoundedRect(oInnerRect, 5, 5); // 添加圆角矩形
}
else
{
oInnerRect = oOuterRect - QMargins(nHeight, nHeight, nHeight, nHeight + 10);
oPath.addRoundedRect(oInnerRect, 0, 0);
}
return oPath;
}
void ToolTipWidget::stopTime()
{
if (m_pTimerClose)
m_pTimerClose->stop();
if (m_pTimerMovePos)
m_pTimerMovePos->stop();
m_CloseDataTime = QDateTime::currentDateTime();
this->close();
this->deleteLater();
}
void ToolTipWidget::slotCloseTimer()
{
m_pTimerClose->stop();
m_bStartFadeOut = true;
m_pAnimFadeOut->start();
}
void ToolTipWidget::slotMoveTimer()
{
QPoint ptThisCenter = m_TipParam.m_pParentWidget->mapToGlobal(m_TipParam.m_pParentWidget->rect().center());
if (ptThisCenter != m_ptThisCenter)
{
stopTime();
}
}
void ToolTipWidget::slotFadeout()
{
if (m_pTimerMovePos)
m_pTimerMovePos->stop();
this->close();
this->deleteLater();
}
void ToolTipWidget::ImmediateCloseTip()
{
this->stopTime();
}
QPoint ToolTipWidget::calcPosOfpParentWidget()
{
QPoint pt(0, 0);
if (!m_TipParam.m_pParentWidget)
return pt;
int nCounWidth = m_TipParam.m_pParentWidget->width()*0.5;//当前单元格的列宽
int nTooltipHeight = -this->height()* 0.5 ; //提示框的高度
QPoint ptGlobalOwnerCenter = m_TipParam.m_pParentWidget->mapToGlobal(m_TipParam.m_pParentWidget->rect().center());
pt = QPoint(ptGlobalOwnerCenter.x(), ptGlobalOwnerCenter.y());
pt += QPoint(nCounWidth, nTooltipHeight);
return pt;
}
void ToolTipWidget::showToolTip(QWidget * pParentWidget, const QString &strText)
{
ToolTipWidget * pTip = NULL;
assert(pParentWidget);
if (!pParentWidget)
return;
if (!m_QPointerTip.isNull() && m_QPointerTip.data() && pParentWidget == m_QPointerTip.data()->parent()
&& strText.compare(m_TipParam.m_strText) == 0
&& !m_QPointerTip->isStartFadeOut())
{
//窗体还没有退出直接使用原来的
return;
}
__int64 llDuration = m_CloseDataTime.msecsTo(QDateTime::currentDateTime()); //第一次与第二次弹出窗体的间隔时间
if (llDuration < 500)
{
pTip = ToolTipWidget::m_QPointerTip;
return;
}
if (!ToolTipWidget::m_QPointerTip.isNull())
{
ToolTipWidget::m_QPointerTip->ImmediateCloseTip();
}
ToolTipParam param = m_TipParam;
param.m_pParentWidget = pParentWidget;
param.m_strText = strText;
pTip = new ToolTipWidget(param, pParentWidget);
ToolTipWidget::m_QPointerTip = pTip;
pTip->tipShowLocal();
pTip->show();
pTip->startTimer(); //show之后启动定时器
}
void ToolTipWidget::startTimer(void)
{
if (!m_TipParam.m_pParentWidget)
{
return;
}
m_pAnimFadeOut->setDuration(m_TipParam.m_nTimeFadeOut);
if (m_pTimerClose)
{
m_pTimerClose->start(m_TipParam.m_nTimeRemain);
}
if (m_pTimerMovePos)
{
m_pTimerMovePos->start();
}
}
//对应的单元格
void ToolTipWidget::tableViewShowToolTip(QWidget *editor, const QModelIndex& oIndex, const QString& strTotalQtyExpr, bool bIsShowTotalQtyExpr/*=false*/)
{
if (editor == nullptr || !oIndex.isValid())
return;
ToolTipWidget * pTip = NULL;
if (!m_QPointerTip.isNull() && m_QPointerTip.data() && editor == m_QPointerTip.data()->parent()
&& strTotalQtyExpr.compare(m_TipParam.m_strText) == 0
&& !m_QPointerTip->isStartFadeOut())
{
//文本相同、父窗体相同、窗体还没有退出直接使用原来的。
return;
}
__int64 llDuration = m_CloseDataTime.msecsTo(QDateTime::currentDateTime()); //第一次与第二次弹出窗体的间隔时间
if (llDuration < 100)
{
pTip = ToolTipWidget::m_QPointerTip;
return;
}
if (!ToolTipWidget::m_QPointerTip.isNull())
{
ToolTipWidget::m_QPointerTip->ImmediateCloseTip();
}
ToolTipParam param = m_TipParam;
param.m_colorText = QColor(100, 100, 100, 0);
param.m_pParentWidget = editor;
param.m_strText = strTotalQtyExpr;
pTip = new ToolTipWidget(param, editor, oIndex, bIsShowTotalQtyExpr);
ToolTipWidget::m_QPointerTip = pTip;
pTip->show();
pTip->startTimer(); //show之后启动定时器
}
void ToolTipWidget::closeTip(QWidget * pParent)
{
if (!ToolTipWidget::m_QPointerTip.isNull())
{
//传进来的父不为空,且不是当前气泡的父时,不关闭当前气泡
if (pParent && pParent != ToolTipWidget::m_QPointerTip.data()->parent())
return;
ToolTipWidget::m_QPointerTip->ImmediateCloseTip();
}
}
void ToolTipWidget::tipShowLocal()
{
QWidget* pParentWidget = this->parentWidget();
QSize oSzParentWidget = pParentWidget->size();
int nParentWidgetX = oSzParentWidget.width();
int nParentWidgetY = oSzParentWidget.height();
QPoint oPtRightBottomParentWidget = pParentWidget->mapToGlobal(QPoint(nParentWidgetX, nParentWidgetY));
//获取父窗体的左下角坐标
QPoint oPtLeftBottom = oPtRightBottomParentWidget - QPoint(oSzParentWidget.width(), 0);
int nLeftBottomX = oPtLeftBottom.x();
int nLeftBottomY = oPtLeftBottom.y();
//移动到父窗体的顶上中部的位置
int nTipWidth = this->width();
nLeftBottomX = nLeftBottomX + nParentWidgetX / 2 - nTipWidth;
nLeftBottomY = nLeftBottomY - nParentWidgetY - 2;
this->move(nLeftBottomX, nLeftBottomY);
}
bool ToolTipWidget::isStartFadeOut()
{
return m_bStartFadeOut;
}
void ToolTipWidget::initUI()
{
this->setMaximumHeight(25);
this->setWindowFlags(Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint | Qt::ToolTip);
this->setAttribute(Qt::WA_TranslucentBackground);
QVBoxLayout * layoutMain = new QVBoxLayout();
layoutMain->setSpacing(0);
if (m_bTableViewShow)
{
layoutMain->setContentsMargins(m_TipParam.m_sizeArrow.height(),
m_TipParam.m_sizeArrow.height(),
m_TipParam.m_sizeArrow.height(),
m_TipParam.m_sizeArrow.height());
this->setLayout(layoutMain);
}
else
{
layoutMain->setContentsMargins(m_TipParam.m_sizeArrow.height() + 12,
m_TipParam.m_sizeArrow.height() + 8,
m_TipParam.m_sizeArrow.height() + 8,
m_TipParam.m_sizeArrow.height());
}
this->setLayout(layoutMain);
QHBoxLayout * layoutContent = new QHBoxLayout();
layoutContent->setSpacing(6);
layoutMain->addLayout(layoutContent);
m_pLayoutLeft = new QVBoxLayout();
m_pLabelIco = new QLabel(this);
m_pLayoutLeft->setContentsMargins(0, 2, 0, 0);
m_pLayoutLeft->addWidget(m_pLabelIco);
m_pLayoutLeft->addStretch();
m_pLayoutRight = new QVBoxLayout();
m_pLayoutRight->setContentsMargins(0, 0, 15, 0);
m_pLayoutRight->setSpacing(0);
m_pLayoutRight->addSpacing(-6);
m_pLabelText = new QLabel();
m_pLabelText->setObjectName(QStringLiteral("LabelText"));
m_pLabelText->adjustSize();
QPalette pa;
pa.setColor(QPalette::WindowText, m_TipParam.m_colorText);
m_pLabelText->setPalette(pa);
m_pLabelText->setWordWrap(true);
if (!m_bTableViewShow)
m_pLabelText->setAlignment(Qt::AlignTop);
else
m_pLabelText->setAlignment(Qt::AlignCenter);
m_pLabelText->setAttribute(Qt::WA_TransparentForMouseEvents, true);
m_pLayoutRight->addWidget(m_pLabelText);
layoutContent->addLayout(m_pLayoutLeft, 0);
layoutContent->addLayout(m_pLayoutRight, 1);
// 关闭定时器设置
m_pTimerClose = new QTimer(this);
m_pTimerMovePos = new QTimer(this);
m_pTimerMovePos->setInterval(200);
// 渐隐效果动画设置
m_pAnimFadeOut = new QPropertyAnimation(this, "windowOpacity");
m_pAnimFadeOut->setStartValue(1);
m_pAnimFadeOut->setEndValue(0);
m_pAnimFadeOut->setEasingCurve(QEasingCurve::Linear);
}
void ToolTipWidget::initConnect()
{
connect(m_pTimerClose, SIGNAL(timeout()), this, SLOT(slotCloseTimer()));
connect(m_pTimerMovePos, SIGNAL(timeout()), this, SLOT(slotMoveTimer()));
connect(m_pAnimFadeOut, SIGNAL(finished()), this, SLOT(slotFadeout()));
}
周五一个分部副总过生日,中午来让我们去分蛋糕,行政主任说这算团体活动赶紧去。蛋糕打破了我的认知,他们说够几百人吃,我心想那要多大啊的蛋糕,要几层啊,然后贫穷限制 我的想象,是那种小蛋糕拼成的大蛋糕,精致的小盘子小叉子,羡慕emmm。没拍照都是领导没拍照应该也不让拍照,就拍了个小的,忽略我的桌上掉的眼睫毛,和被吃了一口破坏的精致。 本来以为晚上还有活动呢,想多了,我只配加班。工作时光:上午运行爬虫,优化爬虫,找爬虫bug,自己写的爬虫真好,能摸鱼啊哈。逃离嵌套数据预防秃头。能拖一天是一天,初级
urllib库urllib库是Python中一个最基本的网络请求的库。它可以模拟浏览器的行为发送请求(都是这样),从而获取返回的数据urllib.request在Python3的urllib库当中,所有和网络请求相关的方法都被集成到了urllib.request模块下#基本使用from urllib importrequestresp= request.urlopen("URL")print(re...
注:本文的观点出自作者本人,并不代表任何公司的立场。科技公司一直都在努力弄清楚如何才能让员工愉快地工作。然而,这并不是一件容易的事。根据我自己的经历,我接触的技术人员平均在一家公司供职的时长为18个月。每当我询问他们的离职原因时,得到的答案通常都是那么几个。他们之所以不考虑离职,我总结出了六个我认为最重要的原因。当然,薪水很重要,但如果无法满足以下情况,仅仅靠薪水也无法留住员工。...
EXCEL VBA编程(excel办公高手必经之路) Office培训讲师,...
虎牙视频站里多数是游戏解说、游戏攻略等视频,对于做游戏视频资源的网站可以从虎牙视频站里调用视频,下面分享虎牙视频PHP解析调用代码,把代码复制一个php文件里,保存后上传到主机空间里调用。vxt天浩博客调用说明:例如http://v.huya.com/play/2865447.html这个播放页的ID为2865447,使用PHP解析调用方法为http://你的域名/huya.php?id=2865...
Map(映射)是一种可迭代的键值对(key/value)结构。所有的值都可以通过键来获取。Map 中的键都是唯一的。Map 也叫哈希表(Hash tables)。Map 有两种类型,可变与不可变,区别在于可变对象可以修改它,而不可变对象不可以。默认情况下 Scala 使用不可变 Map。如果你需要使用可变集合,你需要显式的引入 import scala.collection.mutabl...
上代码:import { defineConfig } from 'vite';import vue from '@vitejs/plugin-vue';import { resolve } from 'path';// https://vitejs.dev/config/export default defineConfig({ server: { port: 9090, strictPort: true, // 严格端口 true:如果端口已被使用,则直接退出,而不会再
背景某些情况下(如在三维绘图),需要绘制系统坐标系。首先来看一下三维迪卡尔坐标系的组成:坐标原点(0,0,0),带箭头的坐标轴,坐标轴标签。因此在绘制坐标系,需要绘制这些元素。Mathematica实现coordinateSystem3D = { {RGBColor[{1, 0, 0}], Arrowheads[0.05], Arrow[Tube[{{0, 0, 0}, {1, 0,...
1. TPS(每秒传输的事物处理个数)概念:即服务器每秒处理的事务数。TPS是软件测试结果的测量单位。TPS包括一条消息入和一条消息出,加上一次用户数据库访问。业务 TPS = CAPS × 每个呼叫平均TPS一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。一般的,评价系统...
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中使用!=或 3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置
当注册一些用户名时需要不重复的字符串,这时我们急需要一个随机生成字符串确保唯一性。填写如下图所示:名称介绍:Random string length:字符串随机数长度;Chars to use for random string generation:生成字符串随机数的字符集,生成的字符串中的字符从这个字段中选取;将生成函数字符串复制到请求参数中,执行请求查看结果。...
keepalived