C++ qspliter在QWidget和QTabWidget之间变得不可区分

C++ qspliter在QWidget和QTabWidget之间变得不可区分,c++,qt,qt4,qtabwidget,qsplitter,C++,Qt,Qt4,Qtabwidget,Qsplitter,我把一个QWidget和一个QTabWidget放在一个水平分离器中,彼此相邻。当拆分器失去形状时,只需将鼠标悬停在拆分器上,就可以知道存在拆分器。如何使其可见 谢谢。这适用于每个拆分器,至少在WinXP和默认的Luna thema(改为经典解决了问题)中是如此。 如果您想继续使用Luna,您可以更改拆分器的渲染方式,例如更改控制柄的背景色 int main(int argc, char *argv[]) { QApplication a(argc, argv); a.s

我把一个QWidget和一个QTabWidget放在一个水平分离器中,彼此相邻。当拆分器失去形状时,只需将鼠标悬停在拆分器上,就可以知道存在拆分器。如何使其可见


谢谢。

这适用于每个拆分器,至少在WinXP和默认的Luna thema(改为经典解决了问题)中是如此。 如果您想继续使用Luna,您可以更改拆分器的渲染方式,例如更改控制柄的背景色

int main(int argc, char *argv[])    {

    QApplication a(argc, argv);
    a.setStyleSheet("QSplitter::handle { background-color: gray }");
    MainWindow w;
    w.show();
    return a.exec();
}
您可以在Qt样式表的

上找到更多信息,因为qspliterHandle(大多数人认为是“拆分器”)是从QWidget派生的,所以您可以向它添加其他小部件。以下是我过去为解决这个问题所做的工作:

// Now add the line to the splitter handle
// Note: index 0 handle is always hidden, index 1 is between the two widgets
QSplitterHandle *handle = pSplitter->handle(1);
QVBoxLayout *layout = new QVBoxLayout(handle);
layout->setSpacing(0);
layout->setMargin(0);

QFrame *line = new QFrame(handle);
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
layout->addWidget(line);

这将向拆分器控制柄添加一条下陷线。当然,您可以为框架
行选择另一种样式
,或者使用完全不同的样式作为添加到拆分器句柄的小部件。

I基于上述代码,但它处理两个拆分器方向。 我只是喜欢不不透明的大小调整和不可折叠的儿童。 夹点由三条平行线组成。你们可以玩手柄宽度,但7的手柄在窗户上看起来不错;没有登录Linux或Mac

void helper::decorateSplitter(QSplitter* splitter, int index)
{
    Q_ASSERT(splitter != NULL);

    const int gripLength = 15; 
    const int gripWidth = 1;
    const int grips = 3;

    splitter->setOpaqueResize(false);
    splitter->setChildrenCollapsible(false);

    splitter->setHandleWidth(7);
    QSplitterHandle* handle = splitter->handle(index);
    Qt::Orientation orientation = splitter->orientation();
    QHBoxLayout* layout = new QHBoxLayout(handle);
    layout->setSpacing(0);
    layout->setMargin(0);

    if (orientation == Qt::Horizontal)
    {
        for (int i=0;i<grips;++i)
        {
            QFrame* line = new QFrame(handle);
            line->setMinimumSize(gripWidth, gripLength);
            line->setMaximumSize(gripWidth, gripLength);
            line->setFrameShape(QFrame::StyledPanel);
            layout->addWidget(line);
        }
    }
    else
    {
        //this will center the vertical grip
        //add a horizontal spacer
        layout->addStretch();
        //create the vertical grip
        QVBoxLayout* vbox = new QVBoxLayout;
        for (int i=0;i<grips;++i)
        {
            QFrame* line = new QFrame(handle);
            line->setMinimumSize(gripLength, gripWidth);
            line->setMaximumSize(gripLength, gripWidth);
            line->setFrameShape(QFrame::StyledPanel);
            vbox->addWidget(line);
        }
        layout->addLayout(vbox);
        //add another horizontal spacer
        layout->addStretch();
    }
}
void helper::decorateSplitter(QSplitter*splitter,int index)
{
Q_断言(拆分器!=NULL);
常数int gripLength=15;
常数int gripWidth=1;
常数int=3;
拆分器->设置查询(假);
拆分器->setChildrenCollapsible(假);
拆分器->设置手柄宽度(7);
qspliterHandle*句柄=拆分器->句柄(索引);
Qt::方向=拆分器->方向();
QHBoxLayout*布局=新的QHBoxLayout(手柄);
布局->设置间距(0);
布局->设置边距(0);
如果(方向==Qt::水平)
{
对于(int i=0;isetMinimumSize(gripWidth,gripLength);
行->设置最大尺寸(gripWidth、gripLength);
line->setFrameShape(QFrame::StyledPanel);
布局->添加小部件(行);
}
}
其他的
{
//这将使垂直夹点居中
//添加一个水平间隔
布局->添加拉伸();
//创建垂直夹点
QVBoxLayout*vbox=新的QVBoxLayout;
对于(int i=0;isetMinimumSize(gripLength,gripWidth);
行->设置最大尺寸(gripLength、gripWidth);
line->setFrameShape(QFrame::StyledPanel);
vbox->addWidget(行);
}
布局->添加布局(vbox);
//添加另一个水平垫片
布局->添加拉伸();
}
}

您可以将QSplitter子类化并覆盖它的受保护虚拟qspliterHandle*qspliter::createHandle()以返回任何让您满意的内容


例如,通过该重载方法,您可以使用自定义绘图返回
qspliterHandle
的子类。

多亏了Merula的回答……我尝试了这个方法,现在我的拆分器是可见的,看起来非常漂亮,但不显得突兀。此代码适用于使用PyQt或PySide的Python

app = QtGui.QApplication(sys.argv)
app.setStyle("Plastique")   # set style (using this style shows splitters! :)

使用要添加句柄的QSplitter调用拆分器_handles{}:

#include "splitter_handles.h"
...
QSplitter spl {};
... // widgets added to 'spl'
plitter_handles {spl}; // adding handles
...
结果:

拆分器_句柄.h

#ifndef SPLITTER_HANDLES_H
#define SPLITTER_HANDLES_H

#include <QLayout>
#include <QPainter>
#include <QSplitter>

class handle : public QWidget
{
    Q_OBJECT

protected:
    void paintEvent(QPaintEvent *e) {
        Q_UNUSED(e);
        QPainter painter {this};
        painter.setPen(Qt::NoPen);
        painter.setBrush(Qt::Dense4Pattern);
        painter.drawRect(this->rect());
    }
};

class splitter_handles {
public:
    splitter_handles(QSplitter * spl) {
        const int width {7};
        spl->setHandleWidth(width);
        for(int h_idx {1}; h_idx < spl->count(); h_idx++) {
            auto l_handle {new handle {}};
            l_handle->setMaximumSize(width*2, width*2);

            auto layout {new QHBoxLayout {spl->handle(h_idx)}};
            layout->setSpacing(0);
            layout->setMargin(1);
            layout->addWidget(l_handle);
        }
    }
};

#endif // SPLITTER_HANDLES_H
\ifndef拆分器\u句柄\u H
#定义拆分器句柄
#包括
#包括
#包括
类句柄:公共QWidget
{
Q_对象
受保护的:
无效油漆事件(QPaintEvent*e){
Q_(e);
油漆工{this};
painter.setPen(Qt::NoPen);
画家。挫折(Qt::Dense4模式);
painter.drawRect(this->rect());
}
};
类拆分器\u句柄{
公众:
拆分器手柄(QSPLITER*spl){
常数int宽度{7};
spl->setHandleWidth(宽度);
对于(int h_idx{1};h_idxcount();h_idx++){
自动l_句柄{新句柄{};
l_手柄->设置最大尺寸(宽度*2,宽度*2);
自动布局{newqhboxlayout{spl->handle(h_idx)};
布局->设置间距(0);
布局->设置边距(1);
布局->添加小部件(l_句柄);
}
}
};
#endif//SPLITTER\u句柄
main.c

#include <QApplication>
#include <QGroupBox>
#include <QLayout>
#include <QSplitter>

#include "splitter_handles.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    auto spl_v {new QSplitter {Qt::Vertical}};
    spl_v->addWidget(new QGroupBox {"box 1"});
    spl_v->addWidget(new QGroupBox {"box 2"});
    spl_v->addWidget(new QGroupBox {"box 3"});
    splitter_handles {spl_v}; // set handles

    auto wdg  {new QWidget {}};
    auto v_lt {new QVBoxLayout {wdg}};
    v_lt->addWidget(spl_v);
    v_lt->setMargin(0);

    auto spl_h {new QSplitter {}};
    spl_h->addWidget(wdg);
    spl_h->addWidget(new QGroupBox {"box 4"});
    spl_h->addWidget(new QGroupBox {"box 5"});
    splitter_handles {spl_h};

    auto h_lt {new QHBoxLayout {}};
    h_lt->addWidget(spl_h);

    QWidget w {};
    w.setLayout(h_lt);
    w.setGeometry(100,100,500,300);
    w.show();

    return a.exec();
}
#包括
#包括
#包括
#包括
#包括“splitter_handles.h”
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
自动spl_v{new QSplitter{Qt::Vertical}};
spl_v->addWidget(新的QGroupBox{“box 1”});
spl_v->addWidget(新的QGroupBox{“box 2”});
spl_v->addWidget(新的QGroupBox{“box 3”});
splitter_handles{spl_v};//设置句柄
自动wdg{newQWidget{}};
自动v_lt{new QVBoxLayout{wdg}};
v_lt->addWidget(spl_v);
v_lt->setMargin(0);
自动spl_h{new qspliter{};
spl_h->addWidget(wdg);
spl_h->addWidget(新的QGroupBox{“box 4”});
spl_h->addWidget(新的QGroupBox{“box 5”});
拆分器句柄{spl_h};
自动h_lt{新QHBoxLayout{};
h\u lt->addWidget(spl\u h);
qw{};
w、 设置布局(h_lt);
w、 集合几何(100500300);
w、 show();
返回a.exec();
}

谢谢。这会更改颜色,但我想更改拆分器的浮雕。可能吗?windows下拆分器的默认行为是绘制背景色。当拆分的组件默认也有bg颜色(QWidget)时,这是不好的。windows的方法是给它们一个不同的颜色和/或凹陷的边框(QFrame支持边框)。如果要使用浮雕,则必须更改样式(忘记样式表)。使用setStyle()更改样式。例如,QPlastiqueStyle支持浮雕。您可以将setStyle()应用于QApplication对象或仅应用于拆分器(不是首选)。我建议首先提到的本机解决方案。您可以覆盖qspliter::createHandle()以使用自定义绘图返回句柄。这太棒了。我只想补充一点,我更喜欢QHBoxLayout,因为这样我可以指定
最大宽度
(用于水平拆分器)向上投票,因为它确实有效,但它确实让人感觉