继承自定义选项卡栏和调整大小事件的实现

Inherit custom TabBar and implementation of resizeEvent

本文关键字:大小事 小事件 实现 调整 自定义 选项 继承      更新时间:2023-10-16

我正在通过QSpinBox动态插入和删除选项卡,效果很好。要填充屏幕的整个宽度(800px),我需要使用自己的 eventFilter 展开选项卡:

主窗口.h

namespace Ui {
class MainWindow;
}
class CustomTabBar : public QTabBar
{
public:
    CustomTabBar(QWidget *parent = Q_NULLPTR)
        : QTabBar(parent)
    {
    }
    void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE
    {
        /* Resize handler */
                if (e->type() == QEvent::Resize) {
                    // The width of each tab is the width of the tab widget / # of tabs.
                    resize(size().width()/count(), size().height());
                }
    }
    void tabInserted(int index) Q_DECL_OVERRIDE
    {
        /* New tab handler */
        insertTab(count(), QIcon(QString("")), QString::number(index));
    }
    void tabRemoved(int index) Q_DECL_OVERRIDE
    {
        /* Tab removed handler */
        removeTab(count() - index);
    }
};
class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    CustomTabBar *tabs;
};

我的主窗口的相关代码如下所示:

主窗口.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    cells = new CustomTabBar(this);
    cells->tabInserted(1);
//    cells->installEventFilter(resizeEvent());
}
void MainWindow::changeCells(int value)   // Called when QSpinBox is changed
{
    if (cells->count() < value) {
        cells->tabInserted(1);
    }
    else if (cells->count() > value) {
        cells->tabRemoved(1);
    }
}

如前所述,最大宽度设置为 800 像素。所需的行为是:

  • 一个标签:800px 宽度
  • 两个选项卡:每个选项卡宽度 400 像素

但是无论我在哪里使用这些自定义事件之一,它都会出现段错误。

我在这里做错了什么?

根据评论,我试图覆盖 QTabBar 的 tabSizeHint 成员和"它对我有用"......

class tab_bar: public QTabBar {
protected:
  virtual QSize tabSizeHint (int index) const override
  {
    QSize s(QTabBar::tabSizeHint(index));
    s.setWidth(width() / count());
    return(s);
  }
};

它似乎可以根据需要工作 - 选项卡的大小可以占据整个窗口宽度。

请注意,可能还有其他样式因素会影响这一点,但我还没有时间检查。

您需要

disconnect(this, SIGNAL(resize()), this, SLOT(resizeEvent())然后在调用resize()后重新connect([...]),以避免由resize -> resizeEvent的无限递归引起的堆栈溢出。编辑:就像@G.M.说的那样。

void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE
{
    disconnect(this, SIGNAL(resize()), this, SLOT(resizeEvent());
    /* Resize handler */
    if (e->type() == QEvent::Resize) {
        // The width of each tab is the width of the tab widget / # of tabs.
        resize(size().width()/count(), size().height());
    }
    connect(this, SIGNAL(resize()), this, SLOT(resizeEvent());
}

通过适当的设计思想,可以避免这样的解决方法,但为了给出更有用的建议,我们需要更好地了解您的用例。

由于这篇文章与这篇文章有关,我可以看到您不了解继承的工作原理。

resizeEventtabInsertedtabRemoved是从Qt框架调用的,不应该直接调用,因此protected。这就是insertTabremoveTab的目的。

你正在做的是,调用tabInserted,它调用insertTab,调用tabInserted,调用insertTab,哪个......

您要做的是在tabInsertedtabRemoved中实现选项卡大小调整,就像您在resizeEvent中(有点错误)所做的那样。

if (e->type() == QEvent::Resize)

resizeEvent中总是正确的,因为这是Qt调用它的条件。