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.8k 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 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