QWidget через слот

Я пытаюсь создать функцию, которая будет отображать виджет в зависимости от переданного ему QWidget.

У меня есть:

position_widget = new positionWidget();
timing_widget = new timingWidget();
...

void MainWindow::showScreen(QWidget *w)
{
    ui->screenWidget->layout()->addWidget(w);
    w->show();
}


void MainWindow::doConnects()
{
QObject::connect(buttons_widget, SIGNAL(showPositionScreen_signal()), this, SLOT(showScreen(position_screen)));
QObject::connect(buttons_widget, SIGNAL(showTimingScreen_signal()), this, SLOT(showScreen(timing_screen)));
}

Ничего не происходит, когда я нажимаю кнопку, и появляется сообщение «Нет такого слота MainWindow::ShowScreen(timing_screen)».


person easty    schedule 02.06.2016    source источник
comment
Вместо этого должно быть SLOT(showScreen(QWidget *))   -  person vahancho    schedule 02.06.2016
comment
Используйте автозаполнение Qt Creator для завершения сигналов и слотов, особенно с соединениями в стиле ole (с использованием макросов SIGNAL и SLOT). Предпочитайте соединения нового стиля, где вы получите ошибку компиляции, если ошиблись.   -  person hyde    schedule 02.06.2016
comment
@thuga, использующий значение, а не тип для макроса слота, аналогичен вопросу, который вы указали, но также есть проблема с несоответствием аргументов в его сигналах и слотах.   -  person tobilocker    schedule 02.06.2016
comment
@tobilocker В обоих вопросах несоответствие параметров.   -  person thuga    schedule 02.06.2016
comment
@thuga В обоих случаях сигнал испускается без каких-либо аргументов, и кто-то пытается подключиться к слоту со значением в сигнальном макросе. Вы правы. Но я вижу разницу: в этом случае пользователь хочет испускать собственный сигнал, когда в другом вопросе пользователь хочет использовать сигнал QAbstractButton clicked() (для которого я на самом деле не вижу никакого варианта использования)   -  person tobilocker    schedule 02.06.2016


Ответы (1)


Если showScreen объявлен как Qt Slot в вашем mainwindow.h например:

private slots:
    void showScreen(QWidget* w);

И ваши Сигналы объявлены в buttons_widget

signals:
    void showPositionScreen_signal(QWidget* w); //Note that signal needs same type as slot
    void showTimingScreen_signal(QWidget* w);

Затем вы можете подключить этот сигнал к слоту. Обратите внимание, что аргументы сигналов и слотов должны совпадать. То есть: "Механизм сигналов и слотов типобезопасен: подпись сигнала должна соответствовать сигнатуре принимающего слота. (На самом деле слот может иметь более короткую сигнатуру, чем сигнал, который он получает, потому что он может игнорировать дополнительные аргументы.)"

connect(buttons_widget, SIGNAL(showPositionScreen_signal(QWidget*)), this, SLOT(showScreen(QWidget*)));

И вам придется излучать position_screen и timing_screen изнутри buttons_widget, например:

emit showPositionScreen_signal(position_screen);

Как указал thuga, это означает, что вам НЕ нужны два разных сигнала. Чтобы передать еще один QWidget в тот же слот, просто издайте этот сигнал вместе с ним. То есть:

emit showPositionScreen_signal(timing_screen);

И я бы предложил тогда изменить название вашего сигнала на что-то подходящее.

person tobilocker    schedule 02.06.2016
comment
Зачем использовать два сигнала, которые делают одно и то же? Одного будет достаточно, если вы передадите виджет в качестве аргумента. - person thuga; 02.06.2016
comment
@thuga Это правда, хороший момент. Вышеупомянутое будет работать, я укажу на это в своем ответе... Спасибо - person tobilocker; 02.06.2016
comment
Это здорово, большое спасибо - person easty; 02.06.2016