Я вставляю и удаляю вкладки динамически через 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 пикселей. Желаемое поведение будет:
Но это segfaulting везде, где я использую одно из этих пользовательских событий.
Что я здесь не так делаю?
Следуя комментариям, я попытался переопределить элемент 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);
}
};
Кажется, он работает так, как вам нужно — вкладки, размер которых занимает всю ширину окна.
Обратите внимание, что могут быть и другие факторы стиля, которые влияют на это, но у меня не было времени, чтобы проверить.
Вам захочется 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());
}
При правильном подходе к проектированию обходных путей можно избежать, но для более полезного предложения нам нужно лучше понять ваш вариант использования.
Так как этот пост связан с этот Я вижу, что вы не поняли, как работает наследование.
resizeEvent
, tabInserted
а также tabRemoved
вызываются из каркаса Qt и не должен вызываться напрямую, следовательно protected
, Что это insertTab
а также removeTab
для.
То, что вы делаете, зовет tabInserted
, который вызывает insertTab
, который вызывает tabInserted
, который вызывает insertTab
, который….
Что вы хотите сделать, это реализовать изменение размера вкладки в вашем tabInserted
а также tabRemoved
так же, как вы (как-то неправильно) сделали в resizeEvent
,
if (e->type() == QEvent::Resize)
Всегда верно в resizeEvent
, так как это условие для вызова Qt.