Modifying the TextureList to use EventBrowser-style chooser.

This commit is contained in:
Kevin McCullough
2020-10-06 14:14:14 -07:00
committed by Baldur Karlsson
parent 0049ed2e84
commit e213cfafa9
7 changed files with 285 additions and 232 deletions
+62
View File
@@ -28,11 +28,13 @@
#include <QCloseEvent>
#include <QCollator>
#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QElapsedTimer>
#include <QFileSystemModel>
#include <QFontDatabase>
#include <QGridLayout>
#include <QGuiApplication>
#include <QHeaderView>
#include <QJsonDocument>
#include <QKeyEvent>
#include <QLabel>
@@ -51,6 +53,7 @@
#include <QTextDocument>
#include <QtMath>
#include "Code/Resources.h"
#include "Widgets/Extended/RDListWidget.h"
#include "Widgets/Extended/RDTreeWidget.h"
// normally this is in the renderdoc core library, but it's needed for the 'unknown enum' path,
@@ -2669,3 +2672,62 @@ void LambdaThread::windowsSetName()
}
#endif
void UpdateVisibleColumns(rdcstr windowTitle, int columnCount, QHeaderView *header,
const QStringList &headers)
{
QDialog dialog;
RDListWidget list;
QDialogButtonBox buttons;
dialog.setWindowTitle(windowTitle);
dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
for(int visIdx = 0; visIdx < columnCount; visIdx++)
{
int logIdx = header->logicalIndex(visIdx);
QListWidgetItem *item = new QListWidgetItem(headers[logIdx], &list);
item->setData(Qt::UserRole, logIdx);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
// The first column must stay enabled
if(logIdx == 0)
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
item->setCheckState(header->isSectionHidden(logIdx) ? Qt::Unchecked : Qt::Checked);
}
list.setSelectionMode(QAbstractItemView::SingleSelection);
list.setDragDropMode(QAbstractItemView::DragDrop);
list.setDefaultDropAction(Qt::MoveAction);
buttons.setOrientation(Qt::Horizontal);
buttons.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
buttons.setCenterButtons(true);
QObject::connect(&buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
QObject::connect(&buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
QVBoxLayout *layout = new QVBoxLayout(&dialog);
layout->addWidget(new QLabel(QString::fromUtf8("Select the columns to enable."), &dialog));
layout->addWidget(&list);
layout->addWidget(&buttons);
if(!RDDialog::show(&dialog))
return;
for(int i = 0; i < columnCount; i++)
{
int logicalIdx = list.item(i)->data(Qt::UserRole).toInt();
if(list.item(i)->checkState() == Qt::Unchecked)
header->hideSection(logicalIdx);
else
header->showSection(logicalIdx);
header->moveSection(header->visualIndex(logicalIdx), i);
}
}
+5
View File
@@ -37,6 +37,8 @@
#include <QStyledItemDelegate>
#include "Code/Interface/QRDInterface.h"
class QHeaderView;
template <typename T>
inline T AlignUp(T x, T a)
{
@@ -733,3 +735,6 @@ float getLuminance(const QColor &col);
QColor contrastingColor(const QColor &col, const QColor &defaultCol);
void *AccessWaylandPlatformInterface(const QByteArray &resource, QWindow *window);
void UpdateVisibleColumns(rdcstr windowTitle, int columnCount, QHeaderView *header,
const QStringList &headers);
@@ -241,6 +241,7 @@ public:
QAbstractItemDelegate *itemDelegate() const;
void setColumns(const QStringList &columns);
const QStringList &getHeaders() const { return m_headers; }
QString headerText(int column) const { return m_headers[column]; }
void setHeaderText(int column, const QString &text);
RDTreeWidgetItem *selectedItem() const;
+2 -56
View File
@@ -740,62 +740,8 @@ void EventBrowser::on_exportDraws_clicked()
void EventBrowser::on_colSelect_clicked()
{
QDialog dialog;
RDListWidget list;
QDialogButtonBox buttons;
dialog.setWindowTitle(tr("Select Event Browser Columns"));
dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
for(int visIdx = 0; visIdx < COL_COUNT; visIdx++)
{
int logIdx = ui->events->header()->logicalIndex(visIdx);
QListWidgetItem *item = new QListWidgetItem(ui->events->headerText(logIdx), &list);
item->setData(Qt::UserRole, logIdx);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
// this must stay enabled
if(logIdx == COL_NAME)
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
item->setCheckState(ui->events->header()->isSectionHidden(logIdx) ? Qt::Unchecked : Qt::Checked);
}
list.setSelectionMode(QAbstractItemView::SingleSelection);
list.setDragDropMode(QAbstractItemView::DragDrop);
list.setDefaultDropAction(Qt::MoveAction);
buttons.setOrientation(Qt::Horizontal);
buttons.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
buttons.setCenterButtons(true);
QObject::connect(&buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
QObject::connect(&buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
QVBoxLayout *layout = new QVBoxLayout(&dialog);
layout->addWidget(new QLabel(tr("Select the columns to enable."), &dialog));
layout->addWidget(&list);
layout->addWidget(&buttons);
int res = RDDialog::show(&dialog);
if(res)
{
for(int i = 0; i < COL_COUNT; i++)
{
int logicalIdx = list.item(i)->data(Qt::UserRole).toInt();
if(list.item(i)->checkState() == Qt::Unchecked)
ui->events->header()->hideSection(logicalIdx);
else
ui->events->header()->showSection(logicalIdx);
ui->events->header()->moveSection(ui->events->header()->visualIndex(logicalIdx), i);
}
}
UpdateVisibleColumns(tr("Select Event Browser Columns"), COL_COUNT, ui->events->header(),
ui->events->getHeaders());
}
QString EventBrowser::GetExportDrawcallString(int indent, bool firstchild,
+161 -166
View File
@@ -38,6 +38,7 @@
#include "Code/QRDUtils.h"
#include "Code/Resources.h"
#include "Dialogs/TextureSaveDialog.h"
#include "Widgets/Extended/RDHeaderView.h"
#include "Widgets/ResourcePreview.h"
#include "Widgets/TextureGoto.h"
#include "flowlayout/FlowLayout.h"
@@ -349,141 +350,19 @@ const ShaderBindpointMapping &Following::GetMapping(ICaptureContext &ctx)
return GetMapping(ctx, Stage);
}
class TextureListItemModel : public QAbstractItemModel
namespace TextureListFilter
{
public:
enum FilterType
{
Textures,
RenderTargets,
String
};
TextureListItemModel(ICaptureContext &ctx, QWidget *parent)
: QAbstractItemModel(parent), m_Ctx(ctx)
{
goArrow.addPixmap(Pixmaps::action(parent), QIcon::Normal, QIcon::Off);
goArrow.addPixmap(Pixmaps::action_hover(parent), QIcon::Normal, QIcon::Off);
}
void reset(FilterType type, const QString &filter)
{
const rdcarray<TextureDescription> src = m_Ctx.GetTextures();
texs.clear();
texs.reserve(src.count());
emit beginResetModel();
TextureCategory rtFlags = TextureCategory::ColorTarget | TextureCategory::DepthTarget;
for(const TextureDescription &t : src)
{
if(type == Textures)
{
if(!(t.creationFlags & rtFlags))
texs.push_back(t);
}
else if(type == RenderTargets)
{
if((t.creationFlags & rtFlags))
texs.push_back(t);
}
else
{
if(filter.isEmpty())
texs.push_back(t);
else if(QString(m_Ctx.GetResourceName(t.resourceId)).contains(filter, Qt::CaseInsensitive))
texs.push_back(t);
}
}
emit endResetModel();
}
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
{
if(row < 0 || row >= rowCount())
return QModelIndex();
return createIndex(row, 0);
}
QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); }
int rowCount(const QModelIndex &parent = QModelIndex()) const override { return texs.count(); }
int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 1; }
Qt::ItemFlags flags(const QModelIndex &index) const override
{
if(!index.isValid())
return 0;
return QAbstractItemModel::flags(index);
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if(index.isValid())
{
if(role == Qt::DisplayRole)
{
if(index.row() >= 0 && index.row() < texs.count())
return m_Ctx.GetResourceName(texs[index.row()].resourceId);
}
if(role == Qt::UserRole)
{
return QVariant::fromValue(texs[index.row()].resourceId);
}
if(role == Qt::DecorationRole)
{
return QVariant(goArrow);
}
}
return QVariant();
}
private:
ICaptureContext &m_Ctx;
QVector<TextureDescription> texs;
QIcon goArrow;
};
class TextureListItemDelegate : public QItemDelegate
enum Columns
{
public:
TextureListItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const override
{
if(index.isValid())
{
QStyleOptionViewItem option = opt;
option.decorationAlignment = Qt::AlignBaseline | Qt::AlignRight;
painter->eraseRect(option.rect);
QIcon icon = index.model()->data(index, Qt::DecorationRole).value<QIcon>();
drawBackground(painter, option, index);
if(option.state & QStyle::State_MouseOver)
drawDecoration(painter, option, option.rect,
icon.pixmap(option.decorationSize, QIcon::Active));
else
drawDecoration(painter, option, option.rect,
icon.pixmap(option.decorationSize, QIcon::Normal));
drawDisplay(painter, option, option.rect,
index.model()->data(index, Qt::DisplayRole).toString());
drawFocus(painter, option, option.rect);
if(option.state & QStyle::State_MouseOver)
{
QRect r = option.rect;
r.adjust(0, 0, -1, -1);
painter->drawRect(r);
}
}
}
Column_TexName,
Column_TexWidth,
Column_TexHeight,
Column_TexDepth,
Column_MipsCount,
Column_TexFormat,
Column_Count,
};
}
TextureDescription *TextureViewer::GetCurrentTexture()
{
@@ -635,6 +514,9 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
});
}
QObject::connect(ui->textureList, &RDTreeWidget::itemActivated, this,
&TextureViewer::texture_itemActivated);
QWidget *renderContainer = ui->renderContainer;
ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace);
@@ -643,6 +525,12 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
ToolWindowManager::DisableDraggableTab |
ToolWindowManager::AlwaysDisplayFullTabs);
ui->dockarea->addToolWindow(
ui->textureListFrame,
ToolWindowManager::AreaReference(ToolWindowManager::NoArea,
ui->dockarea->areaOf(renderContainer), 0.25f));
ui->dockarea->setToolWindowProperties(ui->textureListFrame, ToolWindowManager::HideOnClose);
ui->dockarea->addToolWindow(ui->inputThumbs, ToolWindowManager::AreaReference(
ToolWindowManager::RightOf,
ui->dockarea->areaOf(renderContainer), 0.25f));
@@ -659,9 +547,6 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
ui->dockarea->areaOf(ui->outputThumbs), 0.25f));
ui->dockarea->setToolWindowProperties(ui->pixelContextLayout, ToolWindowManager::HideCloseButton);
ui->dockarea->addToolWindow(ui->textureListFrame, ToolWindowManager::NoArea);
ui->dockarea->setToolWindowProperties(ui->textureListFrame, ToolWindowManager::HideOnClose);
ui->dockarea->setAllowFloatingWindow(false);
renderContainer->setWindowTitle(tr("Unbound"));
@@ -670,8 +555,6 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
ui->inputThumbs->setWindowTitle(tr("Inputs"));
ui->textureListFrame->setWindowTitle(tr("Texture List"));
ui->textureList->setHoverCursor(Qt::PointingHandCursor);
m_Goto = new TextureGoto(this, [this](QPoint p) { GotoLocation(p.x(), p.y()); });
QVBoxLayout *vertical = new QVBoxLayout(this);
@@ -749,9 +632,20 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
ui->textureListFilter->addItems({QString(), tr("Textures"), tr("Render Targets")});
ui->textureList->setModel(new TextureListItemModel(m_Ctx, this));
ui->textureList->setItemDelegate(new TextureListItemDelegate(ui->textureList));
ui->textureList->setColumns({tr("Texture Name"), tr("Width"), tr("Height"), tr("Depth/Slices"),
tr("Mips Count"), tr("Format"), tr("Go")});
ui->textureList->setHoverIconColumn(6, Icons::action(), Icons::action_hover());
ui->textureList->viewport()->setAttribute(Qt::WA_Hover);
ui->textureList->setMouseTracking(true);
{
RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this);
ui->textureList->setHeader(header);
header->setColumnStretchHints({1, -1, -1, -1, -1, -1, -1});
}
ui->textureList->header()->sortIndicatorChanged(TextureListFilter::Column_TexName,
Qt::SortOrder::DescendingOrder);
ui->zoomOption->setCurrentText(QString());
ui->fitToWindow->toggle();
@@ -2881,10 +2775,6 @@ void TextureViewer::OnCaptureLoaded()
ui->debugPixelContext->setEnabled(false);
ui->pixelHistory->setToolTip(QString());
TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model();
model->reset(TextureListItemModel::String, QString());
m_TexDisplay.backgroundColor =
backCol.isValid() ? FloatVector(backCol.redF(), backCol.greenF(), backCol.blueF(), 1.0f)
: FloatVector();
@@ -2977,6 +2867,71 @@ void TextureViewer::Reset()
UI_UpdateChannels();
}
void TextureViewer::refreshTextureList()
{
refreshTextureList(FilterType::None, QString());
}
void addToRoot(RDTreeWidgetItem *root, const TextureDescription &t)
{
const QVariant &res = QVariant::fromValue(t.resourceId);
RDTreeWidgetItem *child =
new RDTreeWidgetItem({res, t.width, t.height, (3 == t.dimension ? t.depth : t.arraysize),
t.mips, t.format.Name(), QString()});
child->setTag(res);
root->addChild(child);
}
void TextureViewer::refreshTextureList(FilterType filterType, const QString &filterStr)
{
ui->textureList->beginUpdate();
ui->textureList->clearSelection();
ui->textureList->clear();
RDTreeWidgetItem *root = ui->textureList->invisibleRootItem();
TextureCategory rtFlags = TextureCategory::ColorTarget | TextureCategory::DepthTarget;
for(const TextureDescription &t : m_Ctx.GetTextures())
{
if(filterType == FilterType::Textures)
{
if(!(t.creationFlags & rtFlags))
addToRoot(root, t);
}
else if(filterType == FilterType::RenderTargets)
{
if((t.creationFlags & rtFlags))
addToRoot(root, t);
}
else
{
if(filterStr.isEmpty())
{
addToRoot(root, t);
}
else
{
if(QString(m_Ctx.GetResourceName(t.resourceId)).contains(filterStr, Qt::CaseInsensitive) ||
QString::number(t.width).contains(filterStr, Qt::CaseInsensitive) ||
QString::number(t.height).contains(filterStr, Qt::CaseInsensitive) ||
QString::number((3 == t.dimension ? t.depth : t.arraysize))
.contains(filterStr, Qt::CaseInsensitive) ||
QString::number(t.mips).contains(filterStr, Qt::CaseInsensitive) ||
QString(t.format.Name()).contains(filterStr, Qt::CaseInsensitive))
addToRoot(root, t);
}
}
}
ui->textureList->setSelectedItem(root);
ui->textureList->setUpdatesEnabled(true);
ui->textureList->endUpdate();
}
void TextureViewer::OnCaptureClosed()
{
Reset();
@@ -3145,6 +3100,18 @@ QVariant TextureViewer::persistData()
{
QVariantMap state = ui->dockarea->saveState();
QVariantList columns;
for(int i = 0; i < TextureListFilter::Column_Count; i++)
{
QVariantMap col;
bool hidden = ui->textureList->header()->isSectionHidden(i);
col[lit("hidden")] = hidden;
columns.push_back(col);
}
state[lit("columns")] = columns;
state[lit("backCol")] = backCol;
state[lit("checker")] = !backCol.isValid();
@@ -3155,6 +3122,19 @@ void TextureViewer::setPersistData(const QVariant &persistData)
{
QVariantMap state = persistData.toMap();
QVariantList columns = state[lit("columns")].toList();
for(int i = 0; i < columns.count() && i < TextureListFilter::Column_Count; i++)
{
QVariantMap col = columns[i].toMap();
bool hidden = col[lit("hidden")].toBool();
if(hidden)
ui->textureList->header()->hideSection(i);
else
ui->textureList->header()->showSection(i);
}
backCol = state[lit("backCol")].value<QColor>();
bool checker = state[lit("checker")].value<bool>();
@@ -3958,7 +3938,7 @@ void TextureViewer::on_texListShow_clicked()
ui->textureListFilter->setCurrentText(QString());
ui->dockarea->moveToolWindow(
ui->textureListFrame,
ToolWindowManager::AreaReference(ToolWindowManager::LeftOf,
ToolWindowManager::AreaReference(ToolWindowManager::BottomOf,
ui->dockarea->areaOf(ui->renderContainer), 0.2f));
ui->dockarea->setToolWindowProperties(ui->textureListFrame, ToolWindowManager::HideOnClose);
}
@@ -3969,40 +3949,55 @@ void TextureViewer::on_cancelTextureListFilter_clicked()
ui->textureListFilter->setCurrentText(QString());
}
void TextureViewer::on_colSelect_clicked()
{
QStringList headers;
for(int i = 0; i < TextureListFilter::Column_Count; ++i)
{
headers.push_back(
ui->textureList->model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
}
UpdateVisibleColumns(tr("Select Texture List Columns"), TextureListFilter::Column_Count,
ui->textureList->header(), headers);
}
void TextureViewer::on_textureListFilter_editTextChanged(const QString &text)
{
TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model();
if(model == NULL)
return;
model->reset(TextureListItemModel::String, text);
refreshTextureList(FilterType::String, text);
}
void TextureViewer::on_textureListFilter_currentIndexChanged(int index)
{
refreshTextureList();
if(ui->textureListFilter->currentIndex() == 1)
refreshTextureList(FilterType::Textures, QString());
else if(ui->textureListFilter->currentIndex() == 2)
refreshTextureList(FilterType::RenderTargets, QString());
else
refreshTextureList(FilterType::String, ui->textureListFilter->currentText());
}
void TextureViewer::refreshTextureList()
void TextureViewer::texture_itemActivated(RDTreeWidgetItem *item, int column)
{
TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model();
if(model == NULL)
QVariant tag = item->tag();
if(!tag.canConvert<ResourceId>())
return;
if(ui->textureListFilter->currentIndex() == 1)
model->reset(TextureListItemModel::Textures, QString());
else if(ui->textureListFilter->currentIndex() == 2)
model->reset(TextureListItemModel::RenderTargets, QString());
else
model->reset(TextureListItemModel::String, ui->textureListFilter->currentText());
}
TextureDescription *tex = m_Ctx.GetTexture(tag.value<ResourceId>());
if(!tex)
return;
void TextureViewer::on_textureList_clicked(const QModelIndex &index)
{
ResourceId id = index.model()->data(index, Qt::UserRole).value<ResourceId>();
ViewTexture(id, false);
if(tex->type == TextureType::Buffer)
{
IBufferViewer *viewer = m_Ctx.ViewTextureAsBuffer(
tex->resourceId, Subresource(), BufferFormatter::GetTextureFormatString(*tex));
m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this);
}
else
{
ViewTexture(tex->resourceId, true);
}
}
bool TextureViewer::canCompileCustomShader(ShaderEncoding encoding)
+13 -1
View File
@@ -36,6 +36,7 @@ namespace Ui
class TextureViewer;
}
class RDTreeWidgetItem;
class ResourcePreview;
class ThumbnailStrip;
class TextureGoto;
@@ -128,6 +129,15 @@ private:
Q_PROPERTY(QVariant persistData READ persistData WRITE setPersistData DESIGNABLE false SCRIPTABLE false)
// Texture List
enum class FilterType
{
None,
Textures,
RenderTargets,
String
};
public:
explicit TextureViewer(ICaptureContext &ctx, QWidget *parent = 0);
~TextureViewer();
@@ -182,7 +192,8 @@ private slots:
void on_cancelTextureListFilter_clicked();
void on_textureListFilter_editTextChanged(const QString &text);
void on_textureListFilter_currentIndexChanged(int index);
void on_textureList_clicked(const QModelIndex &index);
void on_colSelect_clicked();
void texture_itemActivated(RDTreeWidgetItem *item, int column);
// manual slots
void render_mouseClick(QMouseEvent *e);
@@ -243,6 +254,7 @@ private:
void Reset();
void refreshTextureList();
void refreshTextureList(FilterType filterType, const QString &filterStr);
ResourcePreview *UI_CreateThumbnail(ThumbnailStrip *strip);
void UI_CreateThumbnails();
+41 -9
View File
@@ -1308,10 +1308,25 @@ See FAQ on &quot;Gamma display of linear data&quot;</string>
</property>
</widget>
</item>
</layout>
<item>
<widget class="QToolButton" name="colSelect">
<property name="toolTip">
<string>Select visible columns</string>
</property>
<property name="icon">
<iconset resource="../Resources/resources.qrc">
<normaloff>:/timeline_marker.png</normaloff>:/timeline_marker.png
</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="RDListView" name="textureList">
<widget class="RDTreeWidget" name="textureList">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
@@ -1324,18 +1339,30 @@ See FAQ on &quot;Gamma display of linear data&quot;</string>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="defaultDropAction">
<enum>Qt::CopyAction</enum>
<property name="indentation">
<number>0</number>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
<property name="rootIsDecorated">
<bool>true</bool>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="uniformItemSizes">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="clearSelectionOnFocusLoss">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
@@ -1379,6 +1406,11 @@ See FAQ on &quot;Gamma display of linear data&quot;</string>
<extends>QToolButton</extends>
<header>Widgets/Extended/RDToolButton.h</header>
</customwidget>
<customwidget>
<class>RDTreeWidget</class>
<extends>QTreeView</extends>
<header>Widgets/Extended/RDTreeWidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../Resources/resources.qrc"/>