Оторвите вкладки в QT - PullRequest
       17

Оторвите вкладки в QT

0 голосов
/ 01 февраля 2020

Я пытаюсь реализовать отрывную вкладку в QT. Я хочу, чтобы это работало как меню, например. Я хочу, чтобы он плавал или стыковался с исходным окном. Я могу оторваться, но не могу найти событие, когда вкладка возвращается в контейнер вкладок. Это мой код:


class TearOffTabWidget : public QTabWidget {
    Q_OBJECT
public:
    explicit TearOffTabWidget(QWidget *parent);

    // For tear off.
    bool    eventFilter(QObject *watched, QEvent *event) override;

private:
    bool    isDragging() const { return _currentlyDragging != nullptr; }
    void    tearOff(QPoint location);
    void    drag(QPoint location);
    void    drop(QPoint location);

private:
    QPoint          _pressDownLocation;
    QWidget*  _currentlyDragging = nullptr;
};


TearOffTabWidget::TearOffTabWidget(QWidget *parent) :
    QTabWidget(parent) {
    tabBar()->installEventFilter(this);
}


bool TearOffTabWidget::eventFilter(QObject *watched, QEvent * event) {

    // This supports the tear off.
    QMouseEvent *e = dynamic_cast<QMouseEvent *>(event);
    if (watched == tabBar() && e) {
        // This supports the tear off.
        if (isDragging()) {
            if (event->type() == QEvent::MouseButtonRelease) {
                drop(e->pos());
            } else if (event->type() == QEvent::MouseMove) {
                drag(e->pos());
            }
            return false;
        } else if (e->buttons() & Qt::LeftButton) {
            if (event->type() == QEvent::MouseButtonPress) {
                _pressDownLocation = e->pos();
                return false;
            } else if (event->type() == QEvent::MouseMove) {
                auto currentLocation = e->pos();

                // At a certain radius, we tear off.
                int dx = currentLocation.x() - _pressDownLocation.x();
                int dy = currentLocation.y() - _pressDownLocation.y();
                int d2 = dx * dx + dy * dy;
                if (d2 > 400) {
                    tearOff(currentLocation);
                    return false;
                }
            }
        }
    }
    return QTabWidget::eventFilter(watched, event);
}


void    TearOffTabWidget::tearOff(QPoint location) {
    _currentlyDragging = dynamic_cast<QWidget*>(currentWidget());
    if (_currentlyDragging) {

        auto name = tabText(currentIndex());
        _currentlyDragging->setParent(0);
        _currentlyDragging->setWindowTitle(name);
        drag(location); // Set location
        _currentlyDragging->show();
    }
}


void    TearOffTabWidget::drag(QPoint location) {
    _currentlyDragging->move(mapToGlobal(location));
}


void    TearOffTabWidget::drop(QPoint location) {
    _currentlyDragging = nullptr;
}

Я пробовал несколько разных подходов:

В поисках MouseButtonPress, кажется, что это всегда происходит при закреплении окна под мышью. В поисках входа и выхода, но опять же, я не получаю их до тех пор, пока окно, являющееся доком, не будет освобождено, и мышь не выйдет из окна и над моим контейнером вкладок.

Я знаю, что QDockWidget делает аналогичную вещь, и поэтому сделать слезу панели инструментов и меню, чтобы это было возможно. У кого-нибудь есть понимание? Заранее большое спасибо.

...