====== Qt Properties ======
Typové informace knihovny Qt, tentokrát v jazyce C++
===== Strom grafický prvků =====
Třída //TreeItem// v proměnné **obj** uschovává ukazatel na jeden grafický prvek
class TreeItem : public QTreeWidgetItem
{
public:
QObject * obj;
TreeItem () : obj (nullptr) { }
};
class MainWindow : public QMainWindow
{
/* ... */
private slots:
void on_treeWidget_itemDoubleClicked (QTreeWidgetItem *item, int column);
private :
void showBranch (QTreeWidgetItem * target, QObject * obj);
QTableWidgetItem * addLine (QString name, QString value);
};
Metoda **showBranch** do stromu přidá uzel pro jeden grafický objekt
* **cls = obj->metaObject()** jsou typové informace o objektu
* **cls->className ()** pak jméno typu
* pomocí **obj->children()** získáme seznam vnořených grafických prvků
* zavoláme rekurzivně metodu //showBranch// pro vnořené prvky
#include
void MainWindow::showBranch (QTreeWidgetItem *target, QObject *obj)
{
TreeItem * branch = new TreeItem ();
target->addChild (branch);
const QMetaObject * cls = obj->metaObject();
branch->setText (0, obj->objectName() + " : " + cls->className ());
branch->obj = obj;
for ( QObject * t : obj->children() )
showBranch (branch, t);
}
===== Tabulka vlastností =====
Metoda **addLine** přidá do tabulky jednu řádku obsahující jméno a hodnotu
QTableWidgetItem * MainWindow::addLine (QString name, QString value)
{
ui->tableWidget->setHorizontalHeaderLabels (QStringList () << "Name" << "Value");
int inx = ui->tableWidget->rowCount ();
ui->tableWidget->setRowCount (inx +1);
QTableWidgetItem * cell = new QTableWidgetItem ();
cell ->setText (name);
ui->tableWidget->setItem(inx, 0, cell);
cell = new QTableWidgetItem ();
cell ->setText (value);
ui->tableWidget->setItem(inx, 1, cell);
return cell;
}
Pokud "klikneme" do stromu
* zkusíme přetypovat **QTreeWidgetItem** na **TreeItem**
* vymažeme tabulku, nastavíme počet sloupců
* do **obj** uložíme ukazatel na objekt zobrazovaný v daném uzlu stromu
* do **cls** typové informace o tomto objektu
* v typových informací opět nalezneme jméno typu daného objektu a přidáme jako první řádku do tabulky
* počet vlastností daného objektu získáme pomocí **cls->propertyCount()**
* popisy jednotlivých vlastností: **prop = cls->property (i)**
* jméno vlastnosti: **prop.name()**
* hodnotu vlastnosti *prop** pro objekt *obj** získáme pomocí **prop.read (obj)**
* výsledek je univerzálního typu **QVariant**, text získáme metodou **toString**
* pokud je výsledek typu **QIcon** přidáme do tabulky i obrázek
void MainWindow::on_treeWidget_itemDoubleClicked (QTreeWidgetItem *item, int column)
{
TreeItem * node = dynamic_cast < TreeItem * > (item);
if (node != nullptr)
{
ui->tableWidget->clear ();
ui->tableWidget->setColumnCount(2);
ui->tableWidget->setRowCount(0);
QObject * obj = node->obj;
const QMetaObject * cls = obj->metaObject();
addLine ("class name", cls->className());
int cnt = cls->propertyCount();
for (int i = 0; i < cnt; i++)
{
QMetaProperty prop = cls->property (i);
QVariant v = prop.read (obj);
QTableWidgetItem * cell = addLine (prop.name(), v.toString());
if (v.type() == QVariant::Icon)
cell->setData (Qt::DecorationRole, v);
}
}
}
===== Hlavní okno =====
Hlavnímu oknu nastavíme ikonku se sluníčkem
( na obrázku se podívejte na vlastnost //windowIcon// )
Následující cyklus ukazuje jak získat ukazatel na okno, pokud mám jen ukazatel na jeden grafický prvek v okně.
QObject * p = ui->treeWidget;
while (p->parent() != nullptr)
p = p->parent ();
Pomocí //showBranch// zobrazíme strom grafických prvků našeho okna.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowIcon (QIcon::fromTheme("weather-clear"));
QObject * p = ui->treeWidget;
while (p->parent() != nullptr)
p = p->parent ();
showBranch (ui->treeWidget->invisibleRootItem(), p);
ui->treeWidget->expandAll ();
}
{{qtproperties.png}}
[[https://gitlab.fjfi.cvut.cz/culikzde/uop/-/tree/master/QtProperties|gitlab]]