继承自定义TabBar和resizeEvent的实现

时间:2016-06-09 07:22:17

标签: c++ qt qt5 qtabbar eventfilter

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

mainwindow.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;
};

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

mainwindow.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宽
  • 两个标签:每个400px宽
  • ...

但是,当我使用其中一个自定义事件时,它就会分裂。

我在这里做错了什么?

3 个答案:

答案 0 :(得分:0)

在您调用disconnect(this, SIGNAL(resize()), this, SLOT(resizeEvent())之后,您想要connect([...])然后重新resize(),以避免导致堆栈溢出通过无限递归调整大小 - &gt; 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());
}

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

答案 1 :(得分:0)

由于这篇文章与this one有关,我可以看到你不明白继承是如何工作的。

从Qt框架调用

resizeEventtabInsertedtabRemoved,不应直接调用 ,因此protected。这就是insertTabremoveTab的用途。

您正在拨打tabInserted,呼叫insertTab,呼叫tabInserted,呼叫insertTab,其中...... {/ p>

您要做的是在tabInsertedtabRemoved中实施标签大小调整,就像resizeEvent中的那样(有点错误)。

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

resizeEvent中始终为真,因为这是Qt调用它的条件。

答案 2 :(得分:0)

继续发表评论后,我试图覆盖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);
  }
};

它似乎可以按照您的要求工作 - 标签大小可以占据整个窗口宽度。

请注意,可能还有其他影响此问题的风格因素,但我没有时间检查。