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. Mapping binary buttons in the order they are placed on a Widget
QtWS25 Last Chance

Mapping binary buttons in the order they are placed on a Widget

Scheduled Pinned Locked Moved Unsolved General and Desktop
mappingqpushbutton
11 Posts 3 Posters 2.2k Views
  • 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.
  • J Offline
    J Offline
    jensig
    wrote on 15 Jul 2018, 23:10 last edited by jensig
    #1

    Hi,
    I have a widget to print and memorized values of each button in a variable and each row below is a 4 bit binary number.
    alt text
    I'm trying to assign each button position to be "memorized" with a value (0 or 1) for each row in the order that they appear in the widget.

    When a user changes the value of several buttons and presses "calculate", a vector or a string should print out every value on each button in the text box.

    I tried with mapping but I can't get it to work.

    Right now all I can get are the values that were pressed but not all of them (eg. the "0"s) and they don't come out in order.

    The QTextEdit box also changes row spacing for unknown reasons.

    In the example above, it should print in the QTextEdit box:
    1011
    1100
    1000
    1111
    here's my widget.cpp:

    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        // index_ corresponds to the index of each button (0 to 60) == 15 rows of 4 buttons
        index_ = 0;
    
        layout_ = new QGridLayout;
    
        for (unsigned i = 0; i < SIZE_LONG; ++i) {
            for (unsigned j = 0; j < SIZE_BITS; ++j) {
    
                digitButtons[index_] = createButton("0", SLOT(buttonClicked()));
    
                connect(digitButtons[index_], SIGNAL(clicked(bool)), &mapper, SLOT(map()));
    
                mapper.setMapping(digitButtons[index_], index_);
    
                layout_->addWidget(digitButtons[index_++], i, j, Qt::AlignHCenter);
    
                if (i == SIZE_LONG - 1 && j == SIZE_BITS - 1) {
                    setColumnNumber(j);
                    layout_->addWidget(createButton("Calculate", SLOT(calculateClicked())), i + 1, j, Qt::AlignRight);
                }
            }
        }
        connect(&mapper, SIGNAL(mapped(int)), this, SIGNAL(handleButton(int)));
        setLayout(layout_);
    }
    
    Widget::~Widget()
    {}
    
    QString Widget::getButtons() { return btns_; }
    
    // set & get column number for the calculateClicked() SLOT
    void Widget::setColumnNumber(unsigned j) { columnNumber_ = j; }
    
    unsigned Widget::getColumnNumber() { return columnNumber_; }
    
    // if a button is clicked()
    void Widget::buttonClicked()
    {
        QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
        if (isChecked(clickedButton) == true)
            clickedButton->setText("1");
        else
            clickedButton->setText("0");
    
        btns_ += clickedButton->text();
    }
    
    QGridLayout *Widget::getQGridLayout() { return layout_; }
    
    void Widget::calculateClicked()
    {
        clickedButtonResult_ = qobject_cast<QPushButton *>(sender());
        clickedButtonResult_->setText("Calculate");
        createTextEdit(getQGridLayout(), 0, getColumnNumber());
    }
    
    void Widget::createTextEdit(QGridLayout *layout, unsigned i, unsigned j)
    {
        textGroupBox = new QTextEdit;
    
        layout->addWidget(textGroupBox, i + 1, j + 1);
        textGroupBox->setPlainText(btns_);
    }
    
    QPushButton *Widget::createButton(const QString &text, const char *member)
    {
        QPushButton *button = new QPushButton(text);
        button->setCheckable(true);
        button->setChecked(false);
        connect(button, SIGNAL(toggled(bool)), this, member);
        return button;
    }
    
    bool Widget::isChecked(QPushButton *btn)
    {
        return btn->isChecked();
    }
    
    

    widget.h:

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QApplication>
    #include <QString>
    #include <QStringList>
    #include <QPushButton>
    #include <QGridLayout>
    #include <QVector>
    #include <QSignalMapper>
    #include <QGroupBox>
    #include <QFormLayout>
    #include <QLabel>
    #include <QLineEdit>
    #include <QTextBlock>
    #include <QTextEdit>
    
    static const unsigned SIZE_LONG = 15;
    static const unsigned SIZE_BITS = 4;
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
        QVector<int> getVector();
        QString getButtons();
    
        void setColumnNumber(unsigned j);
        unsigned getColumnNumber();
    
        QGridLayout *getQGridLayout();
    
    private slots:
        void buttonClicked();
        void calculateClicked();
    
    private:
    
        QString btns_;
    
        enum { NumDigitButtons = 60 };
        QPushButton *digitButtons[NumDigitButtons];
    
        QSignalMapper mapper;
        unsigned index_;
        QTextEdit *textGroupBox;
        unsigned columnNumber_;
        QPushButton *clickedButtonResult_;
    
        QGridLayout *layout_;
        void createTextEdit(QGridLayout *layout, unsigned i, unsigned j);
        QPushButton *createButton(const QString &text, const char *member);
        bool isChecked(QPushButton *btn);
    
    signals:
        void handleButton(int button);
    
    };
    
    #endif // WIDGET_H
    
    

    main.cpp:

    #include "widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        return a.exec();
    }
    

    I'm trying to do this without lambdas & c++11 for now as I'm fairly new to QT5.
    Thank you for your help.

    jsulmJ J 2 Replies Last reply 16 Jul 2018, 04:34
    0
    • J jensig
      15 Jul 2018, 23:10

      Hi,
      I have a widget to print and memorized values of each button in a variable and each row below is a 4 bit binary number.
      alt text
      I'm trying to assign each button position to be "memorized" with a value (0 or 1) for each row in the order that they appear in the widget.

      When a user changes the value of several buttons and presses "calculate", a vector or a string should print out every value on each button in the text box.

      I tried with mapping but I can't get it to work.

      Right now all I can get are the values that were pressed but not all of them (eg. the "0"s) and they don't come out in order.

      The QTextEdit box also changes row spacing for unknown reasons.

      In the example above, it should print in the QTextEdit box:
      1011
      1100
      1000
      1111
      here's my widget.cpp:

      #include "widget.h"
      
      Widget::Widget(QWidget *parent)
          : QWidget(parent)
      {
          // index_ corresponds to the index of each button (0 to 60) == 15 rows of 4 buttons
          index_ = 0;
      
          layout_ = new QGridLayout;
      
          for (unsigned i = 0; i < SIZE_LONG; ++i) {
              for (unsigned j = 0; j < SIZE_BITS; ++j) {
      
                  digitButtons[index_] = createButton("0", SLOT(buttonClicked()));
      
                  connect(digitButtons[index_], SIGNAL(clicked(bool)), &mapper, SLOT(map()));
      
                  mapper.setMapping(digitButtons[index_], index_);
      
                  layout_->addWidget(digitButtons[index_++], i, j, Qt::AlignHCenter);
      
                  if (i == SIZE_LONG - 1 && j == SIZE_BITS - 1) {
                      setColumnNumber(j);
                      layout_->addWidget(createButton("Calculate", SLOT(calculateClicked())), i + 1, j, Qt::AlignRight);
                  }
              }
          }
          connect(&mapper, SIGNAL(mapped(int)), this, SIGNAL(handleButton(int)));
          setLayout(layout_);
      }
      
      Widget::~Widget()
      {}
      
      QString Widget::getButtons() { return btns_; }
      
      // set & get column number for the calculateClicked() SLOT
      void Widget::setColumnNumber(unsigned j) { columnNumber_ = j; }
      
      unsigned Widget::getColumnNumber() { return columnNumber_; }
      
      // if a button is clicked()
      void Widget::buttonClicked()
      {
          QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
          if (isChecked(clickedButton) == true)
              clickedButton->setText("1");
          else
              clickedButton->setText("0");
      
          btns_ += clickedButton->text();
      }
      
      QGridLayout *Widget::getQGridLayout() { return layout_; }
      
      void Widget::calculateClicked()
      {
          clickedButtonResult_ = qobject_cast<QPushButton *>(sender());
          clickedButtonResult_->setText("Calculate");
          createTextEdit(getQGridLayout(), 0, getColumnNumber());
      }
      
      void Widget::createTextEdit(QGridLayout *layout, unsigned i, unsigned j)
      {
          textGroupBox = new QTextEdit;
      
          layout->addWidget(textGroupBox, i + 1, j + 1);
          textGroupBox->setPlainText(btns_);
      }
      
      QPushButton *Widget::createButton(const QString &text, const char *member)
      {
          QPushButton *button = new QPushButton(text);
          button->setCheckable(true);
          button->setChecked(false);
          connect(button, SIGNAL(toggled(bool)), this, member);
          return button;
      }
      
      bool Widget::isChecked(QPushButton *btn)
      {
          return btn->isChecked();
      }
      
      

      widget.h:

      #ifndef WIDGET_H
      #define WIDGET_H
      
      #include <QWidget>
      #include <QApplication>
      #include <QString>
      #include <QStringList>
      #include <QPushButton>
      #include <QGridLayout>
      #include <QVector>
      #include <QSignalMapper>
      #include <QGroupBox>
      #include <QFormLayout>
      #include <QLabel>
      #include <QLineEdit>
      #include <QTextBlock>
      #include <QTextEdit>
      
      static const unsigned SIZE_LONG = 15;
      static const unsigned SIZE_BITS = 4;
      
      class Widget : public QWidget
      {
          Q_OBJECT
      
      public:
          Widget(QWidget *parent = 0);
          ~Widget();
      
          QVector<int> getVector();
          QString getButtons();
      
          void setColumnNumber(unsigned j);
          unsigned getColumnNumber();
      
          QGridLayout *getQGridLayout();
      
      private slots:
          void buttonClicked();
          void calculateClicked();
      
      private:
      
          QString btns_;
      
          enum { NumDigitButtons = 60 };
          QPushButton *digitButtons[NumDigitButtons];
      
          QSignalMapper mapper;
          unsigned index_;
          QTextEdit *textGroupBox;
          unsigned columnNumber_;
          QPushButton *clickedButtonResult_;
      
          QGridLayout *layout_;
          void createTextEdit(QGridLayout *layout, unsigned i, unsigned j);
          QPushButton *createButton(const QString &text, const char *member);
          bool isChecked(QPushButton *btn);
      
      signals:
          void handleButton(int button);
      
      };
      
      #endif // WIDGET_H
      
      

      main.cpp:

      #include "widget.h"
      #include <QApplication>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          Widget w;
          w.show();
          return a.exec();
      }
      

      I'm trying to do this without lambdas & c++11 for now as I'm fairly new to QT5.
      Thank you for your help.

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on 16 Jul 2018, 04:34 last edited by
      #2

      @jensig What does handleButton(int) do?
      Why do you create a new QTextEdit every time instead of reusing the existing one?
      The spacing inside the text edit is wrong probably because you don't use a font with fix spacing.
      This

      bool Widget::isChecked(QPushButton *btn)
      {
          if (btn->isChecked())
              return true;
          return false;
      }
      

      can be simplified to

      bool Widget::isChecked(QPushButton *btn)
      {
          return btn->isChecked();
      }
      

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      4
      • J Offline
        J Offline
        jensig
        wrote on 16 Jul 2018, 17:14 last edited by
        #3

        @jsulm handleButton(int button) is supposed to be a signal but I have no idea how to implement it.

        I don't understand what you mean when you say to reuse the existing QTextEdit? Could you show me what to modify?

        Thank you

        jsulmJ 1 Reply Last reply 17 Jul 2018, 04:58
        0
        • J jensig
          16 Jul 2018, 17:14

          @jsulm handleButton(int button) is supposed to be a signal but I have no idea how to implement it.

          I don't understand what you mean when you say to reuse the existing QTextEdit? Could you show me what to modify?

          Thank you

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on 17 Jul 2018, 04:58 last edited by jsulm
          #4

          @jensig

          connect(&mapper, SIGNAL(mapped(int)), this, SIGNAL(handleButton(int)));
          

          So, you want to emit a signal when mapped(int) signal is emitted - is that correct?

          "I don't understand what you mean when you say to reuse the existing QTextEdit?" - do you want to create a text edit for each button row?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          J 1 Reply Last reply 17 Jul 2018, 05:28
          1
          • jsulmJ jsulm
            17 Jul 2018, 04:58

            @jensig

            connect(&mapper, SIGNAL(mapped(int)), this, SIGNAL(handleButton(int)));
            

            So, you want to emit a signal when mapped(int) signal is emitted - is that correct?

            "I don't understand what you mean when you say to reuse the existing QTextEdit?" - do you want to create a text edit for each button row?

            J Offline
            J Offline
            jensig
            wrote on 17 Jul 2018, 05:28 last edited by jensig
            #5

            @jsulm
            In regards to mapping, all I want is to have all the values of each button (indexed 0 to 59) in a QVector<QString> or anything else so I would be able to retrieve them when a user presses on "calculate".
            When a user presses any of the buttons, it is able to modify the text on the QPushButton to "0" or "1", so I want their values in order or indexed in a QVector<QString> or anything else when we press on "calculate".

            "So, you want to emit a signal when mapped(int) signal is emitted - is that correct?"

            I am very confused about the utilization of signals so I really can't tell if to be able to retrieve the values I need to emit a signal.

            "do you want to create a text edit for each button row?"
            No, only one QTextEdit at the end to show all values on the buttons like so:
            1011
            1100
            1000
            1111

            Thank you

            jsulmJ 1 Reply Last reply 17 Jul 2018, 05:36
            0
            • J jensig
              17 Jul 2018, 05:28

              @jsulm
              In regards to mapping, all I want is to have all the values of each button (indexed 0 to 59) in a QVector<QString> or anything else so I would be able to retrieve them when a user presses on "calculate".
              When a user presses any of the buttons, it is able to modify the text on the QPushButton to "0" or "1", so I want their values in order or indexed in a QVector<QString> or anything else when we press on "calculate".

              "So, you want to emit a signal when mapped(int) signal is emitted - is that correct?"

              I am very confused about the utilization of signals so I really can't tell if to be able to retrieve the values I need to emit a signal.

              "do you want to create a text edit for each button row?"
              No, only one QTextEdit at the end to show all values on the buttons like so:
              1011
              1100
              1000
              1111

              Thank you

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on 17 Jul 2018, 05:36 last edited by
              #6

              @jensig said in Mapping binary buttons in the order they are placed on a Widget:

              No, only one QTextEdit at the end to show all values on the buttons like so:

              Then do not create a new text edit each time a button is pressed.

              Change this line

              connect(&mapper, SIGNAL(mapped(int)), this, SIGNAL(handleButton(int)));
              

              to

              connect(&mapper, SIGNAL(mapped(int)), this, SLOT(mapped(int)));
              

              And implement mapped slot where you get the index of the button as parameter:

              void Widget::mapped(int index)
              {
              ...
              }
              

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              2
              • J jensig
                15 Jul 2018, 23:10

                Hi,
                I have a widget to print and memorized values of each button in a variable and each row below is a 4 bit binary number.
                alt text
                I'm trying to assign each button position to be "memorized" with a value (0 or 1) for each row in the order that they appear in the widget.

                When a user changes the value of several buttons and presses "calculate", a vector or a string should print out every value on each button in the text box.

                I tried with mapping but I can't get it to work.

                Right now all I can get are the values that were pressed but not all of them (eg. the "0"s) and they don't come out in order.

                The QTextEdit box also changes row spacing for unknown reasons.

                In the example above, it should print in the QTextEdit box:
                1011
                1100
                1000
                1111
                here's my widget.cpp:

                #include "widget.h"
                
                Widget::Widget(QWidget *parent)
                    : QWidget(parent)
                {
                    // index_ corresponds to the index of each button (0 to 60) == 15 rows of 4 buttons
                    index_ = 0;
                
                    layout_ = new QGridLayout;
                
                    for (unsigned i = 0; i < SIZE_LONG; ++i) {
                        for (unsigned j = 0; j < SIZE_BITS; ++j) {
                
                            digitButtons[index_] = createButton("0", SLOT(buttonClicked()));
                
                            connect(digitButtons[index_], SIGNAL(clicked(bool)), &mapper, SLOT(map()));
                
                            mapper.setMapping(digitButtons[index_], index_);
                
                            layout_->addWidget(digitButtons[index_++], i, j, Qt::AlignHCenter);
                
                            if (i == SIZE_LONG - 1 && j == SIZE_BITS - 1) {
                                setColumnNumber(j);
                                layout_->addWidget(createButton("Calculate", SLOT(calculateClicked())), i + 1, j, Qt::AlignRight);
                            }
                        }
                    }
                    connect(&mapper, SIGNAL(mapped(int)), this, SIGNAL(handleButton(int)));
                    setLayout(layout_);
                }
                
                Widget::~Widget()
                {}
                
                QString Widget::getButtons() { return btns_; }
                
                // set & get column number for the calculateClicked() SLOT
                void Widget::setColumnNumber(unsigned j) { columnNumber_ = j; }
                
                unsigned Widget::getColumnNumber() { return columnNumber_; }
                
                // if a button is clicked()
                void Widget::buttonClicked()
                {
                    QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
                    if (isChecked(clickedButton) == true)
                        clickedButton->setText("1");
                    else
                        clickedButton->setText("0");
                
                    btns_ += clickedButton->text();
                }
                
                QGridLayout *Widget::getQGridLayout() { return layout_; }
                
                void Widget::calculateClicked()
                {
                    clickedButtonResult_ = qobject_cast<QPushButton *>(sender());
                    clickedButtonResult_->setText("Calculate");
                    createTextEdit(getQGridLayout(), 0, getColumnNumber());
                }
                
                void Widget::createTextEdit(QGridLayout *layout, unsigned i, unsigned j)
                {
                    textGroupBox = new QTextEdit;
                
                    layout->addWidget(textGroupBox, i + 1, j + 1);
                    textGroupBox->setPlainText(btns_);
                }
                
                QPushButton *Widget::createButton(const QString &text, const char *member)
                {
                    QPushButton *button = new QPushButton(text);
                    button->setCheckable(true);
                    button->setChecked(false);
                    connect(button, SIGNAL(toggled(bool)), this, member);
                    return button;
                }
                
                bool Widget::isChecked(QPushButton *btn)
                {
                    return btn->isChecked();
                }
                
                

                widget.h:

                #ifndef WIDGET_H
                #define WIDGET_H
                
                #include <QWidget>
                #include <QApplication>
                #include <QString>
                #include <QStringList>
                #include <QPushButton>
                #include <QGridLayout>
                #include <QVector>
                #include <QSignalMapper>
                #include <QGroupBox>
                #include <QFormLayout>
                #include <QLabel>
                #include <QLineEdit>
                #include <QTextBlock>
                #include <QTextEdit>
                
                static const unsigned SIZE_LONG = 15;
                static const unsigned SIZE_BITS = 4;
                
                class Widget : public QWidget
                {
                    Q_OBJECT
                
                public:
                    Widget(QWidget *parent = 0);
                    ~Widget();
                
                    QVector<int> getVector();
                    QString getButtons();
                
                    void setColumnNumber(unsigned j);
                    unsigned getColumnNumber();
                
                    QGridLayout *getQGridLayout();
                
                private slots:
                    void buttonClicked();
                    void calculateClicked();
                
                private:
                
                    QString btns_;
                
                    enum { NumDigitButtons = 60 };
                    QPushButton *digitButtons[NumDigitButtons];
                
                    QSignalMapper mapper;
                    unsigned index_;
                    QTextEdit *textGroupBox;
                    unsigned columnNumber_;
                    QPushButton *clickedButtonResult_;
                
                    QGridLayout *layout_;
                    void createTextEdit(QGridLayout *layout, unsigned i, unsigned j);
                    QPushButton *createButton(const QString &text, const char *member);
                    bool isChecked(QPushButton *btn);
                
                signals:
                    void handleButton(int button);
                
                };
                
                #endif // WIDGET_H
                
                

                main.cpp:

                #include "widget.h"
                #include <QApplication>
                
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    Widget w;
                    w.show();
                    return a.exec();
                }
                

                I'm trying to do this without lambdas & c++11 for now as I'm fairly new to QT5.
                Thank you for your help.

                J Offline
                J Offline
                J.Hilk
                Moderators
                wrote on 17 Jul 2018, 05:48 last edited by J.Hilk
                #7

                Hi @jensig

                are you sure, you want to do this without lambdas?

                Would make this so, so much easier:

                #ifndef WIDGET_H
                #define WIDGET_H
                
                #include <QWidget>
                #include <QVector>
                
                class QTextEdit;
                class QPushButton;
                class QGridLayout;
                class Widget : public QWidget
                {
                    Q_OBJECT
                public:
                    explicit Widget(QWidget *parent = nullptr);
                
                
                private:
                    QVector<QVector<QPushButton*>> btns;
                    QGridLayout *layout_;
                    QTextEdit *textEdit;
                };
                
                #endif // WIDGET_H
                
                
                #include "widget.h"
                #include <QGridLayout>
                #include <QTextEdit>
                #include <QPushButton>
                
                static const unsigned SIZE_LONG = 15;
                static const unsigned SIZE_BITS = 4;
                
                Widget::Widget(QWidget *parent)
                    : QWidget(parent)
                {
                
                    layout_ = new QGridLayout;
                    textEdit = new QTextEdit();
                    textEdit->resize(100,100);
                    textEdit->show();
                
                    for (int i = 0; i < SIZE_LONG; ++i) {
                        QVector<QPushButton*> btnRow;
                        for (int j = 0; j < SIZE_BITS; ++j) {
                            QPushButton *btn = new QPushButton("0");
                            btn->setCheckable(true);
                            layout_->addWidget(btn,i,j,Qt::AlignHCenter);
                
                            connect(btn, &QPushButton::toggled, this, [=](bool checked){
                                btn->setText(checked ? "1" : "0");
                                textEdit->clear();
                                for(int x(0); x < btns.size(); x++){
                                    QString line;
                                    for(int y(0); y < btns.at(x).size(); y++){
                                        line.append(btns.at(x).at(y)->text());
                                    }
                                    textEdit->append(line);
                                }
                            });
                
                            btnRow.append(btn);
                        }
                        btns.append(btnRow);
                    }
                    setLayout(layout_);
                }
                

                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                J 1 Reply Last reply 17 Jul 2018, 08:25
                3
                • J J.Hilk
                  17 Jul 2018, 05:48

                  Hi @jensig

                  are you sure, you want to do this without lambdas?

                  Would make this so, so much easier:

                  #ifndef WIDGET_H
                  #define WIDGET_H
                  
                  #include <QWidget>
                  #include <QVector>
                  
                  class QTextEdit;
                  class QPushButton;
                  class QGridLayout;
                  class Widget : public QWidget
                  {
                      Q_OBJECT
                  public:
                      explicit Widget(QWidget *parent = nullptr);
                  
                  
                  private:
                      QVector<QVector<QPushButton*>> btns;
                      QGridLayout *layout_;
                      QTextEdit *textEdit;
                  };
                  
                  #endif // WIDGET_H
                  
                  
                  #include "widget.h"
                  #include <QGridLayout>
                  #include <QTextEdit>
                  #include <QPushButton>
                  
                  static const unsigned SIZE_LONG = 15;
                  static const unsigned SIZE_BITS = 4;
                  
                  Widget::Widget(QWidget *parent)
                      : QWidget(parent)
                  {
                  
                      layout_ = new QGridLayout;
                      textEdit = new QTextEdit();
                      textEdit->resize(100,100);
                      textEdit->show();
                  
                      for (int i = 0; i < SIZE_LONG; ++i) {
                          QVector<QPushButton*> btnRow;
                          for (int j = 0; j < SIZE_BITS; ++j) {
                              QPushButton *btn = new QPushButton("0");
                              btn->setCheckable(true);
                              layout_->addWidget(btn,i,j,Qt::AlignHCenter);
                  
                              connect(btn, &QPushButton::toggled, this, [=](bool checked){
                                  btn->setText(checked ? "1" : "0");
                                  textEdit->clear();
                                  for(int x(0); x < btns.size(); x++){
                                      QString line;
                                      for(int y(0); y < btns.at(x).size(); y++){
                                          line.append(btns.at(x).at(y)->text());
                                      }
                                      textEdit->append(line);
                                  }
                              });
                  
                              btnRow.append(btn);
                          }
                          btns.append(btnRow);
                      }
                      setLayout(layout_);
                  }
                  
                  J Offline
                  J Offline
                  jensig
                  wrote on 17 Jul 2018, 08:25 last edited by jensig
                  #8

                  @J.Hilk
                  Hi , thanks for the simplification.
                  I changed your code a little but I can't figure out how to put a QTextEdit when a "Calculate" button is pressed like in the picture above.

                  Is there any particular reason why you've written QTextEdit, QPushButton, QGridLayout in a forward declaration instead of includes?

                  #include "widget.h"
                  #include <QGridLayout>
                  #include <QTextEdit>
                  #include <QPushButton>
                  
                  static const unsigned SIZE_LONG = 15;
                  static const unsigned SIZE_BITS = 4;
                  
                  Widget::Widget(QWidget *parent)
                      : QWidget(parent)
                  {
                  
                      layout_ = new QGridLayout;
                      textEdit_ = new QTextEdit();
                      textEdit_->resize(100, 100);
                      //textEdit_->show();
                      QPushButton *btnCalculate = new QPushButton("Calculate");
                      btnCalculate->setCheckable(true);
                  
                      for (unsigned i = 0; i < SIZE_LONG; ++i) {
                          QVector<QPushButton*> btnRow;
                          for (unsigned j = 0; j < SIZE_BITS; ++j) {
                              QPushButton *btn = new QPushButton("0");
                              btn->setCheckable(true);
                              layout_->addWidget(btn, i, j, Qt::AlignHCenter);
                  
                              if (i == SIZE_LONG - 1 && j == SIZE_BITS - 1) {
                  
                                  layout_->addWidget(btnCalculate, i + 1, j, Qt::AlignRight);
                              }
                                  connect(btn, &QPushButton::toggled, this, [=](bool checked){
                                      btn->setText(checked ? "1" : "0");
                                      
                  
                                      textEdit_->clear();
                                      for(int x = 0; x < btns_.size(); x++){
                                          QString line;
                                          for(int y = 0; y < btns_[x].size(); y++){
                                              line.append(btns_[x][y]->text());
                                          }
                                          textEdit_->append(line);
                                      }
                                  });
                                  connect(btnCalculate, &QPushButton::toggled, this, [=](bool calculate){
                                         if (calculate == false)
                                            layout_->addWidget(textEdit_, 0, SIZE_BITS + 1, Qt::AlignHCenter);
                                  });
                  
                              btnRow.append(btn);
                          }
                          btns_.append(btnRow);
                      }
                      setLayout(layout_);
                  }
                  

                  widget.h

                  #ifndef WIDGET_H
                  #define WIDGET_H
                  
                  #include <QWidget>
                  #include <QVector>
                  
                  class QTextEdit;
                  class QPushButton;
                  class QGridLayout;
                  class Widget : public QWidget
                  {
                      Q_OBJECT
                  public:
                      explicit Widget(QWidget *parent = nullptr);
                  
                  
                  private:
                      QVector<QVector<QPushButton*>> btns_;
                      QGridLayout *layout_;
                      QTextEdit *textEdit_;
                  };
                  
                  #endif // WIDGET_H
                  

                  Thank you

                  J 1 Reply Last reply 17 Jul 2018, 08:37
                  0
                  • J jensig
                    17 Jul 2018, 08:25

                    @J.Hilk
                    Hi , thanks for the simplification.
                    I changed your code a little but I can't figure out how to put a QTextEdit when a "Calculate" button is pressed like in the picture above.

                    Is there any particular reason why you've written QTextEdit, QPushButton, QGridLayout in a forward declaration instead of includes?

                    #include "widget.h"
                    #include <QGridLayout>
                    #include <QTextEdit>
                    #include <QPushButton>
                    
                    static const unsigned SIZE_LONG = 15;
                    static const unsigned SIZE_BITS = 4;
                    
                    Widget::Widget(QWidget *parent)
                        : QWidget(parent)
                    {
                    
                        layout_ = new QGridLayout;
                        textEdit_ = new QTextEdit();
                        textEdit_->resize(100, 100);
                        //textEdit_->show();
                        QPushButton *btnCalculate = new QPushButton("Calculate");
                        btnCalculate->setCheckable(true);
                    
                        for (unsigned i = 0; i < SIZE_LONG; ++i) {
                            QVector<QPushButton*> btnRow;
                            for (unsigned j = 0; j < SIZE_BITS; ++j) {
                                QPushButton *btn = new QPushButton("0");
                                btn->setCheckable(true);
                                layout_->addWidget(btn, i, j, Qt::AlignHCenter);
                    
                                if (i == SIZE_LONG - 1 && j == SIZE_BITS - 1) {
                    
                                    layout_->addWidget(btnCalculate, i + 1, j, Qt::AlignRight);
                                }
                                    connect(btn, &QPushButton::toggled, this, [=](bool checked){
                                        btn->setText(checked ? "1" : "0");
                                        
                    
                                        textEdit_->clear();
                                        for(int x = 0; x < btns_.size(); x++){
                                            QString line;
                                            for(int y = 0; y < btns_[x].size(); y++){
                                                line.append(btns_[x][y]->text());
                                            }
                                            textEdit_->append(line);
                                        }
                                    });
                                    connect(btnCalculate, &QPushButton::toggled, this, [=](bool calculate){
                                           if (calculate == false)
                                              layout_->addWidget(textEdit_, 0, SIZE_BITS + 1, Qt::AlignHCenter);
                                    });
                    
                                btnRow.append(btn);
                            }
                            btns_.append(btnRow);
                        }
                        setLayout(layout_);
                    }
                    

                    widget.h

                    #ifndef WIDGET_H
                    #define WIDGET_H
                    
                    #include <QWidget>
                    #include <QVector>
                    
                    class QTextEdit;
                    class QPushButton;
                    class QGridLayout;
                    class Widget : public QWidget
                    {
                        Q_OBJECT
                    public:
                        explicit Widget(QWidget *parent = nullptr);
                    
                    
                    private:
                        QVector<QVector<QPushButton*>> btns_;
                        QGridLayout *layout_;
                        QTextEdit *textEdit_;
                    };
                    
                    #endif // WIDGET_H
                    

                    Thank you

                    J Offline
                    J Offline
                    J.Hilk
                    Moderators
                    wrote on 17 Jul 2018, 08:37 last edited by
                    #9

                    @jensig
                    can you clarify, what exactly is supposed to happen when caluclate is pressed? It's hard to guess from the code example.


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    J 1 Reply Last reply 17 Jul 2018, 20:27
                    1
                    • J J.Hilk
                      17 Jul 2018, 08:37

                      @jensig
                      can you clarify, what exactly is supposed to happen when caluclate is pressed? It's hard to guess from the code example.

                      J Offline
                      J Offline
                      jensig
                      wrote on 17 Jul 2018, 20:27 last edited by jensig
                      #10

                      @J.Hilk
                      I couldn't prevent QTextEdit from changing the spacing between rows when it is called with the QPushButton "Calculate" (see image in my first post). Spacing between rows 1, 2 & 3 change when QTextEdit is placed there. I tried to follow @jsulm 's advice but I think he refers to spacing inside QTextEdit and not the spacing between the rows of buttons.
                      I've also tried to follow the documentation without much result Qt5 Layouts.

                      I tried this, but it crashes instantly:
                      The rest of my code is identical to my previous post, where I changed your code.

                                      connect(btnCalculate, &QPushButton::toggled, this, [=](bool calculate){
                                             if (calculate) {
                                                  vLayout_->addWidget(textEdit_); // from QVBoxLayout *vLayout_;
                                                  groupBox_->setLayout(vLayout_); // from QGroupBox *groupBox_;
                                                  layout_->addWidget(groupBox_, 0, SIZE_BITS + 1, Qt::AlignRight); // from QGridLayout *layout_;
                                                 //layout_->setSpacing(0);
                                             }
                                      });
                      
                      The program has unexpectedly finished.
                      The process was ended forcefully.
                      

                      Thank you

                      J 1 Reply Last reply 17 Jul 2018, 21:24
                      0
                      • J jensig
                        17 Jul 2018, 20:27

                        @J.Hilk
                        I couldn't prevent QTextEdit from changing the spacing between rows when it is called with the QPushButton "Calculate" (see image in my first post). Spacing between rows 1, 2 & 3 change when QTextEdit is placed there. I tried to follow @jsulm 's advice but I think he refers to spacing inside QTextEdit and not the spacing between the rows of buttons.
                        I've also tried to follow the documentation without much result Qt5 Layouts.

                        I tried this, but it crashes instantly:
                        The rest of my code is identical to my previous post, where I changed your code.

                                        connect(btnCalculate, &QPushButton::toggled, this, [=](bool calculate){
                                               if (calculate) {
                                                    vLayout_->addWidget(textEdit_); // from QVBoxLayout *vLayout_;
                                                    groupBox_->setLayout(vLayout_); // from QGroupBox *groupBox_;
                                                    layout_->addWidget(groupBox_, 0, SIZE_BITS + 1, Qt::AlignRight); // from QGridLayout *layout_;
                                                   //layout_->setSpacing(0);
                                               }
                                        });
                        
                        The program has unexpectedly finished.
                        The process was ended forcefully.
                        

                        Thank you

                        J Offline
                        J Offline
                        J.Hilk
                        Moderators
                        wrote on 17 Jul 2018, 21:24 last edited by J.Hilk
                        #11

                        Ok @jensig ,
                        as a general rule of thumb, don‘t dynamically create widgets in slots such as "button clicks", that‘s bad design and will end up slowing down your application pretty fast and you may loose oversight of what widget was created and still needs to be deleted. Etc.

                        That said, you can create the QTextEdit during the Button setup and refere it later on.

                        But, QPushButtons have by default a fixed height and placing the QTextEdit into the gridlayout will result in „streched „ rows like you have it in the op.

                        Two solutions I can think of:

                        • Nesting layouts

                        Place your gridlayout and the QTextEdit as Widgets in a QHorizontalLayout. That should solve your issue

                        • stretching the QTextEdit over all rows of the Gridlayout

                        For that I‘ll adjust my example code:
                        Right after the QPushbutton create loop:

                        ...
                        layout_->addWidget(TextEdit,0,SIZE_BITS,SIZE_LONG,1);
                        

                        addWidget has an overload that allows colmns and rows that it shall span:

                        void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = ...)

                        Edit: fixed obious spelling mistakes, creating posts at 1 am on an iPad is apparently not the best idea.


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        1 Reply Last reply
                        1

                        8/11

                        17 Jul 2018, 08:25

                        • Login

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