Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.1 - Qt Creator : 4.4.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Refaire une fenêtre Qt Designer à la main...

Bonsoir tout le monde...

On m'a dit de ne plus utiliser Qt Designer pour créer mes fenêtres, alors j'obéis :p

Mais je dois avouer que c'est assez complexe...
Je galère au niveau des layouts mais je suis assez déçu vu que je n'arrive pas à avoir le même résultat que sous Designer...
Si quelqu'un si connais en layout :) C'est assez vite confus...

Donc c'est ma fenêtre configuration :
image

Voilà le code que j'ai commencé :
TConfig::TConfig(QWidget *parent) : QDialog(parent)
{
setWindowTitle("Configuration de log Live");
setWindowIcon(QIcon("images/icone.png"));

QVBoxLayout *groupLayout_clic_gauche = new QVBoxLayout(this);
QGroupBox *groupBox_clic_gauche = new QGroupBox("Action clic gauche");
groupLayout_clic_gauche->addWidget(groupBox_clic_gauche);

QComboBox *comboBox_clic_gauche = new QComboBox;
comboBox_clic_gauche->addItem("Fenêtre d'accueil");
comboBox_clic_gauche->addItem("Site");
comboBox_clic_gauche->addItem("Forums");

QPushButton *bouton_clic_gauche = new QPushButton("Appliquer");

QLabel *label_clic_gauche = new QLabel("Cette option vous permet de définir l'action du double clic gauche ou droit sur l'icône du log Live.");

QGridLayout *layout_clic_gauche = new QGridLayout(groupBox_clic_gauche);
layout_clic_gauche->addWidget(comboBox_clic_gauche,0, 0);
layout_clic_gauche->addWidget(bouton_clic_gauche, 0, 1);
layout_clic_gauche->addWidget(label_clic_gauche, 1, 0, 1, 2);

setLayout(layout_clic_gauche);

QVBoxLayout *groupLayout_acces_site = new QVBoxLayout(this);
QGroupBox *groupBox_acces_site = new QGroupBox("Site Officiel");
groupLayout_acces_site->addWidget(groupBox_acces_site);

QLabel *label_utilisateur = new QLabel("Utilisateur:");
QLineEdit *lineEdit_utilisateur = new QLineEdit;

QLabel *label_mdp = new QLabel("Mot de passe:");
QLineEdit *lineEdit_mdp = new QLineEdit;
lineEdit_mdp->setEchoMode(QLineEdit::Password);

QPushButton *bouton_acces_site = new QPushButton("Appliquer");

QCheckBox *checkbox_acces_site = new QCheckBox("Connexion Automatique");

QProgressBar *progress_acces_site = new QProgressBar;
progress_acces_site->setValue(0);
progress_acces_site->setTextVisible(true);

QLabel *label_acces_site = new QLabel("Avoir accès au système de message privé, dernière news et pouvoir poster directement.\nAstuces: Lorsque que vos accès sont fourni çi dessus, lors du clic gauche\nsur le 'Forum' disponible au clic droit, vous arriverez sur le forum directement connecté !");

QGridLayout *layout_acces_site = new QGridLayout(groupBox_acces_site);
layout_acces_site->addWidget(label_utilisateur,0, 0);
layout_acces_site->addWidget(lineEdit_utilisateur, 0, 1);
layout_acces_site->addWidget(label_mdp, 0, 3);
layout_acces_site->addWidget(lineEdit_mdp, 0, 4);
layout_acces_site->addWidget(bouton_acces_site, 0, 6);
layout_acces_site->addWidget(checkbox_acces_site, 1, 0, 1, 6);
layout_acces_site->addWidget(progress_acces_site, 2, 0, 2, 6);
layout_acces_site->addWidget(label_acces_site, 3, 0, 3, 6);

setLayout(layout_acces_site);

QGroupBox *groupBox_lancer_demarrage = new QGroupBox("Lancer le log au démarrage", this);
QPushButton *bouton_active_windows = new QPushButton("Activer", this);
QPushButton *bouton_desactive_windows = new QPushButton("Désactiver", this);

QVBoxLayout *layout2 = new QVBoxLayout;

layout2->addWidget(groupBox_acces_site);
layout2->addWidget(label_utilisateur);
layout2->addWidget(lineEdit_utilisateur);
layout2->addWidget(label_mdp);
layout2->addWidget(lineEdit_mdp);
layout2->addWidget(bouton_acces_site);
layout2->addWidget(checkbox_acces_site);
layout2->addWidget(progress_acces_site);
layout2->addWidget(label_acces_site);

layout2->addWidget(groupBox_lancer_demarrage);
layout2->addWidget(bouton_active_windows);
layout2->addWidget(bouton_desactive_windows);

setLayout(layout2);
}
Pour les layouts je pensais faire ce schéma là :
QVBoxLayout *layoutPrincipal = new QVBoxLayout;
QHBoxLayout *layoutPrincipal = new QHBoxLayout;
QFormLayout *formLayout = new QFormLayout;
QHBoxLayout *layoutPrincipal = new QHBoxLayout;
QFormLayout *formLayout = new QFormLayout;
QHBoxLayout *layoutPrincipal = new QHBoxLayout;
QFormLayout *formLayout = new QFormLayout;
QHBoxLayout *layoutPrincipal = new QHBoxLayout;
QFormLayout *formLayout = new QFormLayout;

