简体   繁体   English

将 QWidget 链接到另一个新创建的 QWidget

[英]Linking a QWidget to another QWidget new created

I am try to, by pressing a button in the main QWidget, to create a new QWidget.我试图通过按下主 QWidget 中的按钮来创建一个新的 QWidget。 In that new created QWidget I want to have a button connected to a slot of the main 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
    }

and the second class和第二个 class

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

I want to connect N to something().我想将 N 连接到某物()。

Before we start, there are some other problems with you code.在我们开始之前,您的代码还有一些其他问题。

Note that in your second class, the constructor is not named the same as the class , which will cause some... Problems.请注意,在您的第二个 class 中,构造函数的名称与 class 的名称不同,这会导致一些...问题。 You also forgot to put a parent for your buttons (which may thus cause some unexpected results) AND for your Widgets (which is again not a good idea).您还忘记为您的按钮(这可能会导致一些意想不到的结果)和您的小部件(这又不是一个好主意)放置一个父级。

So, that being said, let us get to the main topic.话虽如此,让我们进入主题。

I tend to only put prototypes and declare the attributes in the.h file to make the code clearer, but you may of course adapt it to your needs or to your own programming convention.我倾向于只在 .h 文件中放置原型并声明属性以使代码更清晰,但您当然可以根据自己的需要或自己的编程约定对其进行调整。

There are several ways to do something like this, but the simplest one should look like this:有几种方法可以做这样的事情,但最简单的应该是这样的:

SmallGUI1.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.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:用户界面.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:用户界面.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
    */
    
}

You can define the second widget as a child of the main widget to make things easier:您可以将第二个小部件定义为主小部件的子小部件,以使事情变得更容易:

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

and then initialize it in the UI constructor, along with your all button.然后在 UI 构造函数中初始化它,以及你的all按钮。 You can initially hide the child widget or disable it:您最初可以隐藏子小部件或禁用它:

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

and 'show' it with button clicked signal并用按钮点击信号“显示”它

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

Doing so gives you the option to connect the clicked signal of your N button to the something function in the parent class这样做可以让您选择将N按钮的点击信号连接到父 class 中的something function

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

The complete program would be as follows,完整的程序如下,

#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();
}

It is not good idea to connect to parent's slots from "nested" class, since SmallGUI1 will be tied to class UI.从“嵌套”class 连接到父插槽不是一个好主意,因为 SmallGUI1 将绑定到 class UI。 Here is better solution, I think:我认为这是更好的解决方案:

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
}

And SmallGUI1 class:和 SmallGUI1 class:

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)
     }

This way, you are connecting QPusButton::clicked signal from SmallGUI1 to the signal SmallGUI1::button_clicked().这样,您将 QPusButton::clicked 信号从 SmallGUI1 连接到信号 SmallGUI1::button_clicked()。 Dont need to implement additional slot, just connect signal to signal.不需要实现额外的插槽,只需将信号连接到信号即可。 And in UI you are connecting button_clicked() signal to the slot dosomething()在 UI 中,您将 button_clicked() 信号连接到插槽 dosomething()

DONT FORGET THE CONSTRUCTOR OF SmallGUI1, In your code, SmallGUI() will be just a method, which will not be called when SmallGUI1 is instantiated.不要忘记 SmallGUI1 的构造函数,在您的代码中,SmallGUI() 将只是一个方法,在 SmallGUI1 实例化时不会调用该方法。 and you have to call it by yourself.你必须自己调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM