Как закрепить вкладку в Qt - PullRequest
1 голос
/ 29 января 2020

Можно ли закрепить вкладку с помощью Qt?

Я хочу, чтобы вкладка всегда оставалась на месте (индекс 0), но при этом могла перемещать другие вкладки.

Пока я пытался прослушать QTabBar :: tabMoved и отменить ход, но это слишком поздно. Я не хочу, чтобы он даже пытался двигаться.

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

1 Ответ

0 голосов
/ 29 января 2020

Я никогда не находил хороший способ сделать это. Но я использовал тот факт, что вы можете хранить необработанные данные в QTabBar для закрепления вкладок и отмены перемещения, если это была закрепленная вкладка. Это не идеально, и у меня все еще есть какое-то уродливое поведение, но я также не хотел использовать события мыши.

Сначала создайте структуру для хранения текущего состояния вкладки:

struct PinnedTab
{
    bool isPinned;
    int currentIndex;
};

Q_DECLARE_METATYPE(PinnedTab); // For QVariant

Затем создайте пользовательский QTabBar для обработки перемещения и используйте QTabWidget для замены текущей панели вкладок (это необходимо сделать перед вставкой вкладок):

class Bar: public QTabBar
{
public:
    void pin(int const index)
    {
        PinnedTab info;
        info.isPinned = true;
        info.currentIndex = index; // TODO: move the tab to the left and do not use current index
        setTabData(index, QVariant::fromValue(info));
    }

    Bar(QWidget* parent=nullptr): QTabBar(parent)
    {}

    virtual void tabLayoutChange() override
    {
        for (int i = 0; i != count(); ++i) // Check if a pinned tab has moved
        {
            if (tabData(i).isValid())
            {
                PinnedTab const info = tabData(i).value<PinnedTab>();
                if (info.isPinned == true && i != info.currentIndex) {
                    rollbackLayout();
                    return;
                }
            }
        }

        for (int i = 0; i != count(); ++i)
        {
            if (tabData(i).isValid())
            {
                PinnedTab info = tabData(i).value<PinnedTab>();
                info.currentIndex = i;
                setTabData(i, QVariant::fromValue(info));
            }
            else
            {
                PinnedTab info;
                info.isPinned = false;
                info.currentIndex = i;
                setTabData(i, QVariant::fromValue(info));
            }
        }
    }

    void rollbackLayout() {
        for (int i = 0; i != count(); ++i)
        {
            if (tabData(i).isValid())
            {
                PinnedTab const info = tabData(i).value<PinnedTab>();
                if (i != info.currentIndex) {
                    moveTab(i, info.currentIndex);
                }
            }
        }
    }
};

tabLayoutChange вызывается, когда макет изменился. Поэтому он будет вызываться при перемещении вкладки.

метод rollbackLayout используется для перемещения каждой вкладки на последнюю позицию, сохраненную в данных вкладки .

Позвоните pin, чтобы закрепить вкладку с указанным индексом.

Я упростил свой код для большей ясности, и вам, возможно, придется переопределить некоторое поведение (сейчас, если вы закрепите вкладку, она сохранит свой текущий положение, и он не будет обрабатывать вставки / удаления вкладок).

...