Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to get x and y position from Gridlayout?
Forum Updated to NodeBB v4.3 + New Features

How to get x and y position from Gridlayout?

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 4 Posters 6.6k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    ihdvsk
    wrote on last edited by
    #3

    sorry i'm new to Qt and i didnt find a fitting function in the QGridlayout Class.
    How could i then resolve my problem better?

    raven-worxR 1 Reply Last reply
    0
    • I ihdvsk

      Hello, i wrote a function to draw a path in a Gridlayout of 20x20 PushButtons from "Start" to "End" but somehow it is not working and causing a crash in my program.

      The Problem is that i need to get the x and y coordinates to set the corresponding PushButton backgroundcolor to black

      here is my function:

      void Widget::setPath(){
      
          int start_x,start_y,end_x,end_y, path_x,path_y;
      
          // finds "Start" and "End" Buttons
          QPushButton *startButton = parentWidget()->findChild<QPushButton *>("Start");
          QPushButton *endButton = parentWidget()->findChild<QPushButton *>("End");
      
          // Gets x and y Value of StartButton in the grid
      
          for(int c = 0;c<20;c++){
              for(int d = 0;d<20;d++){
                  if(array[c][d] == startButton){
                      start_x = c;
                      start_y = d;
                  }
          // Gets x and y Value of EndButton in the grid
                  if(array[c][d] == endButton){
                      end_x = c;
                      end_y = d;
                  }
              }
          }
      
          path_x = start_x;
          path_y = start_y;
      
          while(path_x != end_x){
              // if "End" is to right of "Start" next Button to the right of "Start"
              // will be set to Path
              if(path_x < end_x){
                  path_x = path_x + 1;
                  array[path_x][start_y]->setStyleSheet("background-color:black;");
      
                  // if "End" is to left of "Start" next Button to the left of "Start"
                  // will be set to Path
              } else if (path_x > end_x){
                  path_x = path_x + 1;
                  array[path_x][start_y]->setStyleSheet("background-color:black;");
              }
          }
      
          while(path_y != end_y){
              // if "End" is lower than "Start" next Button to under "Start"
              // will be set to Path
              if(path_y < end_y){
                  path_y -= 1;
                  array[path_x][path_y]->setStyleSheet("background-color:black;");
                  // if "End" is higher than "Start" next Button to above "Start"
                  // will be set to Path
              } else if (path_x > end_y){
                  path_y += 1;
                  array[path_x][path_y]->setStyleSheet("background-color:black;");
              }
          }
      
      
      }
      

      i think this is causing the problem (array[c][d] is the array of pushButtons in the gridlayout):

          // Gets x and y Value of StartButton in the grid
      
          for(int c = 0;c<20;c++){
              for(int d = 0;d<20;d++){
                  if(array[c][d] == startButton){
                      start_x = c;
                      start_y = d;
                  }
          // Gets x and y Value of EndButton in the grid
                  if(array[c][d] == endButton){
                      end_x = c;
                      end_y = d;
                  }
              }
          }
      
      VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #4

      @ihdvsk said in How to get x and y position from Gridlayout?:

      causing a crash

      crash = look at/post the stack trace

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      0
      • I ihdvsk

        sorry i'm new to Qt and i didnt find a fitting function in the QGridlayout Class.
        How could i then resolve my problem better?

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #5

        @ihdvsk said in How to get x and y position from Gridlayout?:

        sorry i'm new to Qt and i didnt find a fitting function in the QGridlayout Class.

        since your code doesn't show clearly what you are trying to do IMHO i can't answer this question.

        But i guess your flow is sequential right? Means your "path" can only progress sequentially from start to end?
        Then eiter use the layout QGridLayout::itemAt(int index) method to iterate through the layout items (=widgets) or store the QWidgets independantly in a QList.

        Or is QGridLayout even the correct layout? Maybe a QHBoxLayout is more appropriate?

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        1
        • I Offline
          I Offline
          ihdvsk
          wrote on last edited by ihdvsk
          #6

          Here is my Code:
          widget.h

          #ifndef WIDGET_H
          #define WIDGET_H
          
          #include <QPushButton>
          #include <QObject>
          #include <QApplication>
          #include <QGridLayout>
          #include <QVBoxLayout>
          
          namespace Ui {
          class Widget;
          }
          
          class Widget : public QWidget
          {
              Q_OBJECT
          
          
              int numOfClicks = 0;
              QPushButton* array[20][20];
          
          public:
              explicit Widget(QWidget *parent = 0);
              ~Widget();
          
          public slots:
          
              void setUp(QWidget* w);
          
              /* sets the first clicked Button to "Start"
               and the second clicked Button to "End" */
              void setStartEnd();
          
              void setPath();  // creates the path from "Start" to "End"
          
          
          private:
              Ui::Widget *ui;
          };
          
          #endif // WIDGET_H
          
          

          main.cpp

          #include "widget.h"
          
          
          int main(int argc, char *argv[])
          {
              QApplication a(argc, argv);
          
              QWidget *w = new QWidget();
              Widget *wid = new Widget();
          
              wid->setUp(w);
          
              return a.exec();
          }
          
          

          and widget.cpp:

          #include "widget.h"
          #include "ui_widget.h"
          
          
          Widget::Widget(QWidget *parent) :
              QWidget(parent),
              ui(new Ui::Widget)
          {
              ui->setupUi(this);
          }
          
          Widget::~Widget()
          {
              delete ui;
          }
          
          
          void Widget::setUp(QWidget* w){
          
              // New GridLayout for Button Array
              QGridLayout *ButtonLayout = new QGridLayout;
          
              // Create 20x20 Buttons in Grid
              for(int i = 0;i<20;i++){
                  for(int j = 0;j<20;j++){
          
                      QPushButton *pushButton = new QPushButton("");
          
                      // Next line will be used to help find the Path later
                      array[i][j] = pushButton;
          
                      // Adds pushButton to Grid
                      w->setLayout(ButtonLayout);
                      ButtonLayout->addWidget(pushButton,i,j,1,1);
          
                      // Connects buttons to setStartEnd() function
                      w->connect(pushButton, SIGNAL(clicked()), this, SLOT(setStartEnd()));
                  }
              }
          
              // Set the grid layout as a main layout
              w->setLayout(ButtonLayout);
          
          
              // Display
              w->show();
          
          }
          
          void Widget::setStartEnd(){
          
          
              /* check if it is the first click
                 if yes the clicked Button is set to "Start" */
          
          
              if(numOfClicks == 0) {
          
              // New QObject that equals the clicked Button
              QObject* obj = sender();
              QPushButton* button = qobject_cast<QPushButton*>(obj);
          
          
              button->setText("Start");
              button->setStyleSheet("background-color:green;");
              button->setObjectName("Start");
          
              numOfClicks = numOfClicks + 1;
          
              /* else if it is the second click (numOfClicks == 1)
                 sets Button to "End" */
          
              } else if(numOfClicks == 1) {
          
                  QObject* obj2 = sender();
                  QPushButton* button2 = qobject_cast<QPushButton*>(obj2);
          
          
                  button2->setText("End");
                  button2->setStyleSheet("background-color:red;");
                  button2->setObjectName("End");
          
                  numOfClicks = numOfClicks + 1;
          
                  setPath();
          
              }
          
          }
          
          
          void Widget::setPath(){
          
              int start_x,start_y,end_x,end_y, path_x,path_y;
          
              // finds "Start" and "End" Buttons
              QPushButton *startButton = parentWidget()->findChild<QPushButton *>("Start");
              QPushButton *endButton = parentWidget()->findChild<QPushButton *>("End");
          
              // Gets x and y Value of StartButton in the grid
          
              for(int c = 0; c<20 ; c++){
                  for(int d = 0; d<20 ; d++){
                      if(array[c][d] == startButton){
                          start_x = c;
                          start_y = d;
                      }
              // Gets x and y Value of EndButton in the grid
                      if(array[c][d] == endButton){
                          end_x = c;
                          end_y = d;
                      }
                  }
              }
          
              path_x = start_x;
              path_y = start_y;
          
              while(path_x != end_x){
                  // if "End" is to the right of "Start" next Button to the right of "Start"
                  // will be set to Path
                  if(path_x < end_x){
                      path_x = path_x + 1;
                      array[path_x][start_y]->setStyleSheet("background-color:black;");
          
                      // if "End" is to the left of "Start" next Button to the left of "Start"
                      // will be set to Path
                  } else if (path_x > end_x){
                      path_x = path_x + 1;
                      array[path_x][start_y]->setStyleSheet("background-color:black;");
                  }
              }
          
              while(path_y != end_y){
                  // if "End" is lower than "Start" next Button to under "Start"
                  // will be set to Path
                  if(path_y < end_y){
                      path_y -= 1;
                      array[path_x][path_y]->setStyleSheet("background-color:black;");
                      // if "End" is higher than "Start" next Button to above "Start"
                      // will be set to Path
                  } else if (path_x > end_y){
                      path_y += 1;
                      array[path_x][path_y]->setStyleSheet("background-color:black;");
                  }
              }
          
          
          }
          
          

          i have a 20x20 grid of PushButtons. the user can select a start and endpoint. The program then should show a horizontally and then vertically path from start to end. Excuse me if the code is ugly, i tried to comment and indent everything

          mrjjM 1 Reply Last reply
          0
          • I ihdvsk

            Here is my Code:
            widget.h

            #ifndef WIDGET_H
            #define WIDGET_H
            
            #include <QPushButton>
            #include <QObject>
            #include <QApplication>
            #include <QGridLayout>
            #include <QVBoxLayout>
            
            namespace Ui {
            class Widget;
            }
            
            class Widget : public QWidget
            {
                Q_OBJECT
            
            
                int numOfClicks = 0;
                QPushButton* array[20][20];
            
            public:
                explicit Widget(QWidget *parent = 0);
                ~Widget();
            
            public slots:
            
                void setUp(QWidget* w);
            
                /* sets the first clicked Button to "Start"
                 and the second clicked Button to "End" */
                void setStartEnd();
            
                void setPath();  // creates the path from "Start" to "End"
            
            
            private:
                Ui::Widget *ui;
            };
            
            #endif // WIDGET_H
            
            

            main.cpp

            #include "widget.h"
            
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
            
                QWidget *w = new QWidget();
                Widget *wid = new Widget();
            
                wid->setUp(w);
            
                return a.exec();
            }
            
            

            and widget.cpp:

            #include "widget.h"
            #include "ui_widget.h"
            
            
            Widget::Widget(QWidget *parent) :
                QWidget(parent),
                ui(new Ui::Widget)
            {
                ui->setupUi(this);
            }
            
            Widget::~Widget()
            {
                delete ui;
            }
            
            
            void Widget::setUp(QWidget* w){
            
                // New GridLayout for Button Array
                QGridLayout *ButtonLayout = new QGridLayout;
            
                // Create 20x20 Buttons in Grid
                for(int i = 0;i<20;i++){
                    for(int j = 0;j<20;j++){
            
                        QPushButton *pushButton = new QPushButton("");
            
                        // Next line will be used to help find the Path later
                        array[i][j] = pushButton;
            
                        // Adds pushButton to Grid
                        w->setLayout(ButtonLayout);
                        ButtonLayout->addWidget(pushButton,i,j,1,1);
            
                        // Connects buttons to setStartEnd() function
                        w->connect(pushButton, SIGNAL(clicked()), this, SLOT(setStartEnd()));
                    }
                }
            
                // Set the grid layout as a main layout
                w->setLayout(ButtonLayout);
            
            
                // Display
                w->show();
            
            }
            
            void Widget::setStartEnd(){
            
            
                /* check if it is the first click
                   if yes the clicked Button is set to "Start" */
            
            
                if(numOfClicks == 0) {
            
                // New QObject that equals the clicked Button
                QObject* obj = sender();
                QPushButton* button = qobject_cast<QPushButton*>(obj);
            
            
                button->setText("Start");
                button->setStyleSheet("background-color:green;");
                button->setObjectName("Start");
            
                numOfClicks = numOfClicks + 1;
            
                /* else if it is the second click (numOfClicks == 1)
                   sets Button to "End" */
            
                } else if(numOfClicks == 1) {
            
                    QObject* obj2 = sender();
                    QPushButton* button2 = qobject_cast<QPushButton*>(obj2);
            
            
                    button2->setText("End");
                    button2->setStyleSheet("background-color:red;");
                    button2->setObjectName("End");
            
                    numOfClicks = numOfClicks + 1;
            
                    setPath();
            
                }
            
            }
            
            
            void Widget::setPath(){
            
                int start_x,start_y,end_x,end_y, path_x,path_y;
            
                // finds "Start" and "End" Buttons
                QPushButton *startButton = parentWidget()->findChild<QPushButton *>("Start");
                QPushButton *endButton = parentWidget()->findChild<QPushButton *>("End");
            
                // Gets x and y Value of StartButton in the grid
            
                for(int c = 0; c<20 ; c++){
                    for(int d = 0; d<20 ; d++){
                        if(array[c][d] == startButton){
                            start_x = c;
                            start_y = d;
                        }
                // Gets x and y Value of EndButton in the grid
                        if(array[c][d] == endButton){
                            end_x = c;
                            end_y = d;
                        }
                    }
                }
            
                path_x = start_x;
                path_y = start_y;
            
                while(path_x != end_x){
                    // if "End" is to the right of "Start" next Button to the right of "Start"
                    // will be set to Path
                    if(path_x < end_x){
                        path_x = path_x + 1;
                        array[path_x][start_y]->setStyleSheet("background-color:black;");
            
                        // if "End" is to the left of "Start" next Button to the left of "Start"
                        // will be set to Path
                    } else if (path_x > end_x){
                        path_x = path_x + 1;
                        array[path_x][start_y]->setStyleSheet("background-color:black;");
                    }
                }
            
                while(path_y != end_y){
                    // if "End" is lower than "Start" next Button to under "Start"
                    // will be set to Path
                    if(path_y < end_y){
                        path_y -= 1;
                        array[path_x][path_y]->setStyleSheet("background-color:black;");
                        // if "End" is higher than "Start" next Button to above "Start"
                        // will be set to Path
                    } else if (path_x > end_y){
                        path_y += 1;
                        array[path_x][path_y]->setStyleSheet("background-color:black;");
                    }
                }
            
            
            }
            
            

            i have a 20x20 grid of PushButtons. the user can select a start and endpoint. The program then should show a horizontally and then vertically path from start to end. Excuse me if the code is ugly, i tried to comment and indent everything

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #7

            @ihdvsk
            Like this ?
            alt text

            1 Reply Last reply
            3
            • I Offline
              I Offline
              ihdvsk
              wrote on last edited by
              #8

              yes this looks perfect!

              mrjjM 1 Reply Last reply
              0
              • I ihdvsk

                yes this looks perfect!

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #9

                @ihdvsk
                Is it also allowed to go back (on the row) if START col is bigger than
                Ends col ?

                alt text

                1 Reply Last reply
                1
                • I Offline
                  I Offline
                  ihdvsk
                  wrote on last edited by
                  #10

                  Yes, it should go horizontally first and then vertically just like your pictures show.

                  1 Reply Last reply
                  0
                  • mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #11

                    Hi
                    Is there not a bug here ?

                      while(path_x != end_x){
                            // if "End" is to the right of "Start" next Button to the right of "Start"
                            // will be set to Path
                            if(path_x < end_x){
                                path_x = path_x + 1;
                                array[path_x][start_y]->setStyleSheet("background-color:black;");
                    
                                // if "End" is to the left of "Start" next Button to the left of "Start"
                                // will be set to Path
                            } else if (path_x > end_x){
                                path_x = path_x + 1;  // should it no go "back" here ? as in -1 
                                array[path_x][start_y]->setStyleSheet("background-color:black;");
                            }
                        }
                    
                    1 Reply Last reply
                    2
                    • I Offline
                      I Offline
                      ihdvsk
                      wrote on last edited by ihdvsk
                      #12

                      I found my mistake. now it works.
                      widget.h

                      #ifndef WIDGET_H
                      #define WIDGET_H
                      
                      #include <QPushButton>
                      #include <QObject>
                      #include <QApplication>
                      #include <QGridLayout>
                      #include <QVBoxLayout>
                      #include <QPair>
                      #include <QLabel>
                      
                      
                      namespace Ui {
                      class Widget;
                      }
                      
                      class Widget : public QWidget
                      {
                          Q_OBJECT
                      
                      
                          int numOfClicks = 0;
                          QPushButton* array[20][20];
                      
                      public:
                          explicit Widget(QWidget *parent = 0);
                          ~Widget();
                      
                      public slots:
                      
                          void setUp(QWidget* w);
                      
                          /* sets the first clicked Button to "Start"
                           and the second clicked Button to "End" */
                          void setStartEnd();
                      
                          void setPath();  // creates the path from "Start" to "End"
                      
                      
                      private:
                          Ui::Widget *ui;
                      };
                      
                      #endif // WIDGET_H
                      
                      

                      main.cpp

                      #include "widget.h"
                      
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                      
                          QWidget *w = new QWidget();
                          Widget *wid = new Widget();
                      
                          wid->setUp(w);
                      
                          return a.exec();
                      }
                      
                      

                      and widget.cpp

                      #include "widget.h"
                      #include "ui_widget.h"
                      
                      
                      Widget::Widget(QWidget *parent) :
                          QWidget(parent),
                          ui(new Ui::Widget)
                      {
                          ui->setupUi(this);
                      }
                      
                      Widget::~Widget()
                      {
                          delete ui;
                      }
                      
                      void Widget::setUp(QWidget* w){
                      
                          // New GridLayout for Button Array
                          QGridLayout *ButtonLayout = new QGridLayout;
                      
                      
                          // Create 20x20 Buttons in Grid
                          for(int i = 0;i<20;i++){
                              for(int j = 0;j<20;j++){
                      
                      
                                  QPushButton *pushButton = new QPushButton("");
                      
                                  // Next line will be used to help find the Path later
                                  array[i][j] = pushButton;
                      
                                  // Adds pushButton to Grid
                                  w->setLayout(ButtonLayout);
                                  ButtonLayout->addWidget(pushButton,i,j,1,1);
                      
                                  // Connects buttons to setStartEnd() function
                                  w->connect(pushButton, SIGNAL(clicked()), this, SLOT(setStartEnd()));
                              }
                          }
                      
                          // Set the grid layout as a main layout
                          w->setLayout(ButtonLayout);
                      
                      
                          // Display
                          w->show();
                      
                      }
                      
                      void Widget::setStartEnd(){
                      
                      
                          /* check if it is the first click
                             if yes the clicked Button is set to "Start" */
                      
                      
                          if(numOfClicks == 0) {
                      
                          // New QObject that equals the clicked Button
                          QObject* obj = sender();
                          QPushButton* button = qobject_cast<QPushButton*>(obj);
                      
                      
                          button->setText("Start");
                          button->setStyleSheet("background-color:green;");
                          button->setObjectName("Start");
                      
                          numOfClicks = numOfClicks + 1;
                      
                          /* else if it is the second click (numOfClicks == 1)
                             sets Button to "End" */
                      
                          } else if(numOfClicks == 1) {
                      
                              QObject* obj2 = sender();
                              QPushButton* button2 = qobject_cast<QPushButton*>(obj2);
                      
                      
                              button2->setText("End");
                              button2->setStyleSheet("background-color:red;");
                              button2->setObjectName("End");
                      
                              numOfClicks = numOfClicks + 1;
                      
                              setPath();
                      
                          }
                      
                      }
                      
                      
                      void Widget::setPath(){
                      
                          int start_x,start_y,end_x,end_y, path_x,path_y;
                      
                          // finds "Start" and "End" Buttons
                      
                          // Gets x and y Value of StartButton in the grid
                          for(int c = 0; c<20 ; c++){
                              for(int d = 0; d<20 ; d++){
                                  if(array[c][d]->objectName() == "Start"){
                                      start_x = c;
                                      start_y = d;
                                  }
                          // Gets x and y Value of EndButton in the grid
                                  if(array[c][d]->objectName() == "End"){
                                      end_x = c;
                                      end_y = d;
                                  }
                              }
                          }
                      
                          path_x = start_x;
                          path_y = start_y;
                      
                          while(path_y != end_y){
                              // if "End" is to the right of "Start" next Button to the right of "Start"
                              // will be set to Path
                              if(path_y < end_y){
                                  path_y += 1;
                                  if(path_y != end_y || path_x != end_x){
                                      array[path_x][path_y]->setStyleSheet("background-color:black;");
                                  }
                                  // if "End" is to the left of "Start" next Button to the left of "Start"
                                  // will be set to Path
                              } else if (path_y > end_y){
                                  path_y -= 1;
                                  if(path_y != end_y || path_x != end_x){
                                      array[path_x][path_y]->setStyleSheet("background-color:black;");
                                  }
                              }
                          }
                      
                          while(path_x != end_x){
                              // if "End" is lower than "Start" next Button to under "Start"
                              // will be set to Path
                              if(path_x < end_x){
                                  path_x += 1;
                                  if(path_x != end_x || path_y != end_y){
                                      array[path_x][path_y]->setStyleSheet("background-color:black;");
                                  }
                      
                                  // if "End" is higher than "Start" next Button to above "Start"
                                  // will be set to Path
                              } else if (path_x > end_x){
                                  path_x -= 1;
                                  if(path_x != end_x || path_y != end_y){
                                      array[path_x][path_y]->setStyleSheet("background-color:black;");
                                  }
                              }
                          }
                      
                      }
                      
                      
                      1 Reply Last reply
                      1
                      • mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by mrjj
                        #13

                        Super, i assume you found bug2 in the y direction ?
                        Yep. fixed.

                        Good work. Funny app :)

                        alt text

                        To fully test, you could add a reset function and call from a button

                        1 Reply Last reply
                        0
                        • mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #14

                          Hi
                          Note:
                          You should set variable to zero or else you cant do it again as it has values (random)

                          void Widget::setPath() {
                          int start_x=0, start_y=0, end_x=0, end_y=0, path_x=0, path_y=0;
                          ...
                          }
                          also a reset function makes it more fun

                          void Widget::Reset() {
                              numOfClicks = 0;
                              for(int c = 0; c < 20 ; c++) {
                                  for(int d = 0; d < 20 ; d++) {
                                      array[c][d]->setStyleSheet(QString());
                                      array[c][d]->setText(QString());
                                  }
                              }
                          }
                          
                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved