Наследовать пользовательский TabBar и реализацию resizeEvent

Я вставляю и удаляю вкладки динамически через QSpinBox, который работает отлично. Чтобы заполнить всю ширину экрана (800 пикселей), мне нужно расширить вкладки, используя мой собственный 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 пикселей. Желаемое поведение будет:

  • Одна вкладка: ширина 800 пикселей
  • Две вкладки шириной 400 пикселей каждая

Но это segfaulting везде, где я использую одно из этих пользовательских событий.

Что я здесь не так делаю?

1

Решение

Следуя комментариям, я попытался переопределить элемент tabSizeHint в QTabBar и «он работает для меня» …

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

Кажется, он работает так, как вам нужно — вкладки, размер которых занимает всю ширину окна.

Обратите внимание, что могут быть и другие факторы стиля, которые влияют на это, но у меня не было времени, чтобы проверить.

0

Другие решения

Вам захочется disconnect(this, SIGNAL(resize()), this, SLOT(resizeEvent()), затем зановоconnect([...]) после того как ты позвонил resize(), чтобы избежать переполнения стека, вызванного бесконечной рекурсией 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());
}

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

0

Так как этот пост связан с этот Я вижу, что вы не поняли, как работает наследование.

resizeEvent, tabInserted а также tabRemoved вызываются из каркаса Qt и не должен вызываться напрямую, следовательно protected, Что это insertTab а также removeTab для.

То, что вы делаете, зовет tabInserted, который вызывает insertTab, который вызывает tabInserted, который вызывает insertTab, который….

Что вы хотите сделать, это реализовать изменение размера вкладки в вашем tabInserted а также tabRemovedтак же, как вы (как-то неправильно) сделали в resizeEvent,

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

Всегда верно в resizeEvent, так как это условие для вызова Qt.

0
По вопросам рекламы [email protected]