继承自定义TabBar和resizeEvent的实现
Inherit custom TabBar and implementation of resizeEvent
我正在通过 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 宽度
- 两个标签:每个标签宽度为 400 像素
- ...
但无论我在哪里使用这些自定义事件之一,它都会出现段错误。
我做错了什么?
您需要 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());
}
通过适当的设计思想,可以避免这样的变通办法,但为了提供更有帮助的建议,我们需要更好地了解您的用例。
因为这个 post 与 有关,我看得出你不明白继承是如何工作的。
resizeEvent
、tabInserted
和tabRemoved
是从Qt框架调用的,不应直接调用,因此protected
.这就是 insertTab
和 removeTab
的目的。
你正在做的是,调用 tabInserted
,调用 insertTab
,调用 tabInserted
,调用 insertTab
,....
您想要做的是在您的 tabInserted
和 tabRemoved
中实现制表符调整大小,就像您在 resizeEvent
.
中所做的(有点错误)
if (e->type() == QEvent::Resize)
在 resizeEvent
中始终为真,因为这是 Qt 调用它的条件。
根据评论,我试图覆盖 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);
}
};
它似乎可以按您的要求工作 -- 选项卡的大小可以占据整个 window 宽度。
请注意,可能还有其他风格因素会影响这一点,但我没有时间检查。
我正在通过 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 宽度
- 两个标签:每个标签宽度为 400 像素
- ...
但无论我在哪里使用这些自定义事件之一,它都会出现段错误。
我做错了什么?
您需要 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());
}
通过适当的设计思想,可以避免这样的变通办法,但为了提供更有帮助的建议,我们需要更好地了解您的用例。
因为这个 post 与
resizeEvent
、tabInserted
和tabRemoved
是从Qt框架调用的,不应直接调用,因此protected
.这就是 insertTab
和 removeTab
的目的。
你正在做的是,调用 tabInserted
,调用 insertTab
,调用 tabInserted
,调用 insertTab
,....
您想要做的是在您的 tabInserted
和 tabRemoved
中实现制表符调整大小,就像您在 resizeEvent
.
if (e->type() == QEvent::Resize)
在 resizeEvent
中始终为真,因为这是 Qt 调用它的条件。
根据评论,我试图覆盖 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);
}
};
它似乎可以按您的要求工作 -- 选项卡的大小可以占据整个 window 宽度。
请注意,可能还有其他风格因素会影响这一点,但我没有时间检查。