====== 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]]