Bienvenue sur le forum !

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

Qt : 5.10.1 - Qt Creator : 4.6.0 - Qt Installer : 3.0.4 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - QBS : 1.11.0

[Qt4] Destruction des layouts par défaut

Bonjour,

J'ai créé un QDockWidget et je voudrais y ajouter des images horizontalement. J'ai donc pensé à ajouter mes images dans le layout du QDockWidget. Seulement celui-ci est vertical et pas moyen d'en mettre un horizontal puisqu'il en possède déjà un. J'ai essayé de l'enlever en faisant un delete mais j'obtient alors une erreur de segmentation. (Dans la doc c'est d'ailleurs précisé que le destructeur ne détruit pas le layout du widget).
Sauriez-vous comment faire alors pour le supprimer et que je puisse mettre un layout horizontal?

Merci

Réponses

  • Salut,

    Dans la doc de QWidget::setLayout(), il est précisé au contraire qu'on doit supprimer un layout par delete avant d'en mettre un nouveau. Ca devrait donc marcher à priori. Peux-tu nous montrer le code le faisant stp?

    Si vraiment ça marche pas ou que tu es super pressé, y'a un petit workaround ;)
    Il y a la méthode QLayout::addItem qui te permettra d'ajouter le layout de tes rêves au layout vertical du QDockWidget.
  • Salut,
    J'ai essayé ce que tu m'as dit IrmatDen, mais ca n'a pas marché. Quand je fais setLayout au layout existant déjà eet que j'ajoute mes images au nouveau, mes images n'apparaissent pas.

    Sinon pour le détruire j'ai fais:

    delete dockWidget->layout();
    QHBoxLayout* layout = new QHBoxLayout(dockWidget);

    Mais donc j'ai cette erreur de segmentation.

    D'ailleurs j'ai une autre quesetion, comment faire pour ajouter les images au dockWidget mais de facon à ne pas agrandir la taille de la fenêtre et donc faire apparaitre une ScrollBar.

    Merci d'avance pour vos réponses, j'ai vraiment beaucoup de mal!
  • Citrouille said:
    delete dockWidget->layout();
    QHBoxLayout* layout = new QHBoxLayout(dockWidget);
    Salut,

    et si tu essaies à la place quelque chose qui ressemble plus à l'exemple de la doc pour setLayout(...), à savoir construire le layout sans le parenter d'emblée à ton dock widget:
    delete dockWidget->layout();
    QHBoxLayout* layout = new QHBoxLayout();
    dockWidget->setLayout(layout);
    ... ça donne quoi ?

    Pour ta seconde question, peut-être qu'en insérant une QScrollArea dans ton layout et ensuite tes composants (images, ...) dans cette QScrollArea, ça suffira (ça reste à tester, je ne suis malheureusement pas rompu aux classes UI de Qt4).
  • Salut,

    QDockWidget ne possede pas de layout interne par defaut ( d'ou ton erreur de segfault )
    D'aileurs a ce point un test serai apreciable pour eviter ton segfault :

    if ( dock->layout() )
    delete dock->layout();

    Ensuite, il suffit d ajouter un layout horizontal dans ton dock :

    QHBoxLayout* hl = new QHBoxLayout( dock );
    QLabel* l = new QLabel;
    l->setPixmap( "toto.png" );
    l->setScaledContents( false ); // pour que l image soit redimensionné a la taille du label, ca peut etre laid ...
    hl->addWidget( l );

    Voila, ca devrai t'aider.

    Normalement une utilisation correct de dockwidget serai :

    QDockWidget dock = new QDockWidget;
    QWidget* w = new QWidget;
    QHBoxLayout* hl = new QHBoxLayout( w );
    hl->setMargin( 0 );
    hl->setSpacing( 0 );
    dock->setWidget( w );
    // et seuleument maintenant tu peu ajouter des label pr afficher tes image ds le nouveau layout.

    P@sNox,
  • Si un widget possede deja un layout, un appel a setLayout ne fera rien, il faut d abord detruire le layout existant.

    P@Nox,
  • pasnox said:
    if ( dock->layout() )
    delete dock->layout();
    Ceci est équivalent à un simple delete dock->layout()

    En effet, faire un 'delete NULL' ne fait rien. Donc si dock->layout() renvoie NULL, le delete n'exécute rien, exactement comme dans ta version avec un 'if'.
  • Detruire un pointeur null cause un segfault ( chez moi en tout cas sous linux et windows :p ) et j'ai justement deja eu ce probleme en essayant de delete un layout(); :D

    D'ailleurs layout ne renvoi pas null, mais 0, est ce different ?!

    P@sNox,
  • null n'existait que pour le C, et par extension le C++. Mais 0 est la valeur devant être utilisée pour les pointeurs en C++, null n'a pas lieu d'être (à part les vestiges dû à son trop gros héritage du C :)).

    Plus haut, j'ai émis l'hypothèse de rajouter un layoutitem comme workaround. Mais si tu veux une scroll bar, il faut faire à base de QScrollArea comme l'a dit nouknouk (et ça annule ton besoin d'un autre layout si je saisis bien).
  • Le probleme avec une QScrollArea est qu'on ne peut y mettre q'un seul objet avec setWidget mais pas plusieurs.
    Et sinon la fonction layout() sur mon DockWidget me dit qu'il ya bien un layout par défaut.
  • Ajoute donc un widget qui contient un layout horizontal, et ajoute des qlabel a ce layout.

    P@sNox,
  • Ca y est ca marche enfin, j'ai fait comme tu as dit Pasnox. Merci beaucoup! J'ai enfin ma liste horizontale. Mais pas ma scrollBar :( Par contre je n'ai pas eu a detruire le layout.
    Merci a tout le monde en tout cas.
  • Euh, y'a pas besoin d'ajouter un widget pour avoir un layout??
    QScrollArea dérivant de QWidget, un simple setLayout fonctionnera.

    Quel est le code et le problème pour les scroll bars?
  • que done un :

    QDockWidget dock = new QDockWidget;
    QWidget* w = new QWidget;
    QHBoxLayout* hl = new QHBoxLayout( w );
    hl->setMargin( 0 );
    hl->setSpacing( 0 );
    QScrollArea* a = new QScrollArea;
    a->setWidget( w );
    dock->setWidget( a );
    // et seuleument maintenant tu peu ajouter des label pr afficher tes image ds le nouveau layout hl

    N'hesites pas a modifier le spacing si tu veux de l'espace entre tes images.

    P@sNox,
  • IrmatDen said:
    Euh, y'a pas besoin d'ajouter un widget pour avoir un layout??
    QScrollArea dérivant de QWidget, un simple setLayout fonctionnera.

    Quel est le code et le problème pour les scroll bars?
    QDockWidget tout comme QScrollArea serve a avoir un widget "central" leur layout sert donc a manager ce "central" widget.

    P@sNox,
  • J'ai copié ton code mais maintenant l'ajout des images dans le layout ne marche plus. Rien n'y apparait.
  • pasnox said:
    Detruire un pointeur null cause un segfault ( chez moi en tout cas sous linux et windows :p ) et j'ai justement deja eu ce probleme en essayant de delete un layout(); :D
    Je comprend pas alors, je viens d'essayer à l'instant :
    #include <stdlib.h>

    int main(int argc, char** argv)
    {
    delete (int*)NULL;
    delete (int*)0;

    exit(0);
    }
    ... et ça marche très bien sous linux (Kubuntu, gcc 4.0.3) et d'après mes souvenirs, ça marche également très bien sous windows (avec MSVC++).

    Remarque: après un petit tour sur google, c'est effectivement une des propriétés de 'delete' (ie. de ne rien faire en cas de delete 0). Par contre après tout dépend de la valeur de la constante NULL ; si elle est différente de zéro, là ça merdouillera. Mais par convention, sur les systèmes (relativement) récents, NULL vaut systématiquement 0.

    Vala. Promis, maintenant j'arrête de troller ;)
  • Je confirme.
    if (x) delete x, c'est inutile.
  • Bien peut etre que j'etais trop fatigué ce jour la :D je referai des tests :)

    P@sNox,
Connectez-vous ou Inscrivez-vous pour répondre.