const QObject * receiver, const char * member);
Просто передайте объект, владеющий сигналом (отправитель), функцию сигнала, объект, владеющий слотом (приемником), и в завершение укажите имя слота.
В примере MyWindow, если бы вы захотели связать сигнал clicked
виджета QPushButton
с вашим слотом doSomething
, вы бы написали:
connect(button, SIGNAL(clicked()), this, SLOT(doSomething()));
Учтите, что необходимо применять макросы SIGNAL
и SLOT
для выделения функций сигналов и слотов. Как и в комплекте GTK+, вы можете связать ряд слотов с заданным сигналом и также связать слот с любым количеством сигналов с помощью множественных вызовов функции connect. Если она завершается аварийно, то возвращает FALSE
.
Остается реализовать ваш слот в виде обычной функции-метода:
void MyWindow::doSomething() {
// Код слота
}
Выполните упражнение 17.2.
Упражнение 17.2. Сигналы и слоты
Теперь, зная основы использования сигналов и слотов, применим их в примере. Усовершенствуйте QMainWindow
, вставьте в него кнопку и свяжите сигнал кнопки clicked
со слотом.
1. Введите следующее объявление класса и назовите файл ButtonWindow.h:
#include
class ButtonWindow : public QMainWindow {
Q_OBJECT
public:
ButtonWindow(QWidget *parent = 0, const char *name = 0);
virtual ~ButtonWindow();
private slots:
void Clicked();
};
2. Далее следует реализация класса в файле ButtonWindow.cpp:
#include "ButtonWindow.moc"
#include
#include
#include
3. В конструкторе вы задаете заголовок окна, создаете кнопку и связываете сигнал нажатия кнопки с вашим слотом. setCaption
— метод объектов типа QMainWindow
, который, что неудивительно, задает заголовок окна:
ButtonWindow::ButtonWindow(QWidget *parent, const char* name) : QMainWindow(parent, name) {
this->setCaption("This is the window Title");
QPushButton *button = new QPushButton("Click Me!", this, "Button1");
button->setGeometry(50, 30, 70, 20);
connect(button, SIGNAL(clicked()), this, SLOT(Clicked()));
}
4. Qt автоматически удаляет виджеты, поэтому ваш деструктор пуст:
ButtonWindow::~ButtonWindow() {}
5. Затем реализация слота:
void ButtonWindow::Clicked(void) {
std::cout << "clicked!\n";
}
6. И наконец, в функции main
вы просто создаете экземпляр типа ButtonWindow
, делаете его главным окном вашего приложения и отображаете окно на экране:
int main(int argc, char **argv) {
QApplication app(argc, argv);
ButtonWindow *window = new ButtonWindow();
app.setMainWidget(window);
window->show();
return app.exec();
}
7. Прежде чем вы сможете откомпилировать данный пример, необходимо запустить препроцессор для заголовочного файла. Программа этого препроцессора называется Meta Object Compiler (moc, компилятор метаобъекта) и должна быть включена в пакет комплекта Qt. Выполните moc
для файла ButtonWindow.h, сохранив результат в файле ButtonWindow.moc:
$ moc ButtonWindow.h -о ButtonWindow.moc
Теперь можно компилировать как обычно, скомпоновав с результатом команды moc
.
$ g++ -о button ButtonWindow.срр -I$QTDIR/include -L$QTDIR/lib -lqui
Выполнив программу, вы получите пример, показанный на рис. 17.3.
Рис. 17.3
Как это работает
В этом примере мы ввели новый виджет и некоторые новые функции, поэтому давайте их рассмотрим. QPushButton
— виджет простой кнопки, хранящий метку и растровую графику и способный активизироваться при щелчке пользователя кнопкой мыши или при нажатии клавиш.
Конструктор объекта QPushButton
очень прост.
QPushButton::QPushButton(const QString &text, QWidget *parent,
const char* name=0);
Первый аргумент — текст метки кнопки, далее родительский виджет и последний аргумент — имя кнопки, обычно применяемое Qt для внутренних операций.
Параметр родительского виджета, общий для всех объектов, — QWidget
, он управляет отображением и уничтожением и разными другими свойствами. Передача NULL
в качестве родительского объекта означает виджет верхнего уровня, при этом создается содержащее его пустое окно. В примере вы передаете текущий объект ButtonWindow
с помощью ключевого слова this
, что приводит к вставке кнопки в основную область окна ButtonWindow
.
Аргумент name
задает имя виджета для внутреннего использования Qt. Если комплект Qt обнаружит ошибку, имя виджета будет выведено в сообщении об ошибке, поэтому неплохо выбирать подходящие имена виджетов, поскольку при отладке это сбережет массу времени.
Читать дальше