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. QPushButton not clickable even if activated
Forum Updated to NodeBB v4.3 + New Features

QPushButton not clickable even if activated

Scheduled Pinned Locked Moved Solved General and Desktop
qpushbuttonvisual studiovs 2019qt 5.12.4qt 5.12
7 Posts 3 Posters 3.3k 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.
  • L Offline
    L Offline
    Lanfeust
    wrote on last edited by
    #1

    Hey!

    I'm programming a little software to help me coding my future softwares: its goal is to generate repetitive code when I create classes. My problem is for the part of code linked to the creation of constructors. We can have more than one constructor so I wanted to create a list in which there are items on the side of minus signs (which delete this item) and, at the end of the list, there is a button with a plus sign (which adds an item) (see picture below). My problem is that when I add/remove some items, at some point, some button won't be clickable anymore; there is no visual changement when the mouse is over the button (no highlighting), even if the rest of the visual part is normal. I don't exactly understand where it's coming from, and the only way to "unlock" the buttons is to turn the window into full screen.

    Picture of the list with plus and minus signed buttons:
    0_1564237922970_aaasssddd.PNG

    I'd really like some help if you understand where the error is coming from. To help you for that, you'll find my code just under this. I'm using Qt 5.12.4 extension on Visual Studio 2019.

    main.cpp

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

    window.h

    #ifndef DEF_WINDOW
    #define DEF_WINDOW
    
    #include "Constructor.h"
    
    #include <QWidget>
    #include <QVBoxLayout>
    #include <QPushButton>
    
    #include <vector>
    
    class Window : public QWidget
    {
    	Q_OBJECT
    
    public:
    	Window();
    
    public slots:
    	void addConstructor();
    
    private:
    	QVBoxLayout* mainLayout = new QVBoxLayout;
    	QVBoxLayout* constructorLayout = new QVBoxLayout;
    	std::vector<Constructor*>* constructorVector = new std::vector<Constructor*>;
    	QPushButton* addConstructorButton = new QPushButton("+", this);
    };
    
    #endif
    

    window.cpp

    #include "Window.h"
    
    Window::Window() {
    	connect(addConstructorButton, SIGNAL(clicked()), this, SLOT(addConstructor()));
    
    	mainLayout->addLayout(constructorLayout);
    	mainLayout->addWidget(addConstructorButton);
    	setLayout(mainLayout);
    }
    
    void Window::addConstructor() {
    	Constructor* c = new Constructor(this, constructorLayout, constructorVector);
    	constructorLayout->addWidget(c);
    	constructorVector->push_back(c);
    }
    

    constructor.h

    #ifndef DEF_CONSTRUCTOR
    #define DEF_CONSTRUCTOR
    
    #include <QWidget>
    #include <QLineEdit>
    #include <QHBoxLayout>
    #include <QPushButton>
    #include <QLayout>
    
    #include <vector>
    
    class Constructor : public QWidget
    {
    	Q_OBJECT
    
    public:
    	Constructor(QWidget* parentWidget, QLayout* parentLayout, std::vector<Constructor*>* parentVector);
    
    public slots:
    	void destroySelf();
    
    private:
    	QLineEdit* lineEdit = new QLineEdit(this);
    
    	QPushButton* removeConstructorButton = new QPushButton("-", this);
    	QLayout* parentLayout;
    	QWidget* parentWidget;
    	std::vector<Constructor*>* parentVector;
    };
    
    #endif
    

    constructor.cpp

    #include "Constructor.h"
    
    Constructor::Constructor(QWidget* parentWidget, QLayout* parentLayout, std::vector<Constructor*>* parentVector) : QWidget(parentWidget)
    {
    	this->parentWidget = parentWidget;
    	this->parentLayout = parentLayout;
    	this->parentVector = parentVector;
    
    	connect(removeConstructorButton, SIGNAL(clicked()), this, SLOT(destroySelf()));
    
    	QHBoxLayout* layout = new QHBoxLayout;
    	layout->addWidget(lineEdit);
    	layout->addWidget(removeConstructorButton);
    	setLayout(layout);
    }
    
    void Constructor::destroySelf()
    {
    	this->disconnect();
    
    	delete lineEdit;
    	delete removeConstructorButton;
    
    	parentLayout->removeWidget(this);
    
    	//remove object from vector
    	for (int i = 0; i < parentVector->size(); i++)
    		if (parentVector->at(i) == this) {
    			parentVector->erase(parentVector->begin() + i);
    			break;
    		}
    }
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      I don't have a direct answer to your question because there's currently nothing really obvious.

      However, there's at least one issue I can see in the design. Your Constructeur widget knows way more than it should about its containing widget. You are creating a tight loop that will end up a nightmare to maintain.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • L Offline
        L Offline
        Lanfeust
        wrote on last edited by
        #3

        Thank you for you answer.

        I'm not sure I'm completely understanding what you're saying and, mostly, how I should fix it. Which input shouldn't be here and what do you mean by "tight loop" (why will it end up a nightmare to maintain) ?

        I'm sorry, I'm quite new with C++ programming. ^^'

        aha_1980A 1 Reply Last reply
        0
        • L Lanfeust

          Thank you for you answer.

          I'm not sure I'm completely understanding what you're saying and, mostly, how I should fix it. Which input shouldn't be here and what do you mean by "tight loop" (why will it end up a nightmare to maintain) ?

          I'm sorry, I'm quite new with C++ programming. ^^'

          aha_1980A Offline
          aha_1980A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on last edited by aha_1980
          #4

          @lanfeust I guess @SGaist refers to the child-parent relationship.

          A child object should know nothing about its parent. The parent, which holds the childs, should have that knowlegde.

          Otherwise it's very hard to re-use the childs somewhere else.

          Example: When building a car (parent), you mount a motor and a gearbox (childs) to get a powertrain.

          However, neither the motor nor the gearbox know each other. It's the cars responsibility to make sure they fit together.

          Regards

          Qt has to stay free or it will die.

          L 1 Reply Last reply
          3
          • L Offline
            L Offline
            Lanfeust
            wrote on last edited by Lanfeust
            #5
            This post is deleted!
            1 Reply Last reply
            0
            • aha_1980A aha_1980

              @lanfeust I guess @SGaist refers to the child-parent relationship.

              A child object should know nothing about its parent. The parent, which holds the childs, should have that knowlegde.

              Otherwise it's very hard to re-use the childs somewhere else.

              Example: When building a car (parent), you mount a motor and a gearbox (childs) to get a powertrain.

              However, neither the motor nor the gearbox know each other. It's the cars responsibility to make sure they fit together.

              Regards

              L Offline
              L Offline
              Lanfeust
              wrote on last edited by
              #6

              @aha_1980 Very interessant, I think I understand, thank you. :)

              1 Reply Last reply
              1
              • L Offline
                L Offline
                Lanfeust
                wrote on last edited by
                #7

                Thank you everbody, thanks to you I have found a way to correct my program. I did as you told me to do: I removed everything the Constructor object knew about its parent (puting it in the parent instead) and the problem went away. I still don't know from where it was coming, but we can clearly see that having a better-programmed program helps to correct some bugs. ^^

                Thanks again to everybody. :D

                If you want my corrected code, here it is:

                main.cpp (nothing changed)

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

                Window.h

                #ifndef DEF_WINDOW
                #define DEF_WINDOW
                
                #include "Constructor.h"
                
                #include <QWidget>
                #include <QVBoxLayout>
                #include <QPushButton>
                
                #include <vector>
                
                class Window : public QWidget
                {
                	Q_OBJECT
                
                public:
                	Window();
                
                public slots:
                	void addConstructor();
                	void destroyConstructor(Constructor*);
                
                private:
                	QVBoxLayout* mainLayout = new QVBoxLayout;
                	QVBoxLayout* constructorLayout = new QVBoxLayout;
                	std::vector<Constructor*>* constructorVector = new std::vector<Constructor*>;
                	QPushButton* addConstructorButton = new QPushButton("+", this);
                };
                
                #endif
                

                Window.cpp

                #include "Window.h"
                
                Window::Window() 
                {
                	connect(addConstructorButton, SIGNAL(clicked()), this, SLOT(addConstructor()));
                
                	mainLayout->addLayout(constructorLayout);
                	mainLayout->addWidget(addConstructorButton);
                	setLayout(mainLayout);
                }
                
                void Window::addConstructor() 
                {
                	Constructor* c = new Constructor(this);
                	constructorLayout->addWidget(c);
                	constructorVector->push_back(c);
                
                	connect(c, SIGNAL(mustBeDestroyed(Constructor*)), this, SLOT(destroyConstructor(Constructor*)));
                }
                
                void Window::destroyConstructor(Constructor* c) 
                {
                	constructorLayout->removeWidget(c);
                
                	//remove object from vector
                	for (int i = 0; i < constructorVector->size(); i++)
                		if (constructorVector->at(i) == c) {
                			constructorVector->erase(constructorVector->begin() + i);
                			break;
                		}
                }
                

                Constructor,h

                #ifndef DEF_CONSTRUCTOR
                #define DEF_CONSTRUCTOR
                
                #include <QWidget>
                #include <QLineEdit>
                #include <QHBoxLayout>
                #include <QPushButton>
                #include <QLayout>
                
                #include <vector>
                
                class Constructor : public QWidget
                {
                	Q_OBJECT
                
                public:
                	Constructor(QWidget* parentWidget);
                
                public slots:
                	void destroySelf();
                
                signals:
                	void mustBeDestroyed(Constructor*);
                
                private:
                	QLineEdit* lineEdit = new QLineEdit(this);
                	QPushButton* destroyConstructorButton = new QPushButton("-", this);
                };
                
                #endif
                

                Constructor.cpp

                #include "Constructor.h"
                
                Constructor::Constructor(QWidget* parentWidget) : QWidget(parentWidget)
                {
                	connect(destroyConstructorButton, SIGNAL(clicked()), this, SLOT(destroySelf()));
                
                	QHBoxLayout* layout = new QHBoxLayout;
                	layout->addWidget(lineEdit);
                	layout->addWidget(destroyConstructorButton);
                	setLayout(layout);
                }
                
                void Constructor::destroySelf()
                {
                	delete lineEdit;
                	delete destroyConstructorButton;
                
                	emit mustBeDestroyed(this);
                
                	this->disconnect();
                	delete this;
                }
                
                1 Reply Last reply
                0

                • Login

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