你能设置一个QWidget来占用QTreeWidget的整个列吗?

时间:2013-03-08 00:21:50

标签: qt qt5 qtreewidget

我有一个自定义QTreeWidget子类,我用它来显示曲目名称/等。在我的MIDI编辑器项目(https://github.com/waddlesplash/ragingmidi)中。我想在这个树小部件中添加另一个列,但是一个小部件占用了整个列而不是每个项目的小部件。

这是可能的,还是我必须找出其他解决方案?

编辑:我正在努力完成以下任务:http://www.anvilstudio.com/compose.jpg - 查看标题视图中的最后一列“(L / R余额后第3位)”行/注释(完全是自定义的,无论如何用VB.NET和封闭源编写)。

编辑2 :您无法看到它,但最后一列滚动而其他列在上图中滚动。在他们的方法中,您必须使用鼠标滚动。我想要一个滚动条。

3 个答案:

答案 0 :(得分:2)

查看Qt文档,似乎有一些选项可以实现这一目标,但在确定哪种方法最适合您的需求之前,有一些重要因素需要解决。

  1. 此自定义树列中显示的内容是静态还是动态?
  2. 是否存在从QTreeWidget到自定义树列的行的一对一映射?
  3. 如果您的自定义树列内容是静态的并且存在一对一的行映射,则使用QTreeWidget::setItemWidget ( QTreeWidgetItem * item, int column, QWidget * widget )函数就足够了。

    但是,如果自定义树列的内容是动态的,或者没有一对一的行映射,则需要采用更复杂的方法。

    如QTreeWidget文档中所述; “如果要显示自定义动态内容或实现自定义编辑器窗口小部件,请使用QTreeView和子类QItemDelegate。”

    QItemDelegate及其子类为插入Qt项目视图的项目(如QTreeView,QListView,QTableView等)执行所有绘图工具。这实际上允许您控制插入到QTreeView类中的任何项目的所有绘图操作,除了能够跨多行扩展内容之外,还可以绘制动态内容。

    为QListWidget实现了类似的方法之后,我建议使用QStyledItemDelegate代替QItemDelegate,因为它允许您更轻松地将此小部件与应用程序的样式布局集成。由于您没有详细说明此自定义QWidget的确切用法,因此您可能还需要QItemEditorCreatorQItemEditorCreatorBaseQItemEditorFactory提供的其他工具。如果可以的话,我会发布我在这里开发的类似小部件,但遗憾的是它是专有软件套件的一部分。

答案 1 :(得分:0)

这并不完全漂亮,因为当自定义窗口小部件位于最右侧列并且列变窄时,它会出现问题,但这是一个开始:

#include <QtGui>

class TreeWidget : public QTreeWidget
{
    Q_OBJECT
public:
    TreeWidget();

    QRect columnRect(int column) const;

private slots:
    void repositionColumnWidget();

private:
    QPushButton * mColumnWidget;
};

TreeWidget::TreeWidget()
    : mColumnWidget(new QPushButton("Custom Column Button", viewport()))
{
    const int COLUMN_COUNT = 6;
    setColumnCount(COLUMN_COUNT);
    for (int row = 0; row < 400; ++row)
    {
        QStringList columns;
        for (int column = 0; column < COLUMN_COUNT; ++column)
        {
            columns << QString("row %1, column %2").arg(row + 1).arg(column + 1);
        }
        addTopLevelItem(new QTreeWidgetItem(columns));
    }
    for (int column = 0; column < COLUMN_COUNT; ++column)
    {
        resizeColumnToContents(column);
    }
    repositionColumnWidget();
    mColumnWidget->show();
    connect(header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(repositionColumnWidget()));
    connect(header(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(repositionColumnWidget()));
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget()));
    connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(repositionColumnWidget()));
}

QRect TreeWidget::columnRect(int column) const
{
    int itemCount = topLevelItemCount();
    if (!itemCount)
    {
        return QRect();
    }
    int columnX = header()->sectionViewportPosition(column);
    int columnY = visualItemRect(topLevelItem(0)).top();
    int columnWidth = header()->sectionSize(column);
    int columnHeight = visualItemRect(topLevelItem(itemCount-1)).bottom() - columnY + 1;

    return QRect(columnX, columnY, columnWidth, columnHeight);
}

void TreeWidget::repositionColumnWidget()
{
    mColumnWidget->setGeometry(columnRect(3));
}

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

    TreeWidget treeWidget;

    treeWidget.resize(800, 600);
    treeWidget.show();

    return a.exec();
}

#include "main.moc"

答案 2 :(得分:0)

一周后我想到的是劫持QTreeWidget的H滚动条,然后让滚动条滚动到最后一列。因为现在,当窗口为620x670px时,所有列都适合,而且屏幕又小了?

除非有人有更好的解决方案或反对意见,为什么这是一个坏主意,这就是我要这样做的方式。