Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: codenameRazuka от Ноябрь 16, 2015, 17:49



Название: Взаимодействие диалогового окна с главным окном
Отправлено: codenameRazuka от Ноябрь 16, 2015, 17:49
В общем, пишу приложение, предоставляющее интерфейс конечному пользователю для взаимодействия с БД. Прежде чем начать что-либо делать с БД, нужно открыть таблицу. Для этого пользователь нажимает соответствующую кнопочку, появляется диалоговое окно, где в виде списка (QListWidget) представлены таблицы, а снизу две кнопки -- "Принять" и "Отмена". Причём кнопка "Принять" не сможет стать активной до того, пока не будет кликнут какой-либо элемент из списка. "Отмена" можно нажать в любом случае. Затем, необходимо информацию  о выборе пользователя передать по нажатии "Принять", и в главном окне соотв. таблицу открыть, т.е. выполнить SQL-запрос, в который подставить имя элемента из списка.
Вопрос: каким образом следует обеспечить передачу строки-имени элемента от диалогового окна главному окну?

Заранее извиняюсь за свой говнокод.

Класс диалогового окна:

Код:
class ChooseTableDialog: public QDialog
{
    Q_OBJECT

private:
    QListWidget *list;
    QPushButton *admitButton;
    QPushButton *cancelButton;

public:
    ChooseTableDialog(QWidget* parrent = 0);

private slots:
    void EnableAdmitButton();

};

void ChooseTableDialog::EnableAdmitButton()
{
    admitButton->setEnabled(true);
}

ChooseTableDialog::ChooseTableDialog(QWidget *parrent) : QDialog(parrent)
{
    list = new QListWidget(this);
    admitButton = new QPushButton(QObject::tr("Принять"),this);
    cancelButton = new QPushButton(QObject::tr("Отмена"),this);

    admitButton->setEnabled(false);

    QObject::connect(admitButton, SIGNAL(clicked()), this, SLOT(close()));
    QObject::connect(list, SIGNAL(itemClicked(QListWidgetItem*), this, SLOT(EnableAdmitButton()));
    QObject::connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));

    QString *tablesString = new QString[6];
    tablesString[0]="Пользователи";
    tablesString[1]="Группы";
    tablesString[2]="Форумы";
    tablesString[3]="Секции";
    tablesString[4]="Темы";
    tablesString[5]="Сообщения";

    QListWidgetItem **listWidgetItems = new QListWidgetItem*[6];

    for (int i = 0; i < 6; i++)
    {
        listWidgetItems[i]=new QListWidgetItem(QObject::tr(tables[i]),list);
    }

    for (int i = 0; i < 6; i++)
    {
        list->addItem(listWidgetItems[i]);
    }

    QVBoxLayout *mainLayout = new QVBoxLayout;

    QHBoxLayout *bottomLayout = new QHBoxLayout;
    bottomLayout->addWidget(admitButton);
    bottomLayout->addWidget(cancelButton);

    mainLayout->addWidget(list);
    mainLayout->addLayout(bottomLayout);
}


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


Код:
class Ui: QWidget
{
public:
    Ui();
    ~Ui();

private:
    QSqlTableModel *table;

    QPushButton *insertButton;
    QPushButton *deleteButton;
    QPushButton *updateButton;
    QPushButton *chooseTableButton;


private slots:
    void insertRecord();
    void deleteRecord();
    void updateRecord();
    void chooseTable();

};



Название: Re: Взаимодействие диалогового окна с главным окном
Отправлено: __Heaven__ от Ноябрь 17, 2015, 11:52
Можно сигналами userChanged(int), userChanged(QString).
А можно написать метод для диалога типа getSelectedUserName()


Название: Re: Взаимодействие диалогового окна с главным окном
Отправлено: codenameRazuka от Ноябрь 17, 2015, 15:30
Добавил такой слот:
Код:
void ChooseTableDialog::PassTableName()
{
    int n = list->count();
    QString str;
    for (i=0; i < n; i++)
    {
        if  (list->item(i)->isSelected())
        {
            str = list->item(i)->text();
            break;
        }
    }
    emit TableChosen(str);
}

В конструкторе связал слот с соотв. сигналом:

Код:
connect(admitButton, SIGNAL(clicked()), this, SLOT(PassTableName()));

Теперь мне необходимо в главном окне реализовать слот, принимающий испускаемый сигнал, правильно?

И ещё. Кто знает, при однократном нажатии на элемент списка, значение поля данного элемента, к-рое проверяет метод isSelected(), устанавливается на true, или следует каким-либо образом его вручную установить, т.е. через setSelected()?


Название: Re: Взаимодействие диалогового окна с главным окном
Отправлено: __Heaven__ от Ноябрь 18, 2015, 10:36
Смотрите, создайте в классе диалога сигналы
userChanged(int userID) и userChanged(QString userName)
В конструкторе класса присоедините их к сигналам списка
Код
C++ (Qt)
connect(list, SIGNAL(currentRowChanged(int)), SIGNAL(userChanged(int)));
connect(list, SIGNAL(currentRowChanged(QString)), SIGNAL(userChanged(QString)));
Таким образом у нас диалог испускает сигналы о смене пользователя.
Теперь наша задача в главном окне перехватить эти сигналы. Для этого создаём слот setUser(...) в качестве аргументов может быть int или QString
Код
C++ (Qt)
void ChooseTableDialog::setUser(const QString& userName){
   // your code
}
А в конструкторе главного окна прикручиваем его к нашему сигналу
Код
C++ (Qt)
connect(dialog, SIGNAL(userChanged(QString)), SLOT(setUser(QString)))
Теперь при клике на каком-либо пользователе главное окно оповещается об этом.
Только в вашем коде не видно, как вызывается сам диалог...
Еще хочу добавить, что статический метод tr() можно использовать без указания QObject::, если класс является наследником QObject.
Код
C++ (Qt)
admitButton = new QPushButton(tr("Принять"),this);
cancelButton = new QPushButton(tr("Отмена"),this);
Также tr не станет работать с не константами
Цитировать
Код
C++ (Qt)
tr(tables[i])