Вызов метода из слота QT в методе stati c - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть метод stati c, который показывает список (Items) и возвращает массив выбранного объекта в Items. Я хотел бы добавить флажок для перезагрузки списка по некоторым параметрам. Мы используем QT 3.3.

//// Static
int CMSUI_InputDialog::FittingList(QWidget* parent,
  const CString& Title,
  const CStringArray& Items,
  bool                  IsMultiSelect,
  int                       DefaultItem,
  bool                  OkIsDefault,
    CArray<int, int>& Selecteds)
{

 int ret = 0;
 Selecteds.RemoveAll();

 /// Create grid
 QDialog    dialog(parent, 0, true);
 dialog.setCaption(QString(Title));

 QGridLayout* pLayoutGrid = Init(&dialog, OkIsDefault);

 //Create checkBox
 QCheckBox* pCheckBox = new QCheckBox(&dialog, "m_pApply_Filter");
 pCheckBox->setText("Norm Filter");

 pLayoutGrid->addWidget(pCheckBox, 0, 0);

 QObject::connect(pCheckBox, SIGNAL(stateChanged(int)), &dialog, SLOT(checkboxClicked()));

 /// Create ListBox
 QListBox* pList = new QListBox(&dialog);
 pList->setMinimumSize(QSize(370, 90));

 pList->setSelectionMode(QListBox::Extended);

 // Load the list
 int Count = Items.GetSize();
 for (int i = 0; i < Count; i++)
 {
    QString QS(Items[i]);
    pList->insertItem(QS);
 }

 if (DefaultItem >= 0 && DefaultItem < Count)
    pList->setSelected(DefaultItem, true);

 pLayoutGrid->addWidget(pList, 1, 0);

 // Connect double clic on QDialog accept
 QObject::connect(pList, SIGNAL(doubleClicked(QListBoxItem*)), &dialog, SLOT(accept()));

 if (dialog.exec() == QDialog::Accepted)
 {
    for (int i = 0; i < Count; i++)
    {
        if (pList->isSelected(i))
            Selecteds.Add(i);
    }
    ret = 1;
  }

  return ret;
}

void CMSUI_InputDialog::checkboxClicked()
{
    //To do
}

checkboxClicked () объявлен в CMSUI_InputDialog.h как слот

class CMSUI_InputDialog
{
protected :

    static QGridLayout* Init(QWidget* pParent, bool OkIsDefault);

public slots:
    void checkboxClicked();


public:
    /// CheckBox  + ListBox for fittings
    static int FittingList(QWidget* parent,
        const CString& Title,
        const CStringArray& Items,
        bool                    IsMultiSelect,
        int                     DefaultItem,
        bool                    OkIsDefault,
        CArray<int, int>& Selecteds);
};

Я пробовал много вещей, но я глуп с QT и не сделал удалось поймать действие на флажке

1 Ответ

0 голосов
/ 07 апреля 2020

Здесь есть небольшая спецификация Qt c, что касается основной проблемы: все это понятно в простом C ++, нет необходимости в знании Qt.

  1. Вы не проверяете результат, возвращаемый методом connect: он возвращает false в случае неудачи. connect в вашем случае терпит неудачу, поэтому нет смысла идти дальше. Слот не будет назван. Причина этого: dialog это просто QDialog, а не CMSUI_InputDialog. Вы не можете добавлять слоты в существующий класс Qt.

  2. Слоты должны быть методами в QObject s. Класс, в который вы добавили «слот», не является производным от QObject. Вам нужно создать такой класс (чтобы заменить QDialog, который вы используете).

  3. slots - это пустой макрос (расширяется до нуля) и таким образом, не влияет на сборку. Однако у него есть цель: moc (мета-объектный компилятор), который обрабатывает заголовочный файл, заметит этот макрос и обработает последующие методы как слоты. Это не сработает, если у вас не будет макроса Q_OBJECT в классе .

Сначала вы захотите выделите параметры для этого диалога в структуру FittingOptions, чтобы сделать код управляемым.

struct FittingOptions {
  const CStringArray& items,
  bool                isMultiSelect,
  int                 defaultItem,
  bool                okIsDefault,
};

Диалог должен стать новым классом, в котором ваш слот будет go:

class FittingList : public QDialog {
  Q_OBJECT
  FittingOptions opt;
  CArray<int, int>* selecteds;

public:
  FittingList(QWidget *parent, const FittingOptions &options) :
    QDialog(parent), opt(options), selecteds(0)
  {
    // TODO: initialization code that creates widgets etc.
  }

  void setSelecteds(CArray<int, int> &selecteds)
  {
    this->selecteds = &selecteds;
  }

  // ...

public slots:
  void checkboxChanged() { /* TODO */ }
};

А затем поместите код инициализации из метода FittingList в конструктор. Измените этот метод на:

int CMSUI_InputDialog::FittingList(QWidget* parent,
  const CString& title,
  const CStringArray& items,
  bool                isMultiSelect,
  int                 defaultItem,
  bool                okIsDefault,
  CArray<int, int>&   selecteds)
{
   const FittingOptions options = { 
     items, isMultiSelect, defaultItem, okIsDefault
   };
   ::FittingList dialog(parent, options);
   dialog.setCaption(QString(title));
   dialog.setSelecteds(selecteds);

   if (dialog.exec() != QDialog::Accepted) return 0;
   return 1;
}

Посмотрите другие примеры в вашем проекте, чтобы увидеть, как они справились с такими проблемами. Этот код довольно устарел по сегодняшним стандартам, но, насколько я понимаю, это работа по техническому обслуживанию, поэтому вы должны сделать больше того же самого - поскольку я полагаю, что вы не обновляете версию Qt.

Примечание: это очевидно то, что касается оригинального автора (ов) кода, а не вас. Вы не написали этот материал. Даже во времена Qt 3 этот код считался бы хрустким - кажущееся повсеместным использование глобальных / синглетных кодов достойно кропотливой работы. Я всегда удивляюсь, почему люди, работающие над такими, предположительно, крупномасштабными проектами, не будут изучать код, за который они заплатили и который им доступен: Qt 3 включает полный исходный код для Qt Designer, и именно здесь можно было бы найти вдохновение / обучение , В наши дни Qt Creator является гораздо большей кодовой базой, чем Designer (более чем на порядок), и имеет достаточно приличную архитектуру, поэтому крупномасштабные проекты могут черпать вдохновение.

...