Связать сигнал и слот с qcheckbox, создать динамически

#c #qt #signals #slot #qcheckbox

#c #qt #сигналы #слот #qcheckbox

Вопрос:

У меня очень специфическая проблема, поэтому я постараюсь быть как можно более ясным.

У меня есть QTabWidget , который содержит QTableWidget , каждая моя строка QTableWidget создается динамически путем чтения файла.

MyTab

Как вы можете видеть, когда я создаю строку, я добавляю a qCheckBox в конце. Теперь моя цель — отправить эту строку QTableWidget на последнюю вкладку моего QtableTab , когда я нажимаю на qCheckBox (и удалить эту строку, когда я снимаю флажок qCheckBox ).

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

 QObject::connect(pCheckBox, SIGNAL(clicked()),  this, SLOT(cliqueCheckBox(monTab,ligne, pCheckBox)));
  

Но это не сработает, у меня ошибка :

 QObject::connect: No such slot supervision::cliqueCheckBox(monTab,ligne, pCheckBox)
  

Но этот слот существует, я объявляю его в своем заголовочном файле и моем cpp следующим образом :

 void supervision::cliqueCheckBox(QTableWidget *monTab, int ligne, QCheckBox *pCheckBox)
  

Хорош ли мой способ обработки для решения этой проблемы? Если да, то как правильно связать сигнал со слотом, а если нет, то как действовать дальше?

Спасибо.

[РЕДАКТИРОВАТЬ]: вот код моей функции, создающей qCheckBox и динамически связывающей ее :

 void supervision::ajouterCheckBox(QTableWidget *monTab, int ligne){
    // Creation de la check box
    QWidget *pWidget = new QWidget(); //Creation du widget contenant la checkbox
    QCheckBox *pCheckBox = new QCheckBox(); // Creation de la checkbox
    QHBoxLayout *pLayout = new QHBoxLayout(pWidget); // Layout pour centrer ma checkbox
    pLayout->addWidget(pCheckBox); // Ajout de la check box au layout
    pLayout->setAlignment(Qt::AlignCenter); //Alignement
    pLayout->setContentsMargins(0,0,0,0);//Supression des bordure
    pWidget->setLayout(pLayout);//Mise en place du layout dans le widget
    monTab->setCellWidget(ligne,5,pWidget);//Mise en place du widget contenant la checkbox dans ça cellule

    //Mise en place de la connection
    QObject::connect(pCheckBox, SIGNAL(clicked()),  this, SLOT(cliqueCheckBox(monTab,ligne, pCheckBox)));
}
  

Комментарии:

1. Что такое supervision ? Пространство имен или класс?

2. Надзор — это класс.

3. И можете ли вы подтвердить, что вы находитесь в функции-члене этого класса при подключении слота?

4. Я добавляю функцию, в которой я делаю это в edit

5. @EvansBelloeil, есть несколько решений. Но сигнатуры подключенного сигнала и слота должны быть подходящими. JBL ответил.

Ответ №1:

Вы подключаетесь SIGNAL(clicked()) к SLOT(cliqueCheckBox(monTab,ligne, pCheckBox) тому, что является недействительным. Аргументы сигнала и слота должны совпадать. Здесь вы не указываете никаких параметров для целевого слота.

Правильная форма :

 QObject::connect(pCheckBox, SIGNAL(clicked()),  this, SLOT(clickedCheckBox()));
  

И clickedCheckBox слот должен иметь доступ к указателям ваших виджетов :

 void myClass::clickedCheckBox()
{
   ...
}
  

Комментарии:

1. Мне нужны параметры, что мне делать?

2. У вас должны быть указатели на ваши виджеты в качестве членов класса. Затем вы можете получить к ним доступ в любом слоте класса.

3. Я добавляю много QCheckBox, поэтому в нем много указателей. Возможно ли создать мой собственный сигнал с 3 параметрами?

4. В этом случае вам может потребоваться QSignalMapper сопоставить сигналы виджетов без параметров с вашим слотом с некоторыми параметрами.

Ответ №2:

На самом деле, у вас проблема в вашем соединении.

Действительно, вы подключаете сигнал с нулевыми параметрами к слоту, который принимает три параметра, и это не сработает.

Когда вы подключаете сигнал к слоту, подписи должны совпадать (или слот должен принимать меньше аргументов), или вы получите ошибку во время выполнения. Действительно, в вашем случае слот ожидает аргументы, которые сигнал не будет отправлять.

Поэтому вы должны найти способ, чтобы ваши подписи совпадали.

РЕДАКТИРОВАТЬ: что касается добавленного вами кода, нет, вы не можете использовать переменные, присутствующие в области видимости, где вы объявляете соединение в качестве параметров. Аргумент Slot может исходить только из связанных сигналов.

Комментарии:

1. Итак, я удаляю эти параметры или добавляю их в свой сигнал (что заставляет меня создавать сигнал ?)?

2. У вас есть несколько вариантов. Вы можете создать слот с 0 параметрами, подключенный к clicked, который находит способ вызвать правильную функцию с правильными аргументами. Вы можете найти справку в документе Qt о ** расширенном отображении сигналов и слотов .

Ответ №3:

Из документации Qt:

Все классы, содержащие сигналы или слоты, должны указывать Q_OBJECT в начале своего объявления. Они также должны быть получены (прямо или косвенно) из QObject.

 class X : public QObject 
{ 
    Q_OBJECT
    ...
};
  

Вы должны объявить слоты в объявлении вашего класса:

 public slots:
    void cliqueCheckBox(QTableWidget *monTab, int ligne, QCheckBox *pCheckBox);
  

Правило о том, включать или нет аргументы в макросы SIGNAL() и SLOT(), если аргументы имеют значения по умолчанию, заключается в том, что сигнатура, переданная макросу SIGNAL(), не должна иметь меньше аргументов, чем сигнатура, переданная макросу SLOT()