gpt4 book ai didi

c++ - 在 Qt5 中实现基于单元格的小部件

转载 作者:行者123 更新时间:2023-11-30 04:53:45 28 4
gpt4 key购买 nike

我正在尝试实现一个类似于 Jupyter Notebook 中的基于单元格的小部件在 Qt 中,多个单元格垂直堆叠。每个单元格都由一个 QTextEdit 和多个按钮组成,单元格的垂直大小会随着在文本编辑中输入更多文本而增加(即文本编辑中没有垂直滚动条)。

但是我不确定在 Qt 中实现这样一个小部件的最佳方法是什么。我已经为每个项目尝试了一个带有自定义小部件(由 QTextEdit 和几个按钮组成)的 QListWidget,但是自定义小部件不会通过输入垂直增长更多文本,而不是 QTextEdit 滚动条会出现。我还使用 QListViewQStyledItemDelegate 实现了第二个版本,但是我遇到了多个问题,包括无法与绘制的按钮交互(通过委托(delegate))。

有关如何实现这种基于单元格的小部件的任何建议/示例?

最佳答案

您可以继承 QTextEdit 并使用 document()->size() 监听 document 大小的变化(不是大小QTextEdit,注意)。然后您可以调整 QTextEdit 父级的大小以反射(reflect)新的大小。要用小部件填充父级,请使用布局。为此,我在下面多次使用了 QVBoxLayout。 (一,在垂直列中容纳多个 QTextEdit 小部件;二,容纳单个 TextEdit)。

#include <QtCore>
#include <QtWidgets>

class DyTextEdit : public QTextEdit
{
Q_OBJECT
public:
DyTextEdit(QWidget *parent = nullptr) :
QTextEdit(parent)
{
QTextDocument *doc = document();
currentSize = doc->size();

qDebug() << "[Init] Size:" << currentSize;

// listen to text/content changes
connect(this, &QTextEdit::textChanged, this, &DyTextEdit::on_textChanged);

// connect <> 💡
connect(this, &DyTextEdit::sizeChanged, this, &DyTextEdit::resizeParent);

doc->setTextWidth(-1);

emit sizeChanged(currentSize); // init
}

signals:
// emitted when document size changes
void sizeChanged(QSizeF size);

public slots:
void on_textChanged()
{
QSizeF newSize = document()->size();

qDebug() << "[TextChanged] Size:" << newSize;

// detect changes in the document size
if (newSize != currentSize)
emit sizeChanged(newSize); // emit signal💡

// update size
currentSize = newSize;
}

void resizeParent(QSizeF size)
{
// resize the parent's height, don't bother with the width
parentWidget()->setFixedHeight(size.height());
}

private:
QSizeF currentSize; // keeps track of current document size

};

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

// holds all dytextedits
QWidget aggregateWidget;
QVBoxLayout aggregateLayout(&aggregateWidget);

// note: for scalability, use a QList (or QLists)

// first textbox
QWidget widget;
QVBoxLayout vbLayout(&widget);
vbLayout.setMargin(0);
DyTextEdit dytext(&widget);
vbLayout.addWidget(&dytext);

// first button row
QHBoxLayout hbLayout(&widget);
hbLayout.setMargin(0);
QPushButton pb1a("Push this.", &widget);
hbLayout.addWidget(&pb1a);
QPushButton pb1b("Push this.", &widget);
hbLayout.addWidget(&pb1b);

// second textbox
QWidget widget2;
QVBoxLayout vbLayout2(&widget2);
vbLayout2.setMargin(0);
DyTextEdit dytext2(&widget2);
vbLayout2.addWidget(&dytext2);

// second button row
QHBoxLayout hbLayout2(&widget2);
hbLayout2.setMargin(0);
QPushButton pb2a("Push this.", &widget2);
hbLayout2.addWidget(&pb2a);
QPushButton pb2b("Push this.", &widget2);
hbLayout2.addWidget(&pb2b);

// add widgets to layout
aggregateLayout.addWidget(&widget); // cell 1
aggregateLayout.addLayout(&hbLayout); // |
aggregateLayout.addWidget(&widget2); // cell 2
aggregateLayout.addLayout(&hbLayout2); // |

aggregateLayout.setSizeConstraint(QLayout::SetMinAndMaxSize);

aggregateWidget.show();

return a.exec();
}

#include "main.moc" // include if there are QObject classes in main.cpp

请注意,在上面,我使用了使用 QHBoxLayout 的按钮行,并将它们添加到与文本框小部件分离的整体聚合布局中。如果您想以不同的格式设置按钮,您仍然可以使用 QGridLayout。您还可以将文本编辑器和按钮布局组合为覆盖两者的另一个小部件(作为保护伞)下的子项。这将更清楚地形成小部件的单元格,并且可能更容易四处移动。 (我已经在 Github 上上传了一个可行的示例。)

演示(macOS):

这是输入内容和复制粘贴内容后的截图。

demonstration using both typed and copied content

请注意,聚合小部件将在删除文本行时收缩。

关于c++ - 在 Qt5 中实现基于单元格的小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53800168/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com