• Qt 鼠标悬浮按钮上出现浮窗效果


    操作:

      鼠标hover于Btn(or other widget),在指定位置显示想要的widget(或其他控件窗口)

      

    方法:重载以下几个api

      void paintEvent(QPaintEvent *);    //由于重载QPushbutton,normal, hover, pressed 按钮的状态需要重新设定
      void enterEvent(QEvent*event);    //鼠标进入的时候发送信号显示 diy widget
      void leaveEvent(QEvent*event);    //鼠标离开的时候发送信号隐藏 diy widget

    实现:

    类原型:

    //构造的时候需要将normal,hover, pressed的状态的图片,其他多余的为扩展,taskPix为任务图标类似QQ消息右上角的小红点,当然也可以自己画
    class MyBtn :public QPushButton {
      Q_OBJECT
      public:
      MyBtn(QWidget *parent, QString Text, QPixmap NorPix, QPixmap HoverTipsPix, QPixmap PressedTaskpix, QPixmap TaskPix);
      void init();
      void SetTaskCounts(int counts) { TaskCounts = counts; }
      void setCurrenPix(QPixmap pix) { CurrenPix = pix; }
      QTimer *pTimer;              //鼠标进入的时候,需要计时器100ms去将获取全局的鼠标位置发给需要显示的Widget


    protected:

      void paintEvent(QPaintEvent *);
      void enterEvent(QEvent*event);
      void leaveEvent(QEvent*event);
      bool eventFilter(QObject *obj, QEvent *event);     //可能要用到的过滤,

    private:
      int TaskCounts;
      QPixmap TaskPix;
      QPixmap NorPix;
      QPixmap HoverPix;
      QPixmap PressPix;
      QPixmap CurrenPix;

      QLabel *TipsLbl;     //需要显示的wigdet  其中构造的Text是放在这里
      QWidget *TipsWgt;    //需要显示的widget  
      QGridLayout *TipsLyt;
    public slots:
      void slot_showWgt(QPoint);
      void slot_updateTasks(int tasks);  //随着消息的变动更新 Taskcounts
    signals:
      void sig_showWgt(QPoint);     //发送消息通知要显示的widget
      void sig_hideWgt();       //发送消息通知要隐藏的widget
    };

    //构造这里初始化基本的数据
    MyBtn::MyBtn(QWidget *parent, QString Text, QPixmap NormalPix, QPixmap HoverTipsPix, QPixmap PressedTaskpix, QPixmap TasksPix) :
    QPushButton(parent)
    {
      init();

      NorPix = NormalPix;
      CurrenPix = NormalPix;
      HoverPix = HoverTipsPix;
      PressPix = PressedTaskpix;
      PressPix = NorPix;
      TaskPix = TasksPix;
      TipsLbl->setText(Text);
    }

    void MyBtn::init()
    {
      pTimer = new QTimer(this);
      TaskCounts = 0;

      TipsWgt = new QWidget;
      TipsLbl = new QLabel(TipsWgt);
      TipsLyt = new QGridLayout(TipsWgt);
      TipsLyt->addWidget(TipsLbl);


      TipsWgt->setWindowFlags(Qt::FramelessWindowHint);
      TipsWgt->setStyleSheet("background-color: transparent");
      TipsWgt->setAutoFillBackground(false);
      TipsWgt->setAttribute(Qt::WA_TranslucentBackground);
      TipsLbl->setStyleSheet("QLabel{border-image: url(:/SprintPlot/image/menuWhatis.png);color:white;}");
      TipsLbl->resize(80, 40);
      QPixmap pix(":/SprintPlot/image/menuWhatis.png");
      TipsLbl->setFixedSize(pix.size());
      TipsLbl->setAlignment(Qt::AlignCenter);
      TipsWgt->resize(80, 40);

      connect(this, &MyBtn::sig_showWgt, this, &MyBtn::slot_showWgt);
    }

    //绘画事件,即重点,把需要的效果重新画出来包括数据
    void MyBtn::paintEvent(QPaintEvent *event)
    {
      QPainter painter(this);

      painter.drawPixmap(QRect(this->rect().x() + this->width() / 4 - 3, this->rect().y()+10, 24, 24), CurrenPix);
      painter.setPen(Qt::white);
      if (TaskCounts > 99)
      {
        painter.drawPixmap(QRect(QPoint(this->x() + 20, 0), QSize(22, 22)), TaskPix);
        painter.drawText(QRect(QPoint(this->x() + 22, 2), QSize(18, 18)), Qt::AlignVCenter, QString::number(99) + "+");
      }
      else if (TaskCounts)

      {  
        painter.drawPixmap(QRect(QPoint(this->x()+ 20, 0), QSize(18, 18)), TaskPix);
        painter.drawText(QRect(QPoint(this->x() + 23, 3), QSize(12, 12)), Qt::AlignCenter, QString::number(TaskCounts));
      }
      else

      {
        update();
      }
    }

    //鼠标进入事件这里获取鼠标的坐标

    void MyBtn::enterEvent(QEvent *event)

    {
      CurrenPix = HoverPix;
      pTimer->stop();
      QPoint oPoint = this->mapToGlobal(QPoint(this->x() - 90, 0));
      emit sig_showWgt(oPoint);
    }

    //鼠标离开事件这里获取鼠标的全局坐标,注意需要转换成小部件的坐标的时候需要调整
    void MyBtn::leaveEvent(QEvent *event)
    {
      CurrenPix = NorPix;
      pTimer->start(100);
      TipsWgt->hide();
    }

     //事件筛选,根据自己需求自己筛吧

    bool MyBtn::eventFilter(QObject *target, QEvent *event)
    {

      if (target == this&&event->type() == QEvent::Enter)
      {
        CurrenPix = HoverPix;
      }
      else if (target == this&&event->type() == QEvent::MouseButtonPress)
      {
        CurrenPix = PressPix;
      }
      else if (target == this&&event->type() == QEvent::Leave)
      {
        CurrenPix = NorPix;
      }
      else

      {
        return true;
      }

      return QPushButton::eventFilter(target, event);
    }

    //在自定义位置显示自定义的Wgt

    void MyBtn::slot_showWgt(QPoint oPoint)
    {
      TipsWgt->move(oPoint);
      TipsWgt->show();
    }

    //更新Btn上的task数量
    void MyBtn::slot_updateTasks(int tasks)
    {
      TaskCounts = tasks;
    }

      效果截图:

        

    注意如果要鼠标进入浮窗不消失的话,需要自己实现这个浮窗,重写enterevent()判断全局鼠标位置

    然后在确定是不是要隐藏窗口,类似于QQ的资料卡。有问题可以博客私聊回复。

  • 相关阅读:
    Visio 2003 怎样将用例图画的更美观些
    Mvc项目实例 MvcMusicStore 四
    Mvc项目实例 MvcMusicStore 三
    Lock 会引起死锁吗
    进程和线程
    vb.net winform pos机并口打印机打印以及开钱箱。。。。
    .net winfrom 定义全局快捷键!
    WebBrowser中HTML的js与winform中其他的窗体调用。。。
    [转]确认网络环境3G/WIFI
    图片分割的代码
  • 原文地址:https://www.cnblogs.com/liuruoqian/p/12044571.html
Copyright © 2020-2023  润新知