Не срабатывает слот в Qt

117
29 ноября 2020, 15:30

У меня есть функция, которая вызывает слот:

void notesWindow::notNotes(QGridLayout *notesLay)
{
    QLabel *notNotesLbl = new QLabel("Заметок еще нет. Добавьте свою первую заметку.");
    notNotesLbl->setAlignment(AlignCenter);
    QPushButton *addNoteBut = new QPushButton("Добавить заметку");
    notesLay->addWidget(notNotesLbl, 0, 0);
    notesLay->addWidget(addNoteBut, 1, 0);
    connect(addNoteBut, SIGNAL(clicked()), this, SLOT(addNotes()));
}

По сути должен сработать вот этот слот:

void notesWindow::addNotes()
{
    QMessageBox* pmbx = new QMessageBox("MessageBox",
                        "<b>A</b> <i>Simple</i>   <u>Message</u>",
                        QMessageBox::Information,
                        QMessageBox::Yes,
                        QMessageBox::No,
                        QMessageBox::Cancel | QMessageBox::Escape);
}

Но он не срабатывает .h файл:

using namespace std;
using namespace Qt;
class notesWindow : public QWidget
{
    Q_OBJECT
public:
    notesWindow(QWidget *parent = 0);
    void showMainTopBar(QHBoxLayout *topBarLay);
    void notNotes(QGridLayout *notesLay);
    void readNotesFile(char *fileName);
private:
    int amountNotes = 0;
    char fileName[10] = "notes.txt";
public slots:
    void addNotes();
};
Answer 1
  1. Убедитесь, что функция, использующая Ваш слот, вызывается в программе хоть раз. По этой причине имеет смысл прописывать все соединения в конструкторе - так будет обеспечена гарантия того, что соединение было осуществлено. (Разумеется, для этого Вы должны создать объект этого класса в теле main() ).
  2. В случае, если слот содержится в классе, из которого производится соединение, то можно воспользоваться сокращенной формой метода connect (), опустив третий параметр (pReceiver), указывающий на объект-получатель. Другими словами, если в качестве объекта-получателя должен стоять указатель this, его можно просто не указывать:

MyClass::MyClass() { connect(pSender, SIGNAL(signalMethod()), SLOT(slot())); }

  1. Также существует альтернативный вариант метода connect(), преимущество которого заключается в том, что все ошибки соединения сигналов со слотами выявляются на этапе компиляции программы, а не при ее исполнении, как это происходит в классическом варианте метода connect(). Прототип альтернативного метода выглядит так: QObject::connect(const QObject* sender, const QMetaMethod& signal, const QObject* receiver, const QMetaMethod& slot, Qt::ConnectionType type = Qt::AutoConnection ); Вот так выглядит аналогичное соединение при помощи альтернативного метода connect():

    QObject::connect(pSender, &SenderClass::signalMethod, pReceiver, &ReceiverClass::slotMethod );

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

Answer 2

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

void notesWindow::addNotes()
{
    QMessageBox* pmbx = new QMessageBox("MessageBox",
                    "<b>A</b> <i>Simple</i>   <u>Message</u>",
                    QMessageBox::Information,
                    QMessageBox::Yes,
                    QMessageBox::No,
                    QMessageBox::Cancel | QMessageBox::Escape);
}

Этот код не будет показывать QMessageBox, для того чтоб что-то было показано, необходимо добавить вызов exec, и не забыть удалить ненужный указатель.

void MainWindow::on_pushButton_clicked()
{
    QMessageBox* pmbx = new QMessageBox("MessageBox",
                            "<b>A</b> <i>Simple</i>   <u>Message</u>",
                            QMessageBox::Information,
                            QMessageBox::Yes,
                            QMessageBox::No,
                            QMessageBox::Cancel | QMessageBox::Escape);
    pmbx->exec();
    pmbx->deleteLater();
}

А еще лучше вообще отказаться от динамического создания объекта, потому что функция exec блокирующая.

void MainWindow::on_pushButton_clicked()
{
    QMessageBox pmbx("MessageBox",
                            "<b>A</b> <i>Simple</i>   <u>Message</u>",
                            QMessageBox::Information,
                            QMessageBox::Yes,
                            QMessageBox::No,
                            QMessageBox::Cancel | QMessageBox::Escape);
    pmbx.exec();
}
READ ALSO
Qt: как проверить query.value на нуль

Qt: как проверить query.value на нуль

Есть объект класса QSqlQuery queryВ query попадает результат некоторого запроса

109
Неполное высвобождение памяти

Неполное высвобождение памяти

Есть задача - реализовать двусвязный список(хранимые значения - целые числа) при помощи структурПри заполнении списка 10^7 значениями память...

131
Расчет стоимости на jquery

Расчет стоимости на jquery

Данный калькулятор рассчитывает цену проката авто в зависимости от сезона, на каждый из 3 сезонов задано 5 разных ценМне нужно усложнить его,...

136
Адаптивность в jquery

Адаптивность в jquery

Например есть такой плагин mmenu, как сделать чтобы он срабатывал только на определенной ширине экрана? подобно медиа запросам в css нашла вот...

97