Réponses

  • utilise QT createur c'est un nouveau IDE pour QT une version 1.3 est disponible c'est trés pratique
  • Oui mais c'est pareil Qt Designer est dedans...
    On m'a dit que si on crée ça fenêtre à la main déjà c'est moins lourd, puis plus personnalisable, et beaucoup plus propre.

    Donc je voudrais essayer pour voir si c'est vraiment mieux...
  • uic.exe te permet de convertir un .ui en .h et de voir comment tes "jolies" fenêtres réalisées sous Designer sont codées en Qt. C'est plutôt formateur et tu peux t'inspirer de ce code si tu ne veux vraiment pas travailler avec un .ui.

    AMHA Designer est un outil très performant. Je l'utilise sans remord. Surtout les dernières versions: avant, il fallait savoir exactement ce que tu voulais faire comme layout car la moindre modification ou déplacement cassait tout. Maintenant, c'est beaucoup plus pratique. Même remarque pour les QGridLayout: avant, 9 fois sur 10, les alignements étaient n'importe comment, alors que maintenant, ça se gère très bien. Je trouve qu'il y a eu de gros progrès.
  • December 2009 modifié
    austin.fla said:
    On m'a dit que si on crée ça fenêtre à la main déjà c'est moins lourd, puis plus personnalisable, et beaucoup plus propre.
    Je ne sais pas qui t'a dit cela, mais je pense qu'il n'a jamais lu le code produit par Qt designer. C'est assez optimal. Je ne vois vraiment pas ce que tu peux faire de mieux. Ce ne peut pas être moins lourd puisque tu auras exactement les mêmes layouts et widgets, ce sera tout aussi personnalisable puisque tu peux facilement ajouter des widgets et layouts à la main en cours d'exécution, et on peut difficilement être plus propre que du code généré (que tu n'as ni à lire ni à comprendre !)
  • Ok merci beaucoup pour vos réponses je vais donc rester sur Qt Designer par contre juste une question :p
    Pour lancer Qt Designer je vais dans démarrer => tous les programmes => Qt SDK by Nokia v2009.05 (open source) => Tools => Qt Designer

    C'est bien celui là qu'il faut ?

    Une autre question aussi est ce que je peux envoyer ma fenêtre à l'un d'entre vous pour qu'il vérifié un peu si tout est bien fait ?

    Merci pour vos réponses :)
  • Pas besoin de lancer un programme à part le designer est intégré DANS QtCreator.
  • Donc ce n'est pas le même alors c'est deux designer différent ?

    Si quelqu'un veut bien vérifier ma fenêtre je vais la mettre sur mon serveur je vais mettre le lien des que possible :)
  • Ce sont les même composants (widgets et autres) qui sont utilisés donc non on ne peut pas dire que ce sont deux designer différents.
    C'est juste plus sympa d'avoir une seule appli avec tout dedans.
  • Non ta manière de faire n'est pas la bonne.
    Tu n'affectes pas tes layouts au widgets concernés.
    Pour faire ça correctement il ne faut pas créer des layouts à partir de la toolbar mais en faisant clic droit > Mise en page sur le widget en question.
    Parce que tel que le fait tu places des widgets à la main ce qui va pas marcher si tu redimensionnes ta fenêtre.
  • Ok je vois un peu donc je supprime toutes mes layouts que j'ai fait juste qu'à présent et je refais avec ta méthode ?
  • Je crois que c'est le plus simple.
  • Quand j'essayer de le faire par ta méthode ma fenêtre change complètement de forme... J'ai plus de taille c'est normal ?
  • C'est normal, ce sont les layouts qui sont en charge de la taille des widgets.
  • Donc avec les layouts je n'aurais plus la même taille partout...
    Est ce que si tu as le temps tu peux faire vite fait genre le premier champs pour voir comment tu fais je dois avouer que je sais pas trop quoi choisir entre les layout form, grille, verticale, horizontale...
  • Je t'ai envoyé une version un peu plus propre par mail.
  • Ah oui effectivement mes layouts par rapport au tienne ne servait strictement à rien...
    Là je viens de voir que la fenêtre que tu as modifié pouvais vraiment s'agrandir si on change la taille de la fenêtre c'est cool :)

    C'est possible de régler les tailles des boutons par exemple je cherchais le moyen justement de remettre le bouton ok soit au milieu de taille normal ou à droite parce que la vu qu'il fait toute la longueur ça fait bizarre je trouve...

    Merci beau tu gères !!


    Maintenant je voudrais passer un un autre problème...

    Les cases à cocher...
    Je voudrais faire en sorte que l'on puisse en cocher que 10 max pour ensuite enregistrer que ce qui sont cocher dans un QStringList

    Donc je pensais à ça mais j'ai pas réussit à le rendre fonctionnel :
    QStringList nomsForums << "actualité" << "achat" << ...;
    QList<int> idForums << 1 << 13 << ...;

    const int NbColonnes = 5;
    int i = 0;
    QGridLayout *grid = new QGridLayout;
    group = new QButtonGroup(this);
    group->setExclusive(false);
    foreach(QString nom, nomsForums)
    {
    QCheckBox *checkbox = new QCheckBox(nom);
    grid->addWidget(checkbox, i / NbColonnes, i % NbColonnes);
    group->addButton(checkbox, idForums[i]);
    ++i;
    }
    connect(group, SIGNAL(buttonClicked(QAbstractButton*)),...);
    Donc avec ce code je suis cencé créer toutes les cases à cocher dans ma fenêtre mais non...
  • Pour régler plus finement les tailles, tu peux utiliser des spacers, ou changer les politiques de taille, ou encore déterminer une taille fixe pour certain widgets.

    Pour l'autre problème je pense que le problème vient du calcul de la ligne/colonne. Pour t'inspirer d'un algorithme correcte regarde l'exemple Flow Layout.
  • December 2009 modifié
    Je reviens sur ce sujet vu que j'ai toujours pas réussi à faire marcher le code...

    Voilà dans mon fichier cpp qui contient les fonctions de ma fenêtre créer via Qt Designer j'ai ceci :
    #include "tconfig.h"

    TConfig::TConfig(QWidget *parent) : QDialog(parent)
    {
    m_ui.setupUi(this);

    // Création des checkbox dans la fenêtre
    QStringList nomsForums;
    nomsForums << "actualité" << "achat" << "bloblob" << "bfsfdsfdb" << "aaaaa" << "nnnnnnn";
    QList<int> idForums;
    idForums << 1 << 13 << 4 << 3 << 78 << 35;

    const int NbColonnes = 5;
    int i = 0;
    QGridLayout *grid = new QGridLayout;
    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->setExclusive(false);

    foreach(QString nom, nomsForums)
    {
    QCheckBox *checkbox = new QCheckBox(nom);
    grid->addWidget(checkbox, i / NbColonnes, i % NbColonnes);
    buttonGroup->addButton(checkbox, idForums[i]);
    ++i;
    }
    connect(buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(on_pushButton_alerte_forums_clicked()));
    // Fin des checkbox
    }
    Dans ma fenêtre Qt designer là ou je veux mettre tout mes checkbox c'est dans un QGroupeBox déjà créer via designer qui s'appelle groupBox_5.

    Quand je compile pas d'erreur mais quand j'ouvre la fenêtre j'ai rien du tout aucune checkbox créer...

    Merci !
  • December 2009 modifié
    essaie d'ajouter
    groupBox_5->setLayout( grid );
    mais ce mélange designer / code C++ finit par faire "dégueulasse"
    au minimun renomme ta variable
    eg: groupBox_5 >>>> gbForums

    plus propre serait de "promouvoir" sur une classe à toi
    dérivée de QGroupBox eg:
    class ForumsBox : public QGroupBox
    {
    Q_OBJECT;
    public:
    ForumsBox( QWidget * p = NULL ) : QGroupBox( p )
    {
    QStringList noms;
    QList<int> ids;
    noms << "actualité" << "achat" << "bloblob" << "bfsfdsfdb" << "aaaaa" << "nnnnnnn";
    ids << 1 << 13 << 4 << 3 << 78 << 35;
    const int nc = 5;
    QGridLayout * grid = new QGridLayout( this );
    QButtonGroup * btGroup = new QButtonGroup;
    btGroup->setExclusive( false );
    btGroup->setObjectName( "btGroup" );
    for( int i = 0; i < noms.count(); i++ )
    {
    QCheckBox * checkbox = new QCheckBox( noms[i] );
    grid->addWidget( checkbox, i / nc, i % nc );
    btGroup->addButton( checkbox, ids[i] );
    }
    }
    };
    et dans la classe TConfig
    // renomme le slot
    // on_btGroup_buttonClicked( int )
    // la connection se fera automatiquement
    TConfig::TConfig( QWidget * p ) : QDialog( p )
    {
    m_ui.setupUi( this );
    }
  • J'ai rajouter dans ma fenêtre via designer un GridLayout et j'ai essayer de faire ça mais ça n'a pas marché :
    TConfig::TConfig(QWidget *parent) : QDialog(parent)
    {
    m_ui.setupUi(this);

    // Création des checkbox dans la fenêtre
    QStringList nomsForums;
    nomsForums << "actualité" << "achat" << "bloblob" << "bfsfdsfdb" << "aaaaa" << "nnnnnnn";
    QList<int> idForums;
    idForums << 1 << 13 << 4 << 3 << 78 << 35;

    const int NbColonnes = 5;
    int i = 0;
    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->setExclusive(false);

    foreach(QString nom, nomsForums)
    {
    QCheckBox *checkbox = new QCheckBox(nom);
    buttonGroup->addButton(checkbox, idForums[i]);
    ++i;
    }
    m_ui.groupBox_5->setLayout(m_ui.gridLayout_4);
    connect(buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(alerte_forums_valide()));
    // Fin des checkbox
    }
    ça compile mais dans ma console de debug j'ai :
    QWidget::SetLayout: Attempting to set QLayout "gridLayout_4" on QGroupBox "groupBox_5, which already has a layout
    Pour la class se serait trop le bordel dans les fichier je pense pour l'instant c'est un tout petit code donc ça va je pense que c'est mieux comme ça, mais je peux me tromper !! ^^
    Merci en tout cas pour votre aide !!
  • December 2009 modifié
    austin.fla said:
    Pour la class se serait trop le bordel dans les fichier
    elle est pas grosse cette classe !!!
    et dans la mesure ou sa présence simplifie le reste ... pourquoi s'en abstenir

    il faut mettre en place ce genre de chose au début
    avant que cela ne devienne compliqué
  • December 2009 modifié
    Je veux bien mais je vois pas trop comment faire du coup pour rendre propre...

    Actuellement pour ma fenêtre j'ai 3 fichiers !
    tconfig.cpp
    tconfig.h
    tconfig.ui

    Voilà ce qu'il contienne :

    tconfig.cpp
    #include "tconfig.h"

    TConfig::TConfig(QWidget *parent) : QDialog(parent)
    {
    m_ui.setupUi(this);

    // Création des checkbox dans la fenêtre
    QStringList nomsForums;
    nomsForums << "actualité" << "achat" << "bloblob" << "bfsfdsfdb" << "aaaaa" << "nnnnnnn";
    QList<int> idForums;
    idForums << 1 << 13 << 4 << 3 << 78 << 35;

    const int NbColonnes = 5;
    int i = 0;
    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->setExclusive(false);

    foreach(QString nom, nomsForums)
    {
    QCheckBox *checkbox = new QCheckBox(nom);
    buttonGroup->addButton(checkbox, idForums[i]);
    ++i;
    }
    m_ui.groupBox_5->setLayout(m_ui.gridLayout_4);
    //buttonGroup->setLayout(m_ui.gridLayout_4);
    //m_ui.gridLayout_4->addWidget(buttonGroup, 0, 0);
    connect(buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(alerte_forums_valide()));
    // Fin des checkbox

    connect(m_ui.pushButton_ok, SIGNAL(clicked()), this, SLOT(close()));
    }

    void TConfig::alerte_forums_valide()
    {
    // Traitement des checkbox ! Quand on en coche une, on rajoute l'id dans un QStringList, si on la décoche on la supprime !
    QMessageBox::information(0, tr("Alerte Forums"), tr("fsfsfdfdfsfdsfdsfdsfdsfdsfdsfd"));
    }


    void TConfig::on_pushButton_alerte_forums_clicked()
    {
    QMessageBox::information(0, tr("Alerte Forums"), tr("Opération effectuée"));
    }
    tconfig.h
    #ifndef TCONFIG_H
    #define TCONFIG_H

    #include <QSettings>
    #include <QMessageBox>
    #include <QDir>
    #include <QCryptographicHash>

    #include "ui_tconfig.h"
    #include "requetes_alertes.h"


    class TConfig : public QDialog
    {
    Q_OBJECT

    public:
    explicit TConfig(QWidget *parent = 0);

    private:
    Ui::TConfig m_ui;
    QStringList nomsForums;

    public slots:
    void alerte_forums_valide();
    void on_pushButton_alerte_forums_clicked();
    };

    #endif // TCONFIG_H
    Tu ferais comment exactement si tu voulais que ce soit bien propre ?
  • quelle ton application ?

    car j'imagine que la classe TConfig est utilisée dans un cadre plus général

    si c'est par exemple un chat, je verrais bien
    une struct/class/namespace global
    définissant ce qui est commun à toute ton application
    exemple
    struct Chat
    {
    struct Forum
    {
    Forum( QString n, int i ) : name( n ), id( i ) {}
    QString name;
    int id;
    };
    static QList<Forum> forums;

    class ConfigDlg;

    static init(); // initialisation de la classe : variables statiques ... forums par exemple
    };
    un classe dialogue de configration
    class Chat::ConfigDlg : public QDialog, private Ui::ConfigDlg
    {
    Q_OBJECT;
    class ForumsBox;
    public:
    ConfigDlg( QWidget * p = NULL );
    ...
    };
    un classe boutons de selection de forums
    class Chat::ConfigDlg::ForumsBox : public QButtonGroup
    {
    Q_OBJECT;
    public:
    ForumsBox( QWidget * p = NULL );
    ...
    };
    l'imbrication des structures peut paraitre complexe,
    mais si elle bien taite, le code général s'en trouvera simplifié

    dans l'exemple ci-dessus, la classe Chat::ConfigDlg::ForumsBox
    peut directement accéder à la liste des forums: forums sans préfixer Chat::forums
    ...
  • Enfaite c'est une fenêtre principal qui va afficher 4-5 fenêtres

    Cette application me sert à dialoguer avec mon site c'est un logiciel qui va me connecter au site et qui va m'afficher les dernières news, nouveau post, topic, mp etc...
    Tout est déjà fait sauf que la j'essaye d'améliorer ma fenêtre de configuration c'est pour ça que je n'étais pas chaud pour faire une nouvelle class vu que le fichier tconfig.cpp et tconfig.h sert seulement à la fenêtre et juste pour ça aucune autre fonction ou autre sert pour le reste du programme.
Connectez-vous ou Inscrivez-vous pour répondre.