我有一个自定义QTreeWidget
子类,我用它来显示曲目名称/等。在我的MIDI编辑器项目(https://github.com/waddlesplash/ragingmidi)中。我想在这个树小部件中添加另一个列,但是一个小部件占用了整个列而不是每个项目的小部件。
这是可能的,还是我必须找出其他解决方案?
编辑:我正在努力完成以下任务:http://www.anvilstudio.com/compose.jpg - 查看标题视图中的最后一列“(L / R余额后第3位)”行/注释(完全是自定义的,无论如何用VB.NET和封闭源编写)。
编辑2 :您无法看到它,但最后一列滚动而其他列在上图中滚动。在他们的方法中,您必须使用鼠标滚动。我想要一个滚动条。
答案 0 :(得分:2)
查看Qt文档,似乎有一些选项可以实现这一目标,但在确定哪种方法最适合您的需求之前,有一些重要因素需要解决。
如果您的自定义树列内容是静态的并且存在一对一的行映射,则使用QTreeWidget::setItemWidget ( QTreeWidgetItem * item, int column, QWidget * widget )函数就足够了。
但是,如果自定义树列的内容是动态的,或者没有一对一的行映射,则需要采用更复杂的方法。
如QTreeWidget文档中所述; “如果要显示自定义动态内容或实现自定义编辑器窗口小部件,请使用QTreeView和子类QItemDelegate。”
QItemDelegate及其子类为插入Qt项目视图的项目(如QTreeView,QListView,QTableView等)执行所有绘图工具。这实际上允许您控制插入到QTreeView类中的任何项目的所有绘图操作,除了能够跨多行扩展内容之外,还可以绘制动态内容。
为QListWidget实现了类似的方法之后,我建议使用QStyledItemDelegate代替QItemDelegate,因为它允许您更轻松地将此小部件与应用程序的样式布局集成。由于您没有详细说明此自定义QWidget的确切用法,因此您可能还需要QItemEditorCreator,QItemEditorCreatorBase和QItemEditorFactory提供的其他工具。如果可以的话,我会发布我在这里开发的类似小部件,但遗憾的是它是专有软件套件的一部分。
答案 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时,所有列都适合,而且屏幕又小了?
除非有人有更好的解决方案或反对意见,为什么这是一个坏主意,这就是我要这样做的方式。