Обработка событий в Qt - PullRequest
2 голосов
/ 15 июля 2011

Я новичок в программировании на Qt GUI и пришел из опыта .NET / Winforms в плане разработки GUI.Я использую Qt Creator IDE.

Как я могу обработать событие нажатия кнопки в Qt, чтобы сделать что-то вроде следующего:

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

Кроме того, как мне найти файл конфигурациичто будет заполнять значения во всех моих текстовых полях редактирования строки при открытии?Я программирую это на C ++.

EDIT : я беру консольное приложение, которое написал кто-то другой, и строю GUI вокруг него.Я хочу получить доступ к одной из функций там из события нажатия кнопки.Однако я не могу понять, как сделать так, чтобы функции исходного приложения попадали в область действия GUI, который я создал, когда я пытаюсь использовать СИГНАЛЫ и СЛОТЫ.

Ответы [ 6 ]

15 голосов
/ 15 июля 2011

Простой пример может быть что-то вроде этого. Скажем, у вас есть такой класс, как 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

6 голосов
/ 15 июля 2011

Это немного долго объяснять, но вы подключаете сигнал от кнопки к слоту с помощью функции.

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

Вам действительно нужно прочитать и понять сигналы и слоты перед тем, какпытается написать код

edit: Вы пытаетесь вызывать функции в скомпилированной отдельной запущенной программе?
Вы путаете Qt Signals с сигналами C / Unix?Вы можете запустить отдельное приложение из вашего приложения Qt, получить его PID и затем отправить ему сигнал 'c'.

Или, если у вас есть источник приложения, вы можете включить его код в ваше приложение Qt изатем вызовите любую из функций, просто обернув их обработчиком слота Qt.

1 голос
/ 13 августа 2011

Полагаю, ваша проблема в том, что вы не можете вызвать функцию консольного приложения, поскольку оно не определено как слот. Вот как вы можете это сделать.

Предположим, у вас есть класс консольного приложения, который может выглядеть следующим образом:

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.

Cheers, Jonny

1 голос
/ 11 августа 2011

Кажется, что ваша проблема на самом деле не в программировании на Qt или GUI, а в общей проблеме проектирования. Другие рассказали вам, как получать уведомления при нажатии кнопки - вы должны подключить это уведомление к любому коду, который вы хотите вызвать. Некоторые возможности:

  • Если вам просто нужно вызвать функцию, включите соответствующий заголовочный файл и вызовите его.
  • Если у вас есть объект, для которого вы хотите вызвать метод, вам нужно будет предоставить ссылку на этот объект классу, который получает уведомление.
  • Если ваше консольное приложение представляет собой отдельную программу, вы можете использовать QProcess для запуска и связи с ним.
1 голос
/ 10 августа 2011

Чтобы получить доступ к функциям, определенным в консольном приложении, необходимо включить заголовки (.h / .hpp), которые объявляют эти функции, и связать их реализацию. Если у вас есть исходный код реализаций (.cpp), вам нужно добавить их в исходные файлы для компиляции (они будут скомпилированы в объектные файлы (.o), которые будут связаны в конечном исполняемом файле). Если консольное приложение является интерфейсом к набору функций, определенных в библиотеке (.lib, .a), вам необходимо связать эту библиотеку.

После этого вы можете использовать механизм сигналов / слотов Qt для подключения сигнала «нажатие кнопки» к слоту, вызывающему функцию, которую вы хотите выполнить, как описано в других ответах.

0 голосов
/ 29 июля 2011

Если у вас есть кнопка, созданная в Designer, вы можете использовать слот on_myButton_clicked () в родительском классе виджетов, как в WinForms.

...