Results 1 to 13 of 13

Thread: Having one code for every pushButton

  1. #1
    Join Date
    Jun 2020
    Posts
    11
    Qt products
    Qt4 Qt5

    Default Having one code for every pushButton

    Hey, I have a 10x10 field of pushButtons and I have a Code for what happens, when one is clicked. How can I rewrite the Code, so that the Code applies for every pushButton and I dont have to rewrite my Code for every one of them? With my Code I would have to create 100 variable and have to Change every one in the Code for each pushButton plus I would rewrite the Name of the pushButton in every one. I would like to have a Code which I can copy and paste in every pushButton. I searched a lot but with my Knowledge a lot is hard to understand. Maybe you have any idea?
    My Code so far is:

    int i=1;

    void MainWindow:n_pushButton_clicked()
    {
    if((i==1))
    {
    ui->pushButton->setStyleSheet("QPushButton { background-color: grey; }\n"
    "QPushButton:enabled { background-color: rgb(200,0,0,100); }\n");
    i=i+1;

    }
    else
    {
    if((i==2))
    {
    ui->pushButton->setStyleSheet("QPushButton { background-color: grey; }\n"
    "QPushButton:enabled { background-color: rgb(0,200,0,100); }\n");
    i=i+1;
    }
    else
    {
    ui->pushButton-> setStyleSheet("QPushButton { }\n"
    "QPushButton:enabled { }\n");
    i=i-2;
    }
    }

    }

  2. #2
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    If you want to handle the event with the same code for each QPushButton, use the QObject::sender method in the slot function. Your method should look something like this :
    Qt Code:
    1. void MainWindow::on_pushButton_clicked()
    2. {
    3. QPushButton *ptr = dynamic_cast<QPushButton*>(sender());
    4. if(ptr == nullptr)
    5. return;
    6. if((i==1))
    7. {
    8. ptr->setStyleSheet("QPushButton { background-color: grey; }\n"
    9. "QPushButton:enabled { background-color: rgb(200,0,0,100); }\n");
    10. i=i+1;
    11. }
    12. else
    13. {
    14. if((i==2))
    15. {
    16. ptr->setStyleSheet("QPushButton { background-color: grey; }\n"
    17. "QPushButton:enabled { background-color: rgb(0,200,0,100); }\n");
    18. i=i+1;
    19. }
    20. else
    21. {
    22. ptr-> setStyleSheet("QPushButton { }\n"
    23. "QPushButton:enabled { }\n");
    24. i=i-2;
    25. }
    26. }
    27. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jun 2020
    Posts
    11
    Qt products
    Qt4 Qt5

    Default Re: Having one code for every pushButton

    Yeah that helps a lot. Little Problem now is that when since int i=1 is out of the pushbutton function, when I now click on a button and then on another i does not equal to 1 anymore so the order of what happens is not the same. When I include int i=1 in the pushbutton function it Always starts at 1 and only the first if-cause is active. Do you have a solution to that as well?
    Last edited by ejoty; 17th June 2020 at 12:39.

  4. #4
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    No because I don't know what it is variable i. Does it apply to all buttons together or separately, where it is modified.

  5. #5
    Join Date
    Jun 2020
    Posts
    11
    Qt products
    Qt4 Qt5

    Default Re: Having one code for every pushButton

    Well I want the pushButton to Change Color when clicked on. So "i" is just a avariable I used to help me assaign a number to a Color, regarding how many times the Buttons is already clicked on, so that I get different Colors when the pushbutton is clicked multiple times. I would like to have the 10x10 field of pushbuttons in which no metter which pushButton gets clicked its Color changes from red to green to blue and then again red green blue and so on. If I use my Code up I would to have 100 variables one for each push button. The way I did it "i" can not apply to all Buttons because then the order is disturbed. But I would like to find a way to have "i" apply to everyone so that I dont have to use a different variable for every pushbutton.

  6. #6
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    So the counter for each buttton separately. I suggest using QMap <QPushButtton *, int>. The service would look something like this.
    Qt Code:
    1. QMap<QPushButton*,int> counter_list;//defined as MainWindow variable
    2. void MainWindow::on_pushButton_clicked()
    3. {
    4. QPushButton *ptr = dynamic_cast<QPushButton*>(sender());
    5. if(ptr == nullptr)
    6. return;
    7.  
    8. int counter = 1;
    9. if(!counter_list.contains(ptr))
    10. counter = counter_list.value(ptr);
    11.  
    12. if(counter==1)
    13. {
    14. ptr->setStyleSheet("QPushButton { background-color: grey; }\n"
    15. "QPushButton:enabled { background-color: rgb(200,0,0,100); }\n");
    16. counter=counter+1;
    17. }
    18. else
    19. {
    20. if(counter==2)
    21. {
    22. ptr->setStyleSheet("QPushButton { background-color: grey; }\n"
    23. "QPushButton:enabled { background-color: rgb(0,200,0,100); }\n");
    24. counter=counter+1;
    25. }
    26. else
    27. {
    28. ptr-> setStyleSheet("QPushButton { }\n"
    29. "QPushButton:enabled { }\n");
    30. counter=counter-2;
    31. }
    32. }
    33. counter_list.insert(ptr,counter);
    34. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Jun 2020
    Posts
    11
    Qt products
    Qt4 Qt5

    Default Re: Having one code for every pushButton

    Hmm..now on the first click the Color does not Change, on the second it turns red and then it stays red. Maybe you see my mistake:

    ```
    #include "map.h"
    #include "ui_map.h"

    Map::Map(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Map)
    {
    ui->setupUi(this);
    }

    Map::~Map()
    {
    delete ui;
    }

    QMap<QPushButton*,int> counter_list;
    void Map:n_pushButtonMap1_clicked()
    {
    QPushButton *ptr = dynamic_cast<QPushButton*>(sender());
    if(ptr == nullptr)
    return;

    int counter = 1;
    if(!counter_list.contains(ptr))
    counter = counter_list.value(ptr);

    if(counter==1)
    {
    ptr->setStyleSheet("QPushButton { background-color: grey; }\n"
    "QPushButton:enabled { background-color: rgb(200,0,0,100); }\n");
    counter=counter+1;
    }
    else
    {
    if(counter==2)
    {
    ptr->setStyleSheet("QPushButton { background-color: grey; }\n"
    "QPushButton:enabled { background-color: rgb(0,200,0,100); }\n");
    counter=counter+1;
    }
    else
    {
    ptr-> setStyleSheet("QPushButton { }\n"
    "QPushButton:enabled { }\n");
    counter=counter-2;
    }
    }
    counter_list.insert(ptr,counter);
    }
    ```

    I think its because "int counter=1" is inside the pushbutton function and whenever I click on it the System resets the counter to 1. But you probably know better than I do

  8. #8
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    1. Please use the CODE tag in your posts.
    2. counter_list should be declared in Map.h as Map class field.
    3. Line 9 from my post should be :
    Qt Code:
    1. if(counter_list.contains(ptr))
    To copy to clipboard, switch view to plain text mode 
    not
    Qt Code:
    1. if(!counter_list.contains(ptr))
    To copy to clipboard, switch view to plain text mode 
    Let's play "find the difference" and tell us why.
    4. Variable counter should be initialized with the value to be after the first click, maybe 2 instead of 1.

  9. #9
    Join Date
    Jun 2020
    Posts
    11
    Qt products
    Qt4 Qt5

    Default Re: Having one code for every pushButton

    Sry I dont know yet where the Code tag is. But now it works! I thank you very much. If you would like to it would be very nice if you could explain to me what line is doing what because I really am a beginner in c++ and I would also like to know what I do and not just copy and paste.

    QMap<QPushButton*,int> counter_list;
    void MainWindow:n_pushButton_clicked()
    {
    QPushButton *ptr = dynamic_cast<QPushButton*>(sender());
    if(ptr == nullptr)
    return;



    if(!counter_list.contains(ptr))
    counter = counter_list.value(ptr);

    counter_list.insert(ptr,counter);

    These lines I do not understand. If you could explain them to me it would be very Kind of you. However you helped me really a lot. Can I somehow give you a thumbs up or anything? Sry I am new here

  10. #10
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    Go to advanced editor and use button with #.
    1.
    Qt Code:
    1. QPushButton *ptr = dynamic_cast<QPushButton*>(sender());
    2. if(ptr == nullptr)
    3. return;
    To copy to clipboard, switch view to plain text mode 
    This is a test if our function is invoked by signal from QPushButton. If not we do nothing. Read about QObject::sender and dynamic_cast (C++ ABC).
    2.
    Qt Code:
    1. if(!counter_list.contains(ptr))
    2. counter = counter_list.value(ptr);
    To copy to clipboard, switch view to plain text mode 
    We check whether our list contains a counter for a specific button. If so we read it.
    3.
    Qt Code:
    1. counter_list.insert(ptr,counter);
    To copy to clipboard, switch view to plain text mode 
    We remember the counter of our button.

    Read in Qt doc how QMap is working.

  11. #11
    Join Date
    Jul 2008
    Location
    Germany
    Posts
    503
    Thanks
    11
    Thanked 76 Times in 74 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    Hi, I think in
    Qt Code:
    1. if(!counter_list.contains(ptr))
    To copy to clipboard, switch view to plain text mode 
    the ! operator is wrong. We want to get the value if the list contains the pointer.

    Ginsengelf

  12. #12
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Having one code for every pushButton

    That's exactly it.

  13. #13
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Having one code for every pushButton

    QSignalMapper is also worth a look for these multiple-button to one slot jobs.

    However, it seems to me that the buttons should each be a custom class instance that tracks its own internal state and renders itself in the appropriate colour for its current state: no containing widget logic required. You might provide a signal to indicate that the state had changed to external observers, and an access function to retrieve (or set if needed) the state from outside. Here's the sort of thing I had in mind:
    Qt Code:
    1. // fancybutton.h
    2. #ifndef FANCYBUTTON_H
    3. #define FANCYBUTTON_H
    4.  
    5. #include <QPushButton>
    6. #include <QVector>
    7. #include <QString>
    8.  
    9. class FancyButton : public QPushButton
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. FancyButton(QWidget *parent = nullptr);
    15. ~FancyButton();
    16.  
    17. private:
    18. void bumpState(bool checked = false);
    19. int m_state;
    20.  
    21. static QVector<QString> m_styles;
    22. };
    23. #endif // FANCYBUTTON_H
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. // fancybutton.cpp
    2. #include "fancybutton.h"
    3.  
    4. QVector<QString> FancyButton::m_styles =
    5. QVector<QString>(
    6. {
    7. QStringLiteral("QPushButton { background-color: grey; } "
    8. "QPushButton:enabled { background-color: rgb(200,0,0); }"),
    9. QStringLiteral("QPushButton { background-color: grey; } "
    10. "QPushButton:enabled { background-color: rgb(0,200,0); }"),
    11. QStringLiteral("QPushButton { background-color: grey; } "
    12. "QPushButton:enabled { background-color: rgb(0,0,200); }"),
    13. });
    14.  
    15. FancyButton::FancyButton(QWidget *parent)
    16. : QPushButton(parent)
    17. , m_state(0)
    18. {
    19. setStyleSheet(m_styles.at(m_state));
    20.  
    21. connect(this, &FancyButton::clicked, this, &FancyButton::bumpState);
    22. }
    23.  
    24. FancyButton::~FancyButton()
    25. {
    26. }
    27.  
    28. void FancyButton::bumpState(bool /*checked*/)
    29. {
    30. m_state = (m_state + 1) % m_styles.count();
    31. setStyleSheet(m_styles.at(m_state));
    32. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. // main.cpp
    2. #include "fancybutton.h"
    3.  
    4. #include <QApplication>
    5. #include <QWidget>
    6. #include <QGridLayout>
    7.  
    8. int main(int argc, char *argv[])
    9. {
    10. QApplication a(argc, argv);
    11. QGridLayout *layout = new QGridLayout(&w);
    12. for (int r = 0; r < 4; ++r) {
    13. for (int c = 0; c < 4; ++c) {
    14. layout->addWidget(new FancyButton(), r, c);
    15. }
    16. }
    17.  
    18. w.show();
    19. return a.exec();
    20. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 2
    Last Post: 20th January 2017, 03:14
  2. PushButton
    By acuce in forum Qt Programming
    Replies: 2
    Last Post: 13th July 2012, 21:06
  3. pyQT how do I enable or disable a pushbutton from the main code?
    By Michael Druckenmiller Sr in forum Newbie
    Replies: 1
    Last Post: 12th January 2012, 19:44
  4. Replies: 3
    Last Post: 29th April 2011, 09:54
  5. Pasting code from code tag in emacs
    By Gopala Krishna in forum General Discussion
    Replies: 0
    Last Post: 16th February 2007, 06:47

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.