Qt中的事件处理

Event Handling in Qt

本文关键字:事件处理 Qt      更新时间:2023-10-16

我是Qt GUI编程的新手,并且在GUI开发方面来自。net/winforms背景。我正在使用Qt Creator IDE。

我如何在Qt中处理按钮按下事件来做以下事情:

if (button.clicked = true)
{
    startProgram();
}

另外,我如何浏览一个配置文件,它将填充值到我所有的行编辑文本框打开时?我正在用c++编程。

EDIT:我正在使用别人编写的控制台应用程序并围绕它构建GUI。我想从一个按钮点击事件中访问其中一个函数。然而,我无法弄清楚如何让原始应用程序的功能在我尝试使用信号和插槽时创建的GUI范围内。

一个简单的例子是这样的:假设你有一个像ProgramStarter这样的类:

#include <QObject>
class ProgramStarter : public QObject {
    Q_OBJECT
public slots:
    void startProgram() {
        //Do stuff
    }
};

和类似这样使用ProgramStarter的地方:

#include <QtGui/QApplication>
#include <QPushButton>
#include <QObject>
#include "programstarter.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QPushButton *testButton = new QPushButton("Push me");
    testButton->resize(100, 40);
    testButton->show();
    ProgramStarter *program = new ProgramStarter;
    QObject::connect(testButton, SIGNAL(clicked()), program, SLOT(startProgram()));
    return app.exec();
}
Qt使用信号和插槽在对象之间进行通信。核心思想是当事件发生时发出信号,这些信号可以连接到插槽。在这种情况下,当按钮被按下时,按钮发出一个clicked()信号,并且clicked()信号连接到startProgram()槽。因此,当按钮被按下时,startProgram()被调用。 Qt有一个元对象系统,可以使用信号和插槽等。这就是为什么ProgramStarter继承QObject和Q_OBJECT宏在头文件中的原因。如果您想了解信号和插槽以及元对象系统在Qt中的工作方式,我强烈建议您阅读本文:http://doc.qt.io/qt-5/signalsandslots.html

解释起来有点长,但是你可以把信号从按钮连接到有功能的插槽。

 connect(button, SIGNAL(triggered()), this, SLOT(doSomething()));

在写代码之前,你真的需要阅读和理解信号和插槽

编辑:你试图在一个编译的单独运行的程序中调用函数?
您是否将Qt信号与C/Unix信号混淆?你可以从Qt应用程序中启动单独的应用程序,获取它的PID,然后向它发送一个'c'信号。

或者如果你有应用程序的源代码,你可以将它的代码包含到你的Qt应用程序中,然后通过简单地用Qt插槽处理程序包装它们来调用任何函数。

为了访问控制台应用程序中定义的函数,您需要包含声明这些函数的头文件(.h/.hpp),并链接它们的实现。如果您有实现的源代码(.cpp),则需要将它们添加到要编译的源代码中(它们将在最终可执行文件中链接的目标文件(.o)中编译)。如果控制台应用程序是库中定义的一组函数的前端。Lib, .a),你需要链接这个库。

之后,您可以使用Qt的信号/插槽机制将"button clicked"信号连接到调用您想要执行的函数的插槽,如其他答案所述。

看起来你的问题并不是真正与Qt或GUI编程有关,而是一般的设计问题。其他人已经告诉过您如何在按钮被按下时获得通知-这取决于您将通知与您想要调用的任何代码挂钩。一些可能性:

  • 如果你只需要调用一个函数,那么包括适当的头文件并调用它。
  • 如果你有一个对象,你想调用一个方法,那么你需要提供一个对象的引用到接收通知的类。
  • 如果你的控制台应用程序是一个单独的程序,你可以使用QProcess来启动它并与它通信。

我猜你的问题是你不能调用控制台应用程序的功能,因为它没有被定义为插槽。你可以这样做。

让我们假设你有一个控制台应用程序类,它看起来像这样:

class ConsoleApp
{
public:
   void run()
   {
      // Code which you want to trigger by a button in your UI.
   }
}

然后我们实现了一个基于Qt的包装器类,它继承自QObject类,因此能够发送和接收信号。这个类只是提供了一个自定义槽,将执行委托给ConsoleApp类。

class ConsoleAppWrapper : public QObject
{
   Q_OBJECT
public slots:
   void startProgram()
   {
      m_consoleApp.run();
   }
private:
   ConsoleApp m_consoleApp;
}

好的,现在我们想要一个按钮,当按下时,将触发调用'run()'方法。

int main(int argc, const char** argv)
{
   QApplication app(argc, argv);
   // Define wrapper for console app.
   ConsoleAppWrapper wrapper;
   // Define button and connect its 'clicked()' signal
   // to the wrapper's 'startProgram()' slot.
   QPushButton startProgramButton("Start Program");
   connect(&startProgramButton, SIGNAL(clicked()), &wrapper, SLOT(startProgram()));
   // Show the button.
   startProgramButton.setVisible(true);
   // Start Qt's event loop.
   app.exec();
}

这应该给你一个"开始程序"按钮,当按下时,将调用ConsoleApp::run()方法。

虽然这个例子不是基于Qt设计器,但我希望这个例子能帮助你理解Qt中的信号和插槽是如何工作的。

欢呼,乔尼

如果你有一个用设计器创建的按钮,你可以在父小部件类中使用on_myButton_clicked() slot,就像在WinForms中一样。