【问题标题】:Event Handling in QtQt 中的事件处理
【发布时间】:2015-12-09 15:26:51
【问题描述】:

我是 Qt GUI 编程的新手,并且在 GUI 开发方面具有 .NET/Winforms 背景。我正在使用 Qt Creator IDE。

如何处理 Qt 中的按钮按下事件以执行以下操作:

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

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

编辑:我正在使用其他人编写的控制台应用程序并围绕它构建一个 GUI。我想从按钮单击事件中访问其中的一个功能。但是,当我尝试使用 SIGNALS 和 SLOTS 时,我无法弄清楚如何让原始应用程序的功能在我创建的 GUI 范围内。

【问题讨论】:

标签: c++ qt user-interface button event-handling


【解决方案1】:

一个简单的例子可能是这样的。假设你有一个像 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() 信号连接到 startProgram() 插槽时,按钮会发出 clicked() 信号。所以当按钮被按下时,startProgram() 会被调用。

Qt 有一个元对象系统,可以使用信号和槽等。这就是 ProgramStarter 继承 QObject 以及 Q_OBJECT 宏在 header 中的原因。如果你想了解 Qt 中信号和槽以及元对象系统是如何工作的,我强烈建议你阅读这篇文章:http://doc.qt.io/qt-5/signalsandslots.html

【讨论】:

  • 感谢您的回复,但是我似乎无法从我的 GUI 访问我需要的任何功能。请查看我在原始问题中添加的其他详细信息。
【解决方案2】:

解释有点长,但是您将按钮的信号连接到具有功能的插槽。

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

在尝试编写代码之前,您确实需要阅读并理解 signals and slots

编辑:您正在尝试在已编译的单独运行程序中调用函数?
您是否将 Qt 信号与 C/Unix 信号混淆了?您可以从 Qt 应用程序中启动单独的应用程序,获取其 PID,然后向其发送“c”信号。

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

【讨论】:

  • 我已经尝试过这种方法,但是我似乎无法访问想要在单击按钮时触发的功能。我在原始问题中添加了更多详细信息。
【解决方案3】:

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

之后,您可以使用 Qt 的信号/槽机制将“按钮单击”信号连接到调用您要执行的函数的槽,如其他答案中所述。

【讨论】:

    【解决方案4】:

    您的问题似乎根本与 Qt 或 GUI 编程无关,而是一般设计问题。其他人已经告诉您如何在按下按钮时收到通知 - 您可以将通知与您想要调用的任何代码挂钩。一些可能性:

    • 如果您只需要调用一个函数,请包含相应的头文件并调用它。
    • 如果您有一个要调用其方法的对象,则需要将该对象的引用提供给接收通知的类。
    • 如果您的控制台应用程序是一个单独的程序,您可以使用 QProcess 来启动它并与之通信。

    【讨论】:

      【解决方案5】:

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

      假设您有一个可能如下所示的控制台应用程序类:

      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 Designer,但我希望这个示例可以帮助您理解信号和插槽在 Qt 中的工作原理。

      干杯, 强尼

      【讨论】:

        【解决方案6】:

        如果您有使用 Designer 创建的按钮,则可以在父窗口小部件类中使用 on_myButton_clicked() 槽,就像在 WinForms 中一样。

        【讨论】:

          猜你喜欢
          • 2014-09-29
          • 2012-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-08
          • 2017-02-04
          • 1970-01-01
          相关资源
          最近更新 更多