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

[Qt4] Question utilisation QGraphicsScene, item and co

Bonjour à tous,
Utilisateur de mac, linux et windows, je souhaiterais developper un browser de fichiers multi plateforme beneficiant des avantages que je connais des 3 os.
Pour cela il faut que je puisse dessiner les icones, avec le nom du fichier en dessous, ces icones doivents etre deplacable sur la scene
apres je verrais pour stocker pour chaque icone dans un fichier sa position, ainsi que la couleur de celui ci (fond de couleur different pour le texte choisi comme sur mac)

Ca permet de mettre certains fichiers en bleu, vert...

Rien que ce debut est difficile, j'avais commencé par creer une classe heritant de Qwidget ou je creait un pixmap pour l'icone, puis un qlabel pour le texte, mais quand j'ai commencé le drag and drop ca allait pas du tout

Ensuite j'ai lu que QgraphicsScene, view, item and co serait plus approprié, je pourrais dessiner par exemple par la suite un fond sur le browser pour y reunir certains fichiers ...

Ma question concerne le depart:

J'avais commencé a creer une classe heritant de GraphicsItem mais ca buguait il me disait que j'essayait d'instancier une classe abstraite :(
donc j'ai remplacé l'heritage par QgraphicsRectItem et la ca passe mieux, mais apres comment on fait la suite ? je dois creer un qlabel image et texte sur mon instance ?

Merci de votre aide

