【问题标题】:Linking a QWidget to another QWidget new created将 QWidget 链接到另一个新创建的 QWidget
【发布时间】:2020-10-14 13:28:01
【问题描述】:

我试图通过按下主 QWidget 中的一个按钮来创建一个新的 QWidget。在新创建的 QWidget 中,我希望有一个按钮连接到主 QWidget 的插槽。

class UI : public QWidget
{
public:
    UI(){connection();};
private:
    QPushButton* all = new QPushButton{ "ALL" };
    void connection(){
       QObject::connect(all,QPushButton::clicked,[](){
             SmallGUI* s=new SmallGUI{};
             s->show();
       });
    }

    void something(){
       //something
    }

还有二等

class SmallGUI1 :
    public QWidget
{
public:
    SmallGUI(){connection();};
private:
     QPushButton* N =new QPushButton;
     
     void connection(){
       //to connect N to something()
     }

我想将 N 连接到 something() 。

【问题讨论】:

    标签: c++ qt qwidget


    【解决方案1】:

    在我们开始之前,您的代码还有一些其他问题。

    请注意,在您的第二个类中,构造函数的名称与类不同,这会导致一些...问题。 您还忘记为您的按钮添加父级(这可能会导致一些意外结果)为您的小部件(这又不是一个好主意)。

    话虽如此,让我们进入主题。

    我倾向于只在 .h 文件中放置原型并声明属性以使代码更清晰,但您当然可以根据自己的需要或自己的编程约定对其进行调整。

    有几种方法可以做这样的事情,但最简单的应该是这样的:

    SmallGUI1.h:

    #include "UI.h" //The file in which the class UI is declared
    //OR :
    //class UI; //If you need to include this file in UI.h
    
    class SmallGUI1 : public QWidget{
    
                Q_OBJECT //Q_OBJECT macro, check the doc for more explainations about it
    
    public:
        explicit SmallGUI1(UI *parent = nullptr); //Explicit means that this constructor cannot be used for implicit casts
        ~SmallGUI1();//Destructor needed because I only put the constructor above
    private:
         QPushButton* N; //Not very good looking to initialize attributes in the .h in my opinion, but works fine.
    
         }
     
    

    SmallGUI1.cpp:

    SmallGUI1::SmallGUI1(UI *parent) : QWidget(parent){
        
        N = new QPushButton(tr("Some text on the button") , this); //tr to enable translation on this string
        
        
        //************* If I understood your question correctly, this is what you are looking for *************
        connect(N , &QPushButton::clicked , parent , &UI::doSomething); //Select the signal you want
        
        /*
        Some code here
        */
        
        show();
        
    }
    
    SmallGUI1::~SmallGUI1(){qDeleteAll(children());}
    

    UI.h:

    class UI : public QWidget{
        
            Q_OBJECT
        
    public:
        explicit UI(QWidget *parent = nullptr);
        ~UI();
    private:
        QPushButton* all;
    
    private slots :
        void createSmallGUI1();
        void doSomething();
    }
    

    UI.cpp:

    #include "SmallGUI1.h"
    
    UI::UI(QWidget *parent) : QWidget(parent){
        
        all = new QPushButton(tr("ALL") , this);
            
            
        connect(all , &QPushButton::clicked , this , &UI::createSmallGUI1);
        /*
        Some code here
        */
        
        
    }
    
    UI::~UI(){qDeleteAll(children());}
    
    void UI::createSmallGUI1(){SmallGUI1 *gui = new SmallGUI1(this);}
    
    void UI::doSomething(){
        
        /*
        Clever code here
        */
        
    }
    

    【讨论】:

      【解决方案2】:

      您可以将第二个小部件定义为主小部件的子小部件以使事情变得更容易:

      class UI : public QWidget {
      ...
       private:
        SmallGUI* s;
      ...
      

      然后在 UI 构造函数中初始化它以及您的 all 按钮。您最初可以隐藏子小部件或禁用它:

         UI() {
          all = new QPushButton{"ALL", this};
          setWindowTitle("UI");  // just for clarification
          s = new SmallGUI(this);
          s->hide();
          connection();
        };
      

      并通过按钮点击信号“显示”它

      connect(all, &QPushButton::clicked, s, &SmallGUI::show);
      

      这样做可以让您选择将N 按钮的点击信号连接到父类中的something 函数

      connect(s->N, &QPushButton::clicked, this, &UI::something);
      

      完整的程序如下,

      #include <QApplication>
      #include <QMessageBox>
      #include <QPushButton>
      #include <QWidget>
      
      class SmallGUI : public QWidget {
       public:
        SmallGUI(QWidget* parent) : QWidget(parent) {
          N = new QPushButton{"btn2", this};
          connection();
        };
        QPushButton* N;
      
       private:
        void connection(){};
      };
      
      class UI : public QWidget {
       public:
        UI() {
          all = new QPushButton{"ALL", this};
          setWindowTitle("UI");  // just for clarification
          s = new SmallGUI(this);
          s->hide();
          connection();
        };
      
       private:
        SmallGUI* s;
        QPushButton* all;
        void connection() {
          connect(all, &QPushButton::clicked, s, &SmallGUI::show);
      
          connect(s->N, &QPushButton::clicked, this, &UI::something);
        }
      
        void something() { QMessageBox::information(this, "Hello", "Hello"); }
      };
      
      int main(int argc, char* argv[]) {
        QApplication a(argc, argv);
      
        UI w;
        w.show();
      
        return a.exec();
      }
      
      

      【讨论】:

        【解决方案3】:

        从“嵌套”类连接到父插槽不是一个好主意,因为 SmallGUI1 将绑定到类 UI。 我认为这是更好的解决方案:

        class UI : public QWidget
        {
        public:
        UI(){connection();};
        private:
        QPushButton* all = new QPushButton{ "ALL" };
        void connection(){
           QObject::connect(all,QPushButton::clicked,[](){
                 SmallGUI1* s=new SmallGUI1;
                 connect(s,&USmallGUI1::button_clicked,this,&UI::something);
                 s->show();
           });
        }
        
        void something(){
           //something
        }
        

        还有 SmallGUI1 类:

        class SmallGUI1 :
            public QWidget
        {
        public:
            SmallGUI1(){connection();};
        signals:
        void button_clicked();
        private:
             QPushButton* N;
             
             void connection(){
               //to connect N to something()
               N = new QPushButton;
               connect(N,&QPushButton::clicked,this,&SmallGUI1::button_clicked)
             }
        

        这样,您将 QPusButton::clicked 信号从 SmallGUI1 连接到信号 SmallGUI1::button_clicked()。不需要实现额外的插槽,只需将信号连接到信号即可。 在 UI 中,您将 button_clicked() 信号连接到插槽 dosomething()

        不要忘记 SmallGUI1 的构造函数!在您的代码中,SmallGUI() 只是一个方法,在 SmallGUI1 实例化时不会调用,需要您自己调用。

        【讨论】:

          猜你喜欢
          • 2020-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-26
          • 1970-01-01
          • 2011-07-28
          • 2014-11-03
          • 2018-01-24
          相关资源
          最近更新 更多