我想在一个水平的拆分器中将QWidget和QTabWidget并排放置。但是拆分器失去了它的形状,只有在将鼠标悬停在上面时才能知道它的位置。应该如何让它可见呢?
谢谢。
我想在一个水平的拆分器中将QWidget和QTabWidget并排放置。但是拆分器失去了它的形状,只有在将鼠标悬停在上面时才能知道它的位置。应该如何让它可见呢?
谢谢。
由于QSplitterHandle(大多数人认为是“分隔符”)派生自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);
这将在分隔符手柄上添加一个凹陷的线条。当然,您可以选择另一种样式的框架line
,或者使用完全不同的小部件作为添加到分隔符手柄的小部件。
我基于上面的代码,但它可以处理两种分隔器方向。 我只喜欢非不透明调整大小和非可折叠子级。 握把由三条平行线组成。您可以玩弄手柄宽度,但 7 的握力在 Windows 上看起来很好; 在 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();
}
}
gripWidth = 2
设置为可见的握把(Win7经典外观)。否则,这是一个很好的解决方案,本应该在Qt多年前就修复的问题。 - DerManu这对于至少在WinXP和默认的Luna主题下的每个分隔符都是正确的(切换到经典模式可以解决问题)。 如果你想继续使用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();
}
您可以在https://doc.qt.io/qt-5/stylesheet-reference.html上找到更多关于Qt样式表的内容。
protected virtual QSplitterHandle * QSplitter::createHandle()
方法,返回任何你想要的东西。QSplitterHandle
子类。使用 splitter_handles {} 函数并传入要添加手柄的 QSplitter:
#include "splitter_handles.h"
...
QSplitter spl {};
... // widgets added to 'spl'
plitter_handles {spl}; // adding handles
...
结果:
splitter_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
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();
}
app = QtGui.QApplication(sys.argv)
app.setStyle("Plastique") # set style (using this style shows splitters! :)
maximumWidth
(对于水平分割器)。 - Phlucious