Qt écrit les propriétés du concepteur-utilisateur des propriétés de contrôle

Introduction

Les propriétés utilisateur sont une fonction nouvellement ajoutée ultérieurement. Si le contrôle personnalisé adopte la propriété modifiée Q_PROPERTY, elle sera automatiquement reconnue dans la barre de propriétés. C'est ce qu'on appelle généralement la propriété de contrôle. Dans le logiciel de conception de configuration, il n'y a que les propriétés de contrôle de le contrôle lui-même. Ce n'est toujours pas suffisant. Après tout, ces propriétés sont uniquement basées sur l'apparence et ne peuvent pas représenter les propriétés d'un certain périphérique. Par conséquent, en plus des propriétés de ce contrôle, des propriétés utilisateur doivent être ajoutées pour stocker le périphérique. propriétés associées au contrôle, telles que le numéro de périphérique, le nom de périphérique, la position géographique et d'autres informations, et ces informations doivent être les mêmes que les attributs de contrôle et peuvent être importées et exportées vers des fichiers XML. Il peut prendre en charge plusieurs attributs utilisateur au niveau en même temps. L'utilisateur remplit lui-même le nom et la valeur. Le nom et la valeur prennent en charge la description chinoise. Dans le fichier XML, afin de faire la distinction entre les propriétés de l'utilisateur et les propriétés du contrôle, les propriétés de l'utilisateur sont spécifiquement représentées en ajoutant l'utilisateur. préfixe devant eux. De cette façon, lorsque le fichier XML est lu pour charger le contrôle, toutes les propriétés commençant par user- sont reconnues et stockées dans la liste des propriétés utilisateur du contrôle.

Depuis l'introduction du mécanisme d'attributs utilisateur, les fonctions existantes du contrôle ont été considérablement étendues. Cela équivaut à lier N données personnalisées. Ces attributs utilisateur peuvent être définis directement à l'aide de setProperty, puis lus via la propriété. Dans l'ordre, prend en charge les attributs chinois convertissez lorsque vous devez définir des attributs : widget->setProperty(name.toStdString().c_str(), value);

Adresse de l'expérience : https://gitee.com/feiyangqingyun/QUCSDK
https://github.com/feiyangqingyun/qucsdk

2. Fonctions mises en œuvre

  1. Charge automatiquement tous les contrôles dans le fichier du plug-in pour générer une liste. Par défaut, plus de 120 contrôles sont inclus.
  2. Faites glisser vers le canevas pour générer automatiquement le contrôle correspondant, ce que vous voyez est ce que vous obtenez.
  3. Dans la barre de propriétés chinoise à droite, la modification des propriétés correspondantes est immédiatement appliquée au contrôle sélectionné correspondant. Elle est intuitive et concise, et convient très bien aux débutants.
  4. Le mécanisme de mappage de traduction de texte de la barre d'attributs d'origine est extrêmement efficace et peut facilement étendre la barre d'attributs dans d'autres langues.
  5. Les propriétés de tous les contrôles sont automatiquement extraites et affichées dans la barre de propriétés à droite, y compris les listes déroulantes de valeurs d'énumération, etc.
  6. Prend en charge la sélection manuelle des fichiers de plug-in et l'importation externe des fichiers de plug-in.
  7. Toutes les informations de configuration de contrôle du canevas actuel peuvent être exportées vers un fichier XML.
  8. Vous pouvez sélectionner manuellement le fichier XML pour ouvrir la disposition du contrôle et charger automatiquement le contrôle en fonction du fichier XML.
  9. Vous pouvez tirer la barre coulissante, cocher la case des données simulées ou saisir la zone de texte pour générer des données et appliquer tous les contrôles.
  10. La commande prend en charge l'extraction et le redimensionnement dans huit directions, s'adapte à n'importe quelle résolution et peut affiner la position vers le haut, le bas, la gauche et la droite sur le clavier.
  11. Il ouvre trois façons de définir les données : la collecte de ports série, la collecte de réseaux et la collecte de bases de données.
  12. Le code est extrêmement concis et les commentaires sont très détaillés. Il peut être utilisé comme prototype de configuration pour étendre plus de fonctions par vous-même.
  13. Écrit en Qt pur, il prend en charge n'importe quelle version de Qt + n'importe quel compilateur + n'importe quel système.

3. Dessin d'effet

4. Code de base

