如何在Qt中固定标签
How to pin a tab in Qt
是否可以使用 Qt 固定标签页?
我希望一个选项卡始终保持在原位(索引 0),同时仍然能够移动其他选项卡。
到目前为止,我试图听 QTabBar::tabMoved 并恢复移动,但为时已晚。我什至不希望它尝试移动。
对我来说最坏的情况是被迫更改鼠标处理方式。如果有其他方法请告诉我。
我从来没有找到一个好的方法来做到这一点。但是,我使用了这样一个事实,即您可以将原始数据存储在 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
以固定具有给定索引的选项卡。
为了更加清晰,我简化了我的代码,您可能需要重新定义一些行为(目前,如果您固定一个选项卡,它将保持其当前位置并且不会处理 insert/remove 选项卡)。
是否可以使用 Qt 固定标签页?
我希望一个选项卡始终保持在原位(索引 0),同时仍然能够移动其他选项卡。
到目前为止,我试图听 QTabBar::tabMoved 并恢复移动,但为时已晚。我什至不希望它尝试移动。
对我来说最坏的情况是被迫更改鼠标处理方式。如果有其他方法请告诉我。
我从来没有找到一个好的方法来做到这一点。但是,我使用了这样一个事实,即您可以将原始数据存储在 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
以固定具有给定索引的选项卡。
为了更加清晰,我简化了我的代码,您可能需要重新定义一些行为(目前,如果您固定一个选项卡,它将保持其当前位置并且不会处理 insert/remove 选项卡)。