在鼠标位置显示工具提示并在右上角显示图例

Show tooltip at mouse position and show legend on top-right corner

下面的玩具问题显示了两个选项卡,每个选项卡包含一个 QGridLayout,其中一个单元格上有一个 ScrollArea,它又包含一个自定义的 QLabel (MyLabel)。当用户将鼠标移到自定义 QLabel 上时,工具提示会显示几秒钟。

test.pro

QT += core gui widgets

CONFIG += c++17
CONFIG += debug
QMAKE_CXXFLAGS += -std=c++17

SOURCES += \
    test.cpp

QMAKE_CLEAN += $$TARGET Makefile

HEADERS += \
    mywidget.h

test.cpp

#include "mywidget.h"
#include <QApplication>
#include <QtGui>
#include <QtCore>
#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyMainWindow myMainWindow;
    myMainWindow.show();
    return a.exec();
}

mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QDebug>
#include <QWidget>
#include <QMdiArea>
#include <QMainWindow>
#include <QScrollArea>
#include <QLabel>
#include <QGridLayout>
#include <QMouseEvent>
#include <QToolTip>

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    MyLabel(QWidget *parent=nullptr, const QString &name="")
        : QLabel(parent), m_name(name)
    {
        resize(1800, 1200);
        setMouseTracking(true);
    }
private:
    void mouseMoveEvent(QMouseEvent *ev) override {
        QToolTip::showText(
                    ev->globalPosition().toPoint()
                    , m_name + ": " + QString::number(ev->pos().x()) + ", " + QString::number(ev->pos().y())
                );

        QLabel::mouseMoveEvent(ev);
    }
private:
    QString m_name;
};

class MyWidget : public QWidget
{
    Q_OBJECT
public:
    MyWidget(QWidget* parent = nullptr, const QString &name="")
        : QWidget(parent), m_name(name)
    {
        setWindowTitle(name);
        m_gridLayout = new QGridLayout(this);
        this->setLayout(m_gridLayout);

        // layout col 1
        m_gridLayout->addWidget(new QLabel("smaller label", this), 0, 0);

        // layout col 2
        m_scrollArea = new QScrollArea(this);
        MyLabel *label = new MyLabel(this, m_name);
        m_scrollArea->setWidget(label);
        m_gridLayout->addWidget(m_scrollArea, 0, 1);
    }

private:
    QString m_name;
    QGridLayout *m_gridLayout;
    QScrollArea *m_scrollArea;
};

class MyMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MyMainWindow(QWidget* parent = nullptr)
        : QMainWindow(parent)
    {
        m_mdiArea = new QMdiArea(this);
        this->setCentralWidget(m_mdiArea);

        MyWidget *myWidget1 = new MyWidget(this, "widget 1");
        m_mdiArea->addSubWindow(myWidget1);

        MyWidget *myWidget2 = new MyWidget(this, "widget 2");
        m_mdiArea->addSubWindow(myWidget2);

        m_mdiArea->setViewMode(QMdiArea::ViewMode::TabbedView);
    }

private:
    QMdiArea *m_mdiArea;
};

#endif // MYWIDGET_H

这是我正在努力解决的两个问题:

  1. 当我通过 Ctrl+Tab 在这两个选项卡之间切换时,如何在不移动鼠标的情况下显示工具提示?在我的实际问题中,我使用工具提示在鼠标点处显示有关数据的信息。
  2. 是否可以在QScollArea视口的右上角显示一些图例,而不考虑滚动条的位置?我正在尝试使用 paintEvent,但很难根据 scoll 条调整位置。

光标位置可以通过QCursor::pos()获取,所以这两个问题都可以通过在paintEvent中使用QCuros::pos()来解决。 paintEvent 不像 mouseMoveEvent 那样直接提供光标位置,这让我很困惑。