void frmMain::openFile(const QString &fileName)
{
    //如果控件列表没有则不用继续
    if (ui->listWidget->count() == 0) {
        return;
    }

    //打开文件
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        return;
    }

    //将文件填充到dom容器
    QDomDocument doc;
    if (!doc.setContent(&file)) {
        file.close();
        return;
    }

    file.close();

    listSelect.clear();
    listUserProperty.clear();
    xmlName = fileName;

    //先清空原有控件
    QList<QWidget *> widgets = ui->centralwidget->findChildren<QWidget *>();
    qDeleteAll(widgets);
    widgets.clear();

    //先判断根元素是否正确
    QDomElement docElem = doc.documentElement();
    if (docElem.tagName() == "canvas") {
        QDomNode node = docElem.firstChild();
        QDomElement element = node.toElement();
        while(!node.isNull()) {
            //控件名称
            QString name = element.tagName();
            //取出当前控件在控件列表中的索引,如果不存在则意味着配置文件中的该控件不存在了
            int index = listNames.indexOf(name);
            if (index < 0) {
                continue;
            }

            //存储控件的坐标位置和宽度高度
            int x, y, width, height;
            //存储自定义控件属性
            QList<QPair<QString, QVariant> > propertys;
            //存储控件自定义属性
            QStringList userProperty;

            //节点名称不为空才继续
            if (!name.isEmpty()) {
                //遍历节点的属性名称和属性值
                QDomNamedNodeMap attrs = element.attributes();
                for (int i = 0; i < attrs.count(); i++) {
                    QDomNode node = attrs.item(i);
                    QString nodeName = node.nodeName();
                    QString nodeValue = node.nodeValue();
                    //qDebug() << name << nodeName << nodeValue;

                    //优先取出坐标+宽高属性,这几个属性不能通过设置弱属性实现
                    if (nodeName == "x") {
                        x = nodeValue.toInt();
                    } else if (nodeName == "y") {
                        y = nodeValue.toInt();
                    } else if (nodeName == "width") {
                        width = nodeValue.toInt();
                    } else if (nodeName == "height") {
                        height = nodeValue.toInt();
                    } else if (nodeName.startsWith("user-")) {
                        //取出user-开头的自定义属性
                        nodeName = nodeName.split("-").last();
                        userProperty << QString("%1|%2").arg(nodeName).arg(nodeValue);
                    } else {
                        QVariant value = QVariant(nodeValue);
                        //为了兼容Qt4,需要将颜色值的rgba分别取出来,因为Qt4不支持16进制字符串带透明度
                        //#6422a3a9 这种格式依次为 argb 带了透明度的才需要特殊处理
                        if (nodeValue.startsWith("#") && nodeValue.length() == 9) {
                            bool ok;
                            int alpha = nodeValue.mid(1, 2).toInt(&ok, 16);
                            int red = nodeValue.mid(3, 2).toInt(&ok, 16);
                            int green = nodeValue.mid(5, 2).toInt(&ok, 16);
                            int blue = nodeValue.mid(7, 2).toInt(&ok, 16);
                            value = QColor(red, green, blue, alpha);
                        }

                        propertys.append(qMakePair(nodeName, value));
                    }
                }
            }

            //qDebug() << name << x << y << width << height;

            //根据不同的控件类型实例化控件
            int countWidget = listWidgets.count();
            int countProperty = propertys.count();
            for (int i = 0; i < countWidget; i++) {
                QString className = listWidgets.at(i)->name();
                if (name == className) {
                    //生成对应的控件
                    QWidget *widget = createWidget(i);
                    //逐个设置自定义控件的属性
                    for (int j = 0; j < countProperty; j++) {
                        QPair<QString, QVariant> property = propertys.at(j);
                        QString name = property.first;
                        QVariant value = property.second;
                        widget->setProperty(name.toStdString().c_str(), value);
                    }

                    //设置控件坐标及宽高
                    widget->setGeometry(x, y, width, height);
                    //实例化选中窗体跟随控件一起
                    newSelect(widget, userProperty);
                    break;
                }
            }

            //移动到下一个节点
            node = node.nextSibling();
            element = node.toElement();
        }
    }
}