Réponses

  • Re,
    J'ai créé une classe perso heritant de QgraphicsItem
    celle-ci me permet d'afficher un carré arrondi deplacable (ce que je voulais)
    neamoins je ne parviens pas a creer une image dessus





    SimpleItem.h
    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>

    class SimpleItem : public QGraphicsItem
    {
    private:
    QGraphicsPixmapItem image;

    public:
    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    20 + penWidth / 2, 20 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    painter->drawRoundRect(-10, -10, 20, 20);
    }

    void init(){
    this->setFlag(QGraphicsItem::ItemIsMovable);

    QGraphicsPixmapItem *img = new QGraphicsPixmapItem(QPixmap("images/folder.png"));
    //this->image.setPixmap(QPixmap("images/folder.png"));
    //this->image.show();
    }
    };
    Mon main
    #include <QtGui/QApplication>
    #include "mainwindow.h"
    #include "SimpleItem.h"
    #include <QGraphicsScene>
    #include <QGraphicsView>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    // MainWindow w;
    // w.show();


    QGraphicsScene scene;


    SimpleItem item;
    item.init();
    item.show();


    scene.addItem(&item);

    QGraphicsView view(&scene);
    view.show();




    return a.exec();
    }
  • Salut,

    tu dois tout dessiner dans la méthode paint, genre painter->drawPixmap(...

    romain
  • roms18 said:
    Salut,

    tu dois tout dessiner dans la méthode paint, genre painter->drawPixmap(...

    romain
    moi j'ai fait ca et ca marche

    par contre pour deplacer les elements je ne peux le faire qu'en selectionnant le carré blanc :(
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>

    class SimpleItem : public QGraphicsItem
    {
    private:
    QGraphicsPixmapItem image;

    public:
    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    20 + penWidth / 2, 20 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    painter->drawRoundRect(-10, -10, 10, 10);
    }

    void init(QString texte){
    this->setFlag(QGraphicsItem::ItemIsMovable);

    QGraphicsPixmapItem *image = new QGraphicsPixmapItem(QPixmap("images/folder.png"),this);
    QGraphicsTextItem *tex= new QGraphicsTextItem(QString(texte),this);
    tex->moveBy(0,48);
    //img->show();
    //this->image.setPixmap(QPixmap("images/folder.png"));
    // this->image.show();
    }
    };

    #endif // SIMPLEITEM_H
  • J'ai essayé avec painter-> (voir code ci -dessous)
    mais:
    1/ je ne peux deplacer qu'avec le carré blanc en haut a gauche
    2/ quand je deplace ca fait un bug graphique bizarre, qui lorsque je redimensionne la fenetre disparait
    il faudrait peut etre que je raffraichisse la vue a chaque deplacement ?

    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>

    class SimpleItem : public QGraphicsItem
    {
    private:
    QString m_texte;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    20 + penWidth / 2, 20 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->drawRoundRect(-10, -10, 10, 10);
    painter->drawPixmap(QPoint(0,0),QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);
    }

    };

    #endif // SIMPLEITEM_H
  • Fais attention à ton boundingRect() qui est < à ton item

    romain
  • roms18 said:
    Fais attention à ton boundingRect() qui est < à ton item

    romain
    exact, en le mettant a 80 c'est mieux j'ai egalement supprimé la creation d'un rectangle qui ne m'est pas utile

    Comment fait ton pour
    1/ gerer le clic droit pour editer l'objet (creation d'un qwidget...)
    2/ editer directement le texte ?
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QTextItem>

    class SimpleItem : public QGraphicsItem
    {
    private:
    QString m_texte;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    80 + penWidth / 2, 80 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->drawTiledPixmap (0,0,50,50,QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);
    }

    };

    #endif // SIMPLEITEM_H
  • c'est pas automatique.

    Regardes du côté de la doc de QGraphicsItem, il y a tous les événements souris, clavier qu'il te faut.
    Surcharges virtual void mouseDoubleClickEvent ( QGraphicsSceneMouseEvent * event ) pour qu'il t'ouvre une boîte de configuration.

    romain
  • roms18 said:
    c'est pas automatique.

    Regardes du côté de la doc de QGraphicsItem, il y a tous les événements souris, clavier qu'il te faut.
    Surcharges virtual void mouseDoubleClickEvent ( QGraphicsSceneMouseEvent * event ) pour qu'il t'ouvre une boîte de configuration.

    romain
    J'ai trouvé, en surchargeant (code plus bas)
    on peut connaitre sur quel element on a cliqué ? dans l' "event" on le sait ?
     void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    QWidget *info= new QWidget;
    QLabel *texte=new QLabel("Fenetre info",info);
    texte->show();

    info->show();


    }
    }
  • en fait, si tu surcharges la méthode mousePressEvent du QGraphicsItem et non de la scène, tu n'as pas a te poser la question.

    romain
  • Au clic droit j'ouvre une fenetre

    Avec un champ qui est automatiquement rempli avec le nom de l'icone
    un bouton valider qui permet de modifier le nom de l'icone

    mais ce bouton ne fonctionne pas :(
      void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    info= new QWidget;
    QLabel *texte=new QLabel("Nom:",info);
    texte->show();

    inputTexte = new QLineEdit(m_texte,info);
    inputTexte->move(50,0);
    inputTexte->show();

    QPushButton *valider=new QPushButton("Valider",info);
    valider->move(0,50);
    valider->show();

    QPushButton::connect(valider,SIGNAL(clicked()),valider ,SLOT(valider_form()));


    info->show();


    }

    }
    void valider_form(){
    QString newNom = inputTexte->text();
    m_texte=newNom;


    info->close();

    QWidget *info2= new QWidget;
    QLabel *confirm=new QLabel("NomNew:"+m_texte,info2);
    confirm->show();

    info2->show();
    }
  • Essaies QObject::connect(valider,SIGNAL(clicked()),this,SLOT(valider_form()));

    Ensuite, vérifie bien que valider_form() est bien un slot déclaré dans ton .h

    romain
  • roms18 said:
    Essaies QObject::connect(valider,SIGNAL(clicked()),this,SLOT(valider_form()));

    Ensuite, vérifie bien que valider_form() est bien un slot déclaré dans ton .h

    romain
    en essayant avec /SimpleItem.h:57: error: no matching function for call to `QObject::connect(QPushButton*&, const char[11], SimpleItem* const, const char[16])'

    et en remettant comme avant rien

    note: je viens de mettre public slots, je l'avait omis

    mon code
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QTextItem>
    #include <QLabel>
    #include <QGraphicsSceneMouseEvent>
    #include <QLineEdit>
    #include <QPushButton>

    class SimpleItem : public QGraphicsItem
    {
    private:
    QString m_texte;
    QLineEdit *inputTexte;
    QWidget *info;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    80 + penWidth / 2, 80 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->drawTiledPixmap (0,0,50,50,QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);
    }

    void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    info= new QWidget;
    QLabel *texte=new QLabel("Nom:",info);
    texte->show();

    inputTexte = new QLineEdit(m_texte,info);
    inputTexte->move(50,0);
    inputTexte->show();

    QPushButton *valider=new QPushButton("Valider",info);
    valider->move(0,50);
    valider->show();

    QPushButton::connect(valider,SIGNAL(clicked()),valider ,SLOT(valider_form()));


    info->show();


    }

    }
    public slots:

    void valider_form(){
    QString newNom = inputTexte->text();
    m_texte=newNom;


    info->close();

    QWidget *info2= new QWidget;
    QLabel *confirm=new QLabel("NomNew:"+m_texte,info2);
    confirm->show();

    info2->show();
    }
    };

    #endif // SIMPLEITEM_H
  • Ta classe ne contient pas la macro Q_OBJECT et ne dérive pas de QObject.
    Ton slot ne sera pas considéré comme tel sans ça.
  • chsxf said:
    Ta classe ne contient pas la macro Q_OBJECT et ne dérive pas de QObject.
    Ton slot ne sera pas considéré comme tel sans ça.
    En modifiant comme ceci, rien de neuf:
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QObject>
    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QTextItem>
    #include <QLabel>
    #include <QGraphicsSceneMouseEvent>
    #include <QLineEdit>
    #include <QPushButton>

    class SimpleItem : public QObject,public QGraphicsItem
    {
    Q_OBJECT

    private:
    QString m_texte;
    QLineEdit *inputTexte;
    QWidget *info;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    80 + penWidth / 2, 80 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->drawTiledPixmap (0,0,50,50,QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);
    }

    void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    info= new QWidget;
    QLabel *texte=new QLabel("Nom:",info);
    texte->show();

    inputTexte = new QLineEdit(m_texte,info);
    inputTexte->move(50,0);
    inputTexte->show();

    QPushButton *valider=new QPushButton("Valider",info);
    valider->move(0,50);
    valider->show();

    info->connect(valider,SIGNAL(clicked()),SLOT(valider_form()));


    info->show();


    }

    }
    public Q_SLOTS:

    void valider_form(){
    QString newNom = inputTexte->text();
    m_texte=newNom;


    info->close();

    QWidget *info2= new QWidget;
    QLabel *confirm=new QLabel("NomNew:"+m_texte,info2);
    confirm->show();

    info2->show();
    }
    };

    #endif // SIMPLEITEM_H
  • C'est bon

    j'avais laissé une erreur dans l'appel connect :)
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QObject>
    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QTextItem>
    #include <QLabel>
    #include <QGraphicsSceneMouseEvent>
    #include <QLineEdit>
    #include <QPushButton>

    class SimpleItem : public QObject,public QGraphicsItem
    {
    Q_OBJECT

    private:
    QString m_texte;
    QLineEdit *inputTexte;
    QWidget *info;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    80 + penWidth / 2, 80 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->drawTiledPixmap (0,0,50,50,QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);
    }

    void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    info= new QWidget;
    QLabel *texte=new QLabel("Nom:",info);
    texte->show();

    inputTexte = new QLineEdit(m_texte,info);
    inputTexte->move(50,0);
    inputTexte->show();

    QPushButton *valider=new QPushButton("Valider",info);
    valider->move(0,50);
    valider->show();

    info->connect(valider,SIGNAL(clicked()),this,SLOT(valider_form()));


    info->show();


    }

    }
    public Q_SLOTS:

    void valider_form(){
    QString newNom = inputTexte->text();
    m_texte=newNom;


    info->close();

    QWidget *info2= new QWidget;
    QLabel *confirm=new QLabel("NomNew:"+m_texte,info2);
    confirm->show();

    info2->show();
    }
    };

    #endif // SIMPLEITEM_H
  • Continuons sur notre bonne lancée :)

    Desormais je souhaite pouvoir assigné une couleur aux icones, par defaut rien, et on peut via une fenetre definir une couleur

    pour la phase dev, je me contente de passer en rouge les icones dont je viens de cliquer droit dessus puis valider la mini fenetre

    hors:
    1/ tous mes icones créé ont une couleur, differente qui plus est
    2/ quand je fais l'action pour changer de couleur (clic droit sur l'icone + valider) ca change de couleur, mais pas rouge, une autre couleur
    et si je repete l'action ca fait une nouvelle couleur

    mon code
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QObject>
    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QTextItem>
    #include <QLabel>
    #include <QGraphicsSceneMouseEvent>
    #include <QLineEdit>
    #include <QPushButton>

    class SimpleItem : public QObject,public QGraphicsItem
    {
    Q_OBJECT

    private:
    QString m_texte;
    QLineEdit *inputTexte;
    QWidget *info;
    Qt::GlobalColor *m_background;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    m_background=new Qt::GlobalColor(Qt::white);
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    80 + penWidth / 2, 80 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->setBrush(QBrush(QRgb(m_background)));
    painter->drawRect(0,0,25,25);
    painter->drawTiledPixmap (0,0,50,50,QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);

    }

    void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    info= new QWidget;
    QLabel *texte=new QLabel("Nom:",info);
    texte->show();

    inputTexte = new QLineEdit(m_texte,info);
    inputTexte->move(50,0);
    inputTexte->show();

    QPushButton *valider=new QPushButton("Valider",info);
    valider->move(0,50);
    valider->show();

    info->connect(valider,SIGNAL(clicked()),this,SLOT(valider_form()));


    info->show();


    }

    }
    public Q_SLOTS:

    void valider_form(){
    QString newNom = inputTexte->text();
    m_texte=newNom;
    m_background=new Qt::GlobalColor(Qt::red);


    // this->setProperty(

    info->close();
    }
    };

    #endif // SIMPLEITEM_H
  • Au temps pour moi, j'ai trouvé

    Une simple erreur de c++

    Par contre un truc tout bete que je me demandais hier:

    pour un browser je dois avoir 3 parties:
    1/a gauche: les raccourcis vers les repertoires favoris (modifiable comme l'explorateur d'ubuntu et de mac)
    2/en haut la barre d'adresse (bien pratique surtout si on doit bosser en terminal a coté)
    3/ la scene: ce que je developpe (avec votre aide) depuis le debut

    Comment qu'on fait ca avec les widget ?

    je créé un widget, puis dedans un horizontal(2), un vertical(1) et un dernier contenant la scene ?
    #ifndef SIMPLEITEM_H
    #define SIMPLEITEM_H

    #include <QObject>
    #include <QGraphicsItem>
    #include <QGraphicsPixmapItem>
    #include <QPainter>
    #include <QTextItem>
    #include <QLabel>
    #include <QGraphicsSceneMouseEvent>
    #include <QLineEdit>
    #include <QPushButton>
    #include <QColor>

    class SimpleItem : public QObject,public QGraphicsItem
    {
    Q_OBJECT

    private:
    QString m_texte;
    QLineEdit *inputTexte;
    QWidget *info;
    QColor m_background;

    public:
    SimpleItem(QString texte){
    m_texte=texte;
    m_background=Qt::white;
    }

    QRectF boundingRect() const
    {

    qreal penWidth = 1;
    return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
    80 + penWidth / 2, 80 + penWidth / 2);
    }

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
    QWidget *widget)
    {
    this->setFlag(QGraphicsItem::ItemIsMovable);

    painter->setBrush(QBrush(m_background));
    painter->drawRect(0,0,25,25);
    painter->drawTiledPixmap (0,0,50,50,QPixmap("images/folder.png"));
    painter->drawText(QPoint(0,50),m_texte);

    }

    void mousePressEvent(QGraphicsSceneMouseEvent *event){
    if ( event->button()==Qt::RightButton){

    info= new QWidget;
    QLabel *texte=new QLabel("Nom:",info);
    texte->show();

    inputTexte = new QLineEdit(m_texte,info);
    inputTexte->move(50,0);
    inputTexte->show();

    QPushButton *valider=new QPushButton("Valider",info);
    valider->move(0,50);
    valider->show();

    info->connect(valider,SIGNAL(clicked()),this,SLOT(valider_form()));


    info->show();


    }

    }
    public Q_SLOTS:

    void valider_form(){
    QString newNom = inputTexte->text();
    m_texte=newNom;
    m_background=Qt::red;


    // this->setProperty(

    info->close();
    }
    };

    #endif // SIMPLEITEM_H
Connectez-vous ou Inscrivez-vous pour répondre.