简体   繁体   English

C++ Qt 信号与槽

[英]C++ Qt Signals and Slots

I have difficulty connecting to SLOTs defined in a different class. I have 2 classes - Computations and MainWindow.我很难连接到在不同的 class 中定义的 SLOT。我有 2 个类 - Computations 和 MainWindow。 MainWindow is supposed to handle the GUI part of the program only and Computations handles the calculations. MainWindow 应该只处理程序的 GUI 部分,而 Computations 处理计算。 I am creating a calculator.我正在创建一个计算器。

Basically, I want to understand how I can connect to SLOTs in the Computations Class from the MainWindow Class.基本上,我想了解如何从 MainWindow Class 连接到 Computations Class 中的 SLOT。

I guess you already checked the Qt Signals & Slots page . 我想您已经检查了Qt Signals&Slots页面 To implement what you want you need to have an instance of your class in the other one. 要实现您想要的内容,您需要在另一个实例中拥有您的类的一个实例。

So for example in your MainWindow class, you can include the Computations class and create a member variable of it: 因此,例如在您的MainWindow类中,您可以包括Computations类并为其创建一个成员变量:

#include "computations.h"

class MainWindow : public QMainWindow
{
   Q_ObBJECT
public:
   //..
private:
   Computations *_computation;
};

and then in the constructor of MainWindow after initializing the _computation object ( _computation = new Computations(); ) you do the connections like this (works for Qt5): 然后在初始化_computation对象( _computation = new Computations(); )后在MainWindow的构造函数中进行如下连接(适用于Qt5):

QObject::connect(_computation, &Computations::somethingHappened, this, &MainWindow::doSomeGuiStuff);
QObject::connect(this, &MainWindow::guiThingHappened, _computation, &Computations::doSomeComputation);

depending on which way it should go. 取决于应该走哪条路。

I hope this helps. 我希望这有帮助。

Such connections belong at a level where both the UI and the controller (computation object) are available. 这样的连接属于UI和控制器(计算对象)都可用的级别。 Thus, either in the body of main , or in a class that composes that various elements of the application at a high level (such a class usually shouldn't derive from QApplication , though). 因此,无论是在main ,还是在较高层次上组成应用程序各种元素的类中(尽管此类通常通常不应源自QApplication )。

It is almost always too tight of a coupling if the UI class knows of the existence of the computation object, or is somehow tied to its details. 如果UI类知道计算对象的存在或以某种方式与其详细信息联系在一起,则几乎总是太过紧密。 I usually design the UI to have an interface composed of signals and slots of as generic a nature as practicable, and then tie it to one or more controller objects via signal/slot connections. 我通常将UI设计为具有一个由信号和插槽组成的接口,该接口和插槽在实际可行的情况下具有一般性质,然后通过信号/插槽连接将其绑定到一个或多个控制器对象。 I also leverage the property system to expose UI-relevant properties in a generic manner, often using viewmodel objects to interface a UI-agnostic controller to a concrete kind of a UI. 我还利用属性系统以通用的方式公开与UI相关的属性,通常使用viewmodel对象将与UI无关的控制器与特定类型的UI接口。

In your case, I'd suggest that neither MainWindow know of Computations , nor vice versa: 在您的情况下,建议不要让MainWindow知道Computations ,反之亦然:

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  Computations comp;
  MainWindow ui;
  QObject::connect(&comp, ..., &ui, ...);
  /* more connections here */
  ui.show();
  return app.exec();
}

For more concrete examples, see answer #1 or answer #2 . 有关更多具体示例,请参见答案1答案2

This is another version how to use, I think can be easier to understand for beginners 这是另一个版本的用法,我认为对于初学者来说可以更容易理解

You need define signal and slots in your classes. 您需要在类中定义信号和插槽。 Add to header of your class, for example signals to MainWindow, slots to Computations 添加到类的标题中,例如,发送给MainWindow的信号,发送给Computations的插槽

public slots:
    void something();

signals:
    void something_happend();

Then, in anywhere, where you want use it, in your example in mainwindow.cpp , you need to connect signal and slot. 然后,在任何要使用它的地方,在mainwindow.cpp的示例中,您都需要连接信号和插槽。 Do this by QObject::connect : 通过QObject :: connect做到这一点:

QObject::connect(who_emit,SIGNAL(what_signal),who_receive,SLOT(what_slot))

Example: 例:

mainwindow.h 主窗口

signals:
    void something_happend();

computations.h 计算.h

public slots:
    void something_happend();

mainwindow.cpp 主窗口

Computations *c = new Computations(this);
QObject::connect(this,SIGNAL(something_happend()),c,SLOT(something()));

If you want to pass some arguments, SIGNAL and SLOT that you want to connect need have same types of arguments: 如果要传递一些参数,则要连接的SIGNAL和SLOT需要具有相同类型的参数:

public slots:
    void something(int c);

signals:
    void something_happend(int c);

QObject::connect(this,SIGNAL(something_happend(int)),c,SLOT(something(int)));

you need slots and signals because those work together, like this: your file.h你需要插槽和信号,因为它们一起工作,就像这样:你的 file.h

public slots:
    void start();

signals:
    void levelChanged(int level);

implementing:实施:

void MainBoard::start()
{
    isStarted = true;
    clearBoard();
    emit levelChanged(1);

}

now you need to link a button现在你需要链接一个按钮

startButton = new QPushButton(tr("&Start"));
startButton->setFocusPolicy(Qt::NoFocus);

connect(startButton, &QPushButton::clicked, board, &MainBoard::start);

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

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