void frmMain::saveFile(const QString &fileName)
{
    //如果控件列表没有则不用继续
    if (ui->listWidget->count() == 0) {
        return;
    }

    QFile file(fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) {
        return;
    }

    //以流的形式输出文件
    QTextStream stream(&file);

    //构建xml数据
    QStringList list;

    //添加固定头部数据
    list << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    //添加canvas主标签,保存宽高和背景图片,还可以自行添加其他属性
    list << QString("<canvas width=\"%1\" height=\"%2\" image=\"%3\">")
         .arg(ui->centralwidget->width()).arg(ui->centralwidget->height()).arg("bg.jpg");

    //从容器中找到所有控件,根据控件的类名保存该类的所有属性
    QList<QWidget *> widgets = ui->centralwidget->findChildren<QWidget *>();
    foreach (QWidget *widget, widgets) {
        const QMetaObject *metaObject = widget->metaObject();
        QString className = metaObject->className();

        //如果当前控件的父类不是主窗体则无需导出,有些控件有子控件无需导出
        if (widget->parent() != ui->centralwidget || className == "SelectWidget") {
            continue;
        }

        //逐个存储自定义控件属性
        //metaObject->propertyOffset()表示当前控件的属性开始索引,0开始的是父类的属性
        QStringList values;
        int index = metaObject->propertyOffset();
        int count = metaObject->propertyCount();
        for (int i = index; i < count; i++) {
            QMetaProperty property = metaObject->property(i);
            QString nodeName = property.name();
            QVariant variant = property.read(widget);
            QString typeName = variant.typeName();
            QString nodeValue = variant.toString();

            //如果是颜色值则取出透明度一起,颜色值toString在Qt4中默认不转透明度
            if (typeName == "QColor") {
                QColor color = variant.value<QColor>();
                if (color.alpha() < 255) {
                    //Qt4不支持HexArgb格式的字符串,需要挨个取出来拼接
                    //nodeValue = color.name(QColor::HexArgb);
                    QString alpha = QString("%1").arg(color.alpha(), 2, 16, QChar('0'));
                    QString red = QString("%1").arg(color.red(), 2, 16, QChar('0'));
                    QString green = QString("%1").arg(color.green(), 2, 16, QChar('0'));
                    QString blue = QString("%1").arg(color.blue(), 2, 16, QChar('0'));
                    nodeValue = QString("#%1%2%3%4").arg(alpha).arg(red).arg(green).arg(blue);
                }
            }

            //枚举值要特殊处理,需要以字符串形式写入,不然存储到配置文件数据为int
            if (property.isEnumType()) {
                QMetaEnum enumValue = property.enumerator();
                nodeValue = enumValue.valueToKey(nodeValue.toInt());
            }

            values << QString("%1=\"%2\"").arg(nodeName).arg(nodeValue);
            //qDebug() << nodeName << nodeValue << variant;
        }

        //找到当前控件对应的索引
        index = -1;
        count = listSelect.count();
        for (int i = 0; i < count; i++) {
            if (listSelect.at(i)->getWidget() == widget) {
                index = i;
                break;
            }
        }

        //可以用下面方法列出所有的用户属性,然后取值,本程序已经用 listUserProperty 存储了
        //qDebug() << widget->dynamicPropertyNames();

        //逐个存储控件的用户属性
        QStringList userProperty = listUserProperty.at(index);
        count = userProperty.count();
        for (int i = 0; i < count; i++) {
            QStringList list = userProperty.at(i).split("|");
            values << QString("user-%1=\"%2\"").arg(list.at(0)).arg(list.at(1));
        }

        //逐个添加界面上的控件的属性
        QString geometry = QString("x=\"%1\" y=\"%2\" width=\"%3\" height=\"%4\"").arg(widget->x()).arg(widget->y()).arg(widget->width()).arg(widget->height());
        QString str = QString("\t<%1 %2 %3/>").arg(className).arg(geometry).arg(values.join(" "));
        list << str;
    }

    //添加固定尾部数据
    list << "</canvas>";

    //写入文件
    QString data = list.join("\n");
    stream << data;
    file.close();
}

En guise d'avantage pour cet article, vous pouvez recevoir gratuitement un package d'apprentissage sur le développement Qt et des vidéos techniques, comprenant (les bases du langage C++, l'introduction à la programmation Qt, le mécanisme de signal et de slot QT, le dessin d'image de développement de l'interface QT, le réseau QT, la base de données QT. programmation, pratique de projet QT , pour recevoir les frais↓↓

5. Introduction au contrôle

  1. Plus de 160 commandes exquises, couvrant divers tableaux de bord, barres de progression, boules de progression, boussoles, courbes, règles, thermomètres, barres de navigation, barres de navigation, flatui, boutons de surbrillance, sélecteurs coulissants, calendrier lunaire, etc. Dépasse de loin le nombre de contrôles intégrés par qwt.
  2. Chaque classe peut être formée indépendamment en un contrôle distinct, avec couplage nul. Chaque contrôle possède un fichier d'en-tête et un fichier d'implémentation, et ne s'appuie pas sur d'autres fichiers. Il est pratique qu'un seul contrôle soit intégré au projet sous la forme de code source, avec moins de code. Les classes de contrôle de qwt sont imbriquées et fortement couplées. Si vous souhaitez utiliser l'un des contrôles, vous devez inclure tout le code.
  3. Tous écrits en Qt pur, dessinés par QWidget+QPainter, prennent en charge n'importe quelle version de Qt de Qt4.6 à Qt5.12, prennent en charge les compilateurs tels que mingw, msvc, gcc, etc., prennent en charge n'importe quel système d'exploitation tel que windows+linux+mac+ Linux intégré, etc., sans code tronqué, peut être directement intégré dans Qt Creator et utilisé comme les contrôles intégrés. La plupart des effets n'ont besoin que de définir quelques propriétés, ce qui est extrêmement pratique.
  4. Chaque contrôle possède une DEMO distincte correspondante contenant le code source du contrôle pour une référence et une utilisation faciles. Il fournit également une DEMO intégrée utilisée par tous les contrôles.
  5. Le code source de chaque contrôle comporte des commentaires chinois détaillés et est écrit conformément à des spécifications de conception unifiées, ce qui facilite l'apprentissage de l'écriture de contrôles personnalisés.
  6. La correspondance des couleurs par défaut de chaque contrôle et la correspondance des couleurs correspondant à la démo sont très exquises.
  7. Plus de 130 contrôles visibles et 6 contrôles invisibles.
  8. Certains contrôles proposent plusieurs choix de styles et plusieurs choix de styles d’indicateurs.
  9. Tous les contrôles s'adaptent pour former des changements d'étirement.
  10. Concepteur d'attributs de contrôle personnalisé intégré, prend en charge la conception par glisser-déposer, WYSIWYG, prend en charge l'importation et l'exportation au format XML.
  11. Livré avec une démo de contrôle ActiveX, tous les contrôles peuvent être exécutés directement dans le navigateur IE.
  12. Intégrez des polices graphiques fontawesome + des centaines de polices graphiques collectées par Alibaba iconfont et profitez du plaisir apporté par les polices graphiques.
  13. Tous les contrôles génèrent enfin un fichier de bibliothèque dynamique (dll ou plus, etc.), qui peut être directement intégré dans qtcreator pour une conception par glisser-déposer.
  14. Il existe déjà une version qml, et une version pyqt sera envisagée ultérieurement si la demande est forte de la part des utilisateurs.
  15. Le plug-in de contrôle personnalisé est ouvert à une utilisation dynamique de la bibliothèque (gratuite pour toujours), sans aucune porte dérobée ni restriction, alors n'hésitez pas à l'utiliser.
  16. Actuellement, 26 versions de DLL ont été fournies, dont qt5.12.3 msvc2017 32+64 mingw 32+64.
  17. Des contrôles sont ajoutés et améliorés de temps en temps, et le SDK est mis à jour de temps en temps. Les suggestions sont les bienvenues, merci !
  18. Pour les livres d'introduction à Qt, nous recommandons "Démarrage rapide avec Qt Creator" et "Introduction à la programmation Qt5" de Huo Yafei. Pour les livres Qt avancés, nous recommandons la "Programmation Qt4 GUI C++ officielle" de Huo Yafei.
  19. Je recommande fortement la série de livres d'auto-culture et de planification pour les programmeurs, "The Big Talk Programmer", "Programmer's Growth Course" et "The Worry-Relieving Programmer", qui vous seront très utiles et dureront toute une vie !
  20. Lien de téléchargement du SDK : https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ Code d'extraction : 877p

Lien original : cnblogs.com/feiyangqingyun/p/11922938.html

En guise d'avantage pour cet article, vous pouvez recevoir gratuitement un package d'apprentissage sur le développement Qt et des vidéos techniques, comprenant (les bases du langage C++, l'introduction à la programmation Qt, le mécanisme de signal et de slot QT, le dessin d'image de développement de l'interface QT, le réseau QT, la base de données QT. programmation, pratique de projet QT , pour recevoir les frais↓↓

Je suppose que tu aimes

Origine blog.csdn.net/hw5230/article/details/132813264
conseillé
Classement