Anfänger in C++, Hilfe mit Qt



  • Hallo Zusammen

    Ich bin seit ca. 4 Jahren ein .Net und C# entwickler und möchte C++ erlernen. Evt. hat Jemand Tipps für den Umstieg? Auf jeden Fall dachte ich mir, ich programmiere einen Sudoku-Auflöser, als Einstieg in die Sprache. Jedoch scheitere ich schon am Anfang.

    Ich habe meinen Code hier angehängt. Ich versuche bei einem Click auf ein Quadrat, dieses in einer anderen Farbe zu zeichnen.

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include"QWidget"
    #include <QtGui>
    #include "QPixmap"
    #include <iostream>
    #include <string>
    #include <QMessageBox>
    struct Point
    {
        int x;
        int y;
        int width;
        int height;
    };
    
    class InputBox
    {
    public:
        Point p;
        bool selected;
    };
    
    class MyWidget : public QWidget
    {
    public:
        MyWidget();
        int x;
        int y;
        InputBox boxes [9][9];
    protected:
        void paintEvent(QPaintEvent *);
        void mouseReleaseEvent(QMouseEvent *);
    private:
        void initBoxes();
    };
    
    MyWidget::MyWidget()
    {
        QPalette palette(MyWidget::palette());
        palette.setColor(backgroundRole(), Qt::white);
        setPalette(palette);
        initBoxes();
    }
    
    void MyWidget::initBoxes()
    {
        int margin = 5;
        int cWidth = 50;
        int cHeight = 50;
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                Point p;
                p.y = row * cHeight + margin;
                p.x = col * cWidth + margin;
                p.width = cWidth;
                p.height = cHeight;
    
                InputBox b;
                b.p = p;
                b.selected = false;
                boxes[row][col] = b;
            }
        }
    }
    
    void MyWidget::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                InputBox b = boxes[row][col];
    
                if (b.selected == true)
                {
                    painter.setPen(Qt::darkBlue);
                    painter.fillRect(b.p.x, b.p.y, b.p.width, b.p.height, Qt::SolidPattern);
                }
                else
                {
                    painter.setPen(Qt::darkGreen);
                    painter.drawRect(b.p.x, b.p.y, b.p.width, b.p.height);
                }
            }
        }
    }
    
    void MyWidget::mouseReleaseEvent(QMouseEvent *e)
    {
        x = e->x();
        y = e->y();
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                InputBox b = boxes[row][col];
                b.selected = false;
    
                QRect rect(b.p.x, b.p.y, b.p.width, b.p.height);
    
                if (rect.contains(x, y))
                {
                    b.selected = true;
                    QMessageBox::information(NULL,"SELECTED BOX INFORMATION", QString("Row:%1;Col:%2").arg(row).arg(col),QMessageBox::Ok);
                }
            }
        }
    
        update();
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        MyWidget* my_widget = new MyWidget();
    
        setCentralWidget(my_widget);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    Hat Jemand eine Idee, was ich falsch mache?

    mfg
    Ajay



  • ajay schrieb:

    Hat Jemand eine Idee, was ich falsch mache?

    Ja, in mouseReleaseEvent veränderst du eine lokale Kopie eines Elements von boxes, nicht das Element selbst. Vielleicht möchtest du dort eine Referenz verwenden:

    InputBox& b = boxes[row][col];
    

    Ansonsten würde ich dazu raten, erstmal C++ zu lernen und dann Qt.

    Edit: Das hätte auch den Vorteil, dass du nicht ins Qt-Forum abgeschoben wirst, obwohl du gar keine Qt-Frage hast 😉



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Andere GUIs - Qt, GTK+, wxWidgets verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Bashar schrieb:

    ajay schrieb:

    Hat Jemand eine Idee, was ich falsch mache?

    Ja, in mouseReleaseEvent veränderst du eine lokale Kopie eines Elements von boxes, nicht das Element selbst. Vielleicht möchtest du dort eine Referenz verwenden:

    InputBox& b = boxes[row][col];
    

    Ansonsten würde ich dazu raten, erstmal C++ zu lernen und dann Qt.

    Edit: Das hätte auch den Vorteil, dass du nicht ins Qt-Forum abgeschoben wirst, obwohl du gar keine Qt-Frage hast 😉

    Vielen Dank für deine Hilfe, war ein Volltreffer 👍 . Ich dachte, ich kann das kombiniert lernen, deshalb habe ich auch mit Qt angefangen.



  • Nun habe ich anch der Änderung mit dem &-Zeichen ein komisches Phänomen. Sobald ich auf eine Box klicke, bzw ein Element aus dem Array hole, werden alle nachfolgenden Elementen auch als "Selektiert" angezeigt. Beim Debuggen waren diese jedoch nicht auf selektiert :S irgendwie ist der Debugger auch sehr langsam (lagt viel).

    Kann es damit zusammenhängen, dass ich nun die Adresse anspreche?



  • Ich verstehe nicht ganz, was du mit "als selektiert angezeigt" meinst. Und was die "nachfolgenden" Elemente sind ist mir auch nicht 100% klar.



  • Bashar schrieb:

    Ich verstehe nicht ganz, was du mit "als selektiert angezeigt" meinst. Und was die "nachfolgenden" Elemente sind ist mir auch nicht 100% klar.

    Ich habe Bilder angehängt um es zu veranschaulichen. Sobald ich auf ein Element klicke, möchte ich das Verhalten aus dem Bild 1. Jedoch verhält es sich so wie im Bild 2, dass alle nachfolgenden Boxe auch ausgewählt werden :S.

    Ich denke mir, es liegt an der Referenz, die ich verwende. Kann es sein, dass die Referenz mir alle nachfolgenden Elemente des Arrays verändert, sobald ich das Objekt verändere?

    http://www.bilder-upload.eu/thumb/b97680-1379367419.png

    http://www.bilder-upload.eu/thumb/69d268-1379367435.png

    mfg und danke für deine Hilfe
    Ajay

    Edit: (source code)

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include"QWidget"
    #include <QtGui>
    #include "QPixmap"
    #include <iostream>
    #include <string>
    #include <QMessageBox>
    
    struct Point
    {
        int x;
        int y;
        int width;
        int height;
    };
    
    class InputBox
    {
    public:
        Point p;
        bool selected;
    };
    
    class MyWidget : public QWidget
    {
    public:
        MyWidget();
        InputBox boxes [9][9];
    protected:
        void paintEvent(QPaintEvent *);
        void mouseReleaseEvent(QMouseEvent *);
    private:
        void initBoxes();
    };
    
    MyWidget::MyWidget()
    {
        QPalette palette(MyWidget::palette());
        palette.setColor(backgroundRole(), Qt::white);
        setPalette(palette);
        initBoxes();
    }
    
    void MyWidget::initBoxes()
    {
        int margin = 5;
        int cWidth = 50;
        int cHeight = 50;
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                Point p;
                p.y = row * cHeight + margin;
                p.x = col * cWidth + margin;
                p.width = cWidth;
                p.height = cHeight;
    
                InputBox b;
                b.p = p;
                b.selected = false;
                boxes[row][col] = b;
            }
        }
    }
    
    void MyWidget::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                InputBox b = boxes[row][col];
    
                if (b.selected)
                {
                    painter.setBrush(Qt::yellow);
                    painter.fillRect(b.p.x, b.p.y, b.p.width, b.p.height, Qt::SolidPattern);
                }
    
                painter.setPen(Qt::darkGreen);
                painter.drawRect(b.p.x, b.p.y, b.p.width, b.p.height);
            }
        }
    }
    
    void MyWidget::mouseReleaseEvent(QMouseEvent *e)
    {
        int x = e->x();
        int y = e->y();
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                InputBox& b = boxes[row][col];
                b.selected = false;
    
                QRect rect(b.p.x, b.p.y, b.p.width, b.p.height);
    
                if (rect.contains(x, y))
                {
                    b.selected = true;
    
                    //Inform Event
                    //QMessageBox::information(NULL,"SELECTED BOX INFORMATION", QString("Row:%1;Col:%2").arg(row).arg(col),QMessageBox::Ok);
                }
            }
        }
    
        update();
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        MyWidget* my_widget = new MyWidget();
    
        setCentralWidget(my_widget);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    


  • Ich kenn mich mit Qt nicht aus, aber ich tippe mal, es liegt daran, wie du mit dem QPainter umgehst. Beim ersten Feld mit selected==true stellst du die Hintergrundfarbe ein, ich nehme an, das gilt dann auch für die drawRect-Aufrufe später. Mit der Referenz hat das mit Sicherheit nichts zu tun. Die wird jedesmal neu initialisiert.



  • Bashar schrieb:

    Ich kenn mich mit Qt nicht aus, aber ich tippe mal, es liegt daran, wie du mit dem QPainter umgehst. Beim ersten Feld mit selected==true stellst du die Hintergrundfarbe ein, ich nehme an, das gilt dann auch für die drawRect-Aufrufe später. Mit der Referenz hat das mit Sicherheit nichts zu tun. Die wird jedesmal neu initialisiert.

    Wieder ein Treffer ins Schwarze! Vielen Dank für deine Hilfe Bashar.
    Ich hab den Code nun so geändert:

    if (b.selected)
                {
                    painter.setBrush(Qt::yellow);
                    painter.fillRect(b.p.x, b.p.y, b.p.width, b.p.height, Qt::SolidPattern);
                }
                else
                {
                    painter.setBrush(Qt::transparent);
                }
    


  • Ich hätte da noch eine Frage. Ich habe nun alles versucht, aber bekomme es nicht hin.

    Nun kann ich eine Box auswählen und dann eine Eingabe betätigen, was auch gezeichnet wird. Jedoch möchte ich, dass es bei der ausgewählten Box, die gelb gefärbt ist, die Eingabe sofort sehen, aber ich sehe diese erst, wenn ich eine andere Box auswähle. Zum Verständnis habe ich hier ein Bild upgeloadet:

    http://www.bilder-upload.eu/thumb/e2241e-1379440598.png

    Ich denke es liegt irgendwie an einem Z-Index, da beim erneuten reinklicken in ein Feld, welches ein Wert besitzt, der Wert nicht angezeigt wird. Ich habe die Reihenfolge der Paint-Aufrufe unterschiedlich angeordnet, ohne erfolg. Könnt Ihr mir helfen?

    Anbei ein Snippet aus meinem Code:

    class InputBox    
    {                 
    public:           
        Point p;      
        bool selected;
        QString value;
    };                
    
    void Ui::MyWidget::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
    
        for(int row = 0; row<9; row++)
        {
            for (int col = 0; col<9; col++)
            {
                InputBox b = boxes[row][col];
    
                if (b.selected)
                {
                    painter.setBrush(Qt::yellow);
                    painter.fillRect(b.p.x, b.p.y, b.p.width, b.p.height, Qt::SolidPattern);
                }
                else
                {
                    painter.setBrush(Qt::transparent);
                }
    
                if (b.value != "")
                {
                    QFont font=painter.font() ;
                    font.setPointSize ( 18 );
                    painter.setFont(font);
    
                    QRect rect(b.p.x, b.p.y, b.p.width, b.p.height);
    
                    painter.drawText(rect, Qt::AlignCenter, b.value);
                }
    
                painter.setPen(Qt::darkGreen);
                painter.drawRect(b.p.x, b.p.y, b.p.width, b.p.height);
            }
        }
    }
    


  • 😕 Ich habe noch keine Lösung zu diesem Problem gefunden. Hätte Jemand Zeit um mir das zu erklären? Ein FillRect überdeckt das DrawText, egal in welcher Reihenfolge ich dies aufrufe.



  • Sollte

    painter.setPen
    

    nicht auch vor

    painter.drawText
    

    gesetzt werden?


Log in to reply