- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 QTreeWidget
进行了子类化为了重新实现 protected
drag
的功能和 drop
为了拖放一个QTreeWidget
的 parent 和 child .
它几乎可以工作,问题 就是当我尝试拖放 child 或 parent 时,一旦我放下它们,它们就会被删除。
源码可见here以防您需要查看发生了什么。
此外,如果我尝试拖放父级,不幸的是它不会移动,也没有任何 react 。
请看下面对 children 的奇怪效果:
我将 child “Original”拖到“Sample”下,这个过程似乎可以正常工作:
删除“原始”后,您可以看到索引似乎在那里,但似乎被部分删除:
我不确定到底发生了什么,为什么 child 似乎没有完全正确地被丢弃,为什么 parent 实际上一动不动。
在最小可验证示例的代码下方:
主窗口.h
#include <QMainWindow>
class QTreeWidget;
class QTreeWidgetItem;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QTreeWidgetItem *createItem(const QString &name, const QString &iconPath);
private:
Ui::MainWindow *ui;
QTreeWidget *widget;
QString m_Name;
QString m_Path;
};
#endif // MAINWINDOW_H
主窗口.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
ui->treeWidget->setDragEnabled(true);
ui->treeWidget->viewport()->setAcceptDrops(true);
ui->treeWidget->setDropIndicatorShown(true);
ui->treeWidget->setDragDropMode(QAbstractItemView::InternalMove);
auto *top1 = createItem("Images", "/home/ui/qrc/laserscan.png");
auto *top2 = createItem("Path", "/home/ui/qrc/laserscan.png");
top1->addChild(createItem("Original", "/home/ui/qrc/laserscan.png"));
top1->addChild(createItem("Sample", "/home/ui/qrc/laserscan.png"));
top2->addChild(createItem("Left Side", "/home/ui/qrc/laserscan.png"));
top2->addChild(createItem("Right Side", "/home/ui/qrc/laserscan.png"));
ui->treeWidget->addTopLevelItems({ top1, top2 });
// Below I am assigning to each parent/children a checkbox
const int n_tops = ui->treeWidget->topLevelItemCount();
for(int a = 0; a<n_tops; ++a) {
const int n_children = ui->treeWidget->topLevelItem(a)->childCount();
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a));
for(int b = 0; b<n_children; ++b) {
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a)->child(b));
}
}
}
MainWindow::~MainWindow()
{
delete ui;
}
QTreeWidgetItem *MainWindow::createItem(const QString &name, const QString &iconPath)
{
auto *item = new QTreeWidgetItem(QStringList{name});
item->setIcon(0, QIcon(iconPath));
return item;
}
maphelpers.h
#include <QTreeWidget>
#include <QTreeWidgetItem>
void qtreewidgetitem_assign_qcheckbox(QTreeWidget *tree_widget, QTreeWidgetItem *tree_item);
#endif // MAPHELPERS_H
maphelpers.cpp
#include <QTreeWidget>
void qtreewidgetitem_assign_qcheckbox(QTreeWidget *tree_widget, QTreeWidgetItem *tree_item)
{
MyCheckBoxMap *myCheckBoxMap = new MyCheckBoxMap(tree_item);
tree_widget->setItemWidget(tree_item, MAP_COLUMN, myCheckBoxMap);
}
下面是我如何分类
QTreeWidget
:
#include <QTreeWidget>
class CustomTreeWidget : public QTreeWidget
{
public:
CustomTreeWidget(QWidget *parent = Q_NULLPTR);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dropEvent(QDropEvent *event) override;
private:
QTreeWidgetItem *draggedItem;
};
#endif // CUSTOMTREEWIDGET_H
customtreewidget.cpp
CustomTreeWidget::CustomTreeWidget(QWidget *parent)
{
QTreeWidgetItem* parentItem = new QTreeWidgetItem();
parentItem->setText(0, "Test");
parentItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled);
int num_rows = topLevelItemCount();
for(int i = 0; i < num_rows; ++i)
{
int nChildren = topLevelItem(i)->childCount();
QTreeWidgetItem* pItem = new QTreeWidgetItem(parentItem);
for(int j = 0; j < nChildren; ++j) {
pItem->setText(0, QString("Number %1").arg(i) );
pItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);
pItem->addChild(pItem);
topLevelItem(i)->child(j);
}
}
}
void CustomTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{
draggedItem = currentItem();
QTreeWidget::dragEnterEvent(event);
}
void CustomTreeWidget::dropEvent(QDropEvent *event)
{
QModelIndex droppedIndex = indexAt(event->pos());
if(!droppedIndex.isValid()) {
return;
}
if(draggedItem) {
QTreeWidgetItem *mParent = draggedItem->parent();
if(mParent) {
if(itemFromIndex(droppedIndex.parent()) != mParent)
return;
mParent->removeChild(draggedItem);
mParent->insertChild(droppedIndex.row(), draggedItem);
}
}
}
到目前为止我所做的和我尝试过的:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto *top1 = createItem("Images", "/home/ui/qrc/laserscan.png");
auto *top2 = createItem("Path", "/home/ui/qrc/laserscan.png");
top1->addChild(createItem("Original", "/home/ui/qrc/laserscan.png"));
top1->addChild(createItem("Sample", "/home/ui/qrc/laserscan.png"));
top2->addChild(createItem("Left Side", "/home/ui/qrc/laserscan.png"));
top2->addChild(createItem("Right Side", "/home/ui/qrc/laserscan.png"));
ui->treeWidget->addTopLevelItems({ top1, top2 });
const int n_tops = ui->treeWidget->topLevelItemCount();
// Below I am assigning to each parent/children a checkbox
for(int a = 0; a<n_tops; ++a) {
const int n_children = ui->treeWidget->topLevelItem(a)->childCount();
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a));
for(int b = 0; b<n_children; ++b) {
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a)->child(b));
}
}
QTreeWidgetItem *parentItem = Q_NULLPTR;
QTreeWidgetItem *childItem = Q_NULLPTR;
QTreeWidgetItemIterator it(ui->treeWidget);
while (*it) {
parentItem = new QTreeWidgetItem(ui->treeWidget);
//parentItem->setText(0, it.key());
foreach (const auto &str, it) {
childItem = new QTreeWidgetItem;
childItem->setText(0, str);
parentItem->addChild(childItem);
}
}
}
2) 在对官方文档进行进一步研究后,我决定应用
QMapIterator Class 来解决问题。我想保留构造函数,因为我最初构造并认为通过
QMap
打算以不同的方式重写构造函数,基本上是下面的实现思想,但不想通过那种方式:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto *top1 = createItem("Images", "/home/ui/qrc/laserscan.png");
auto *top2 = createItem("Path", "/home/ui/qrc/laserscan.png");
top1->addChild(createItem("Original", "/home/ui/qrc/laserscan.png"));
top1->addChild(createItem("Sample", "/home/ui/qrc/laserscan.png"));
top2->addChild(createItem("Left Side", "/home/ui/qrc/laserscan.png"));
top2->addChild(createItem("Right Side", "/home/ui/qrc/laserscan.png"));
ui->treeWidget->addTopLevelItems({ top1, top2 });
ui->treeWidget->addTopLevelItems({ top1, top2 });
const int n_tops = ui->treeWidget->topLevelItemCount();
// Below I am assigning to each parent/children a checkbox
for(int a = 0; a<n_tops; ++a) {
const int n_children = ui->treeWidget->topLevelItem(a)->childCount();
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a));
for(int b = 0; b<n_children; ++b) {
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a)->child(b));
}
}
QTreeWidgetItem *parentItem = Q_NULLPTR;
QTreeWidgetItem *childItem = Q_NULLPTR;
QMapIterator<QString, QStringList> i(treeMap);
while (i.hasNext()) {
i.next();
parentItem = new QTreeWidgetItem(widget);
parentItem->setText(0, i.key());
foreach (const auto &str, i.value()) {
childItem = new QTreeWidgetItem;
childItem->setText(0, str);
parentItem->addChild(childItem);
}
}
}
3) 经过更多研究,我发现了
this source , 和
this other source这对于实现
QTreeWidget
的子类化很有用(尤其是最后一篇文章)。 .
最佳答案
我认为复选框正在处理鼠标事件,并且不要让事件通过该项目。要获得所需的行为,您应该删除此部分:
const int n_tops = ui->treeWidget->topLevelItemCount();
for(int a = 0; a<n_tops; ++a) {
const int n_children = ui->treeWidget->topLevelItem(a)->childCount();
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a));
for(int b = 0; b<n_children; ++b) {
qtreewidgetitem_assign_qcheckbox(ui->treeWidget, ui->treeWidget->topLevelItem(a)->child(b));
}
}
在
createItem()
功能:
QTreeWidgetItem *MainWindow::createItem(const QString &name, const QString &iconPath)
{
auto *item = new QTreeWidgetItem(QStringList{name});
item->setCheckState(0, Qt::Unchecked);
item->setIcon(0, QIcon(iconPath));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
return item;
}
关于c++ - QTreeWidgetItem 的拖放不能正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64322036/
我已将 QTreeWidget 子类化(称为 ToolsSelectorWidget)并通过重写 QTreeWidget::dropEvent() 在其中启用重新排序 void ToolsSelect
我有一个 QTreeWidget有几列,我添加 QTreeWidgetItems到它。我尝试使第二列包含每个 Item 的数值所以我可以按这个值对项目进行排序 QTreeWidgetItem has
我必须用可能太长而无法放在一行中的项目(或项目的子项)填充 QTreeWidget,因此我正在寻找一种自动换行它们的方法。 我想 myQTreeWidget.setWordWrap(True) (通过
我有一个QTreeWidget,我想在某个索引处插入一个子项。我尝试过 void QTreeWidgetItem::insertChild ( int index, QTreeWidgetItem *
我对 QTreeWidget 进行了子类化为了重新实现 protected drag 的功能和 drop为了拖放一个QTreeWidget的 parent 和 child . 它几乎可以工作,问题 就
尝试将图标置于 QTreeWidgetItem 的中心。使用 setTextAlignment() 设置的格式仅适用于列中的文本。例如: item = new QTreeWidgetItem(tree
我需要创建支持格式化文本的 QTreeWidgetItems,例如: MyCreatedType - INTEGER(1) (即:上面的行应该有一个“正常”部分:MyCreatedType 和一个“格
我有一个QTreeWidget,我想在某个索引处插入一个子项。我尝试过 void QTreeWidgetItem::insertChild ( int index, QTreeWidgetItem *
我的QTreeWidget有一个列。它的项目有一个复选框、一个图标和文本。如果用户在某个项目内单击,我想知道该图标是否被单击。如何在 QTreeWidgetItem 中找到图标的位置和大小? 更新添加
有一个函数,当用户单击 QTreeWidgetItem 时触发。我想知道是否有一种方法可以以编程方式“单击”某个项目。我已经尝试过 .setCurrentIndex(index) .setCurren
此代码创建 QTreeWidget,并将 QComboBox 和 QLineEdit 设置为项目小部件。如果要执行以下步骤: 此对话框打开后... 单击该项目(而不是其项目小部件)。项目的背景颜色变为
我创建了一个带有多个 QTreeWidgetItem 的 QTreeWidget。 这是我的代码: //Defined property tree m_pPropertyTree = new QTre
我有以下数据: 1.0 2.0 3.1 4.1 5.2 其中Index.SubIndex但我想在 QTreeWidget 中显示如下: 索引 1 索引3 索引4 索引 2 索引 5 但我做了如下操作:
我有一个QTreeWidget,我希望某些行是不可选择的,这可以通过QTreeWidgetItem::setFlags(treeWidgetItem->flags() & ~Qt::ItemIsSel
我有一个 QTreeWidgetItem。我可以使用 setSelectionMode(QAbstractItemView::MultipleSelection) 设置多选模式。在这种情况下,用户无需
class A { QTreeWidget Tree; QTreeWidgetItem Item; QTreeWidgetItem* pointer; } A::A() { ... Item = QT
我正在尝试构建一个具有多个 QTreeWidgetItems 的 QTreeWidget,我尝试手动添加其中一些并且它可以工作。我的问题是如何使用 for 或 while 循环添加项目。 这是我的部分
我已经设置了我的 QTreeWidget,这样每个单元格都充满了组合框,但是我想在选定的组合框旁边创建一个文本编辑小部件(或覆盖现有的组合框),具体取决于用户选择的组合框项目。 我想我可以通过在初始设
我有一个带有 QTreeWidget 的 Qt 应用程序。在树小部件中,我有与我的应用程序的内部对象关联的项目。为了使该关联起作用,我希望每个树项目都保存一个内部对象的内部标识号。 推荐的方法是什么?
如何通过文本查找QTreeWidgetItem中的item?是否有 QTreeWidget 的 findItem 方法的模拟? 最佳答案 我相信您正在寻找的是 QTreeWidget 中的递归搜索。为
我是一名优秀的程序员,十分优秀!