Как я могу изменить синхронизацию для сигналов и слотов в QT?

#c #qt #signals

#c #qt #сигналы

Вопрос:

Я создаю программу, которая управляет информацией об учениках. В настоящее время у меня есть tableview и у меня есть кнопка добавить, когда я нажимаю на кнопку добавить, появляется новое диалоговое окно, предлагающее пользователям добавить нового ученика. Я намереваюсь создать соединение сигнала и слота с моим диалоговым окном, чтобы при каждом нажатии кнопки ok мой tableview обновлялся (я использую SQLITE). Однако проблема прямо сейчас заключается в том, что мне кажется, что база данных обновляется после того, как я вызываю свою функцию refreshwindow, поэтому, когда я вызываю свою функцию refreshwindow, база данных еще не была обновлена. Я не уверен, что это проблема, но это то, что я думаю.

Ниже приведены некоторые коды: Когда я нажимаю на кнопку добавить

 void viewStudents::on_addStudent_clicked()
{
    studentWindow = new studentManagement(username,this);
    QObject::connect(studentWindow,SIGNAL(accepted()),this, SLOT(refreshwindow()));
    studentWindow->show();
}
  

моя функция обновления окна

 void viewStudents::refreshwindow()
{
    QSqlQueryModel *modal = new QSqlQueryModel();
    QSqlDatabase tempdb = QSqlDatabase::addDatabase("QSQLITE");
    tempdb.setDatabaseName("accounts.db");
    if(tempdb.open()){
        QSqlQuery tempquery;
        tempquery.exec("SELECT firstname, lastname, DOB, Day_of_lessons, Start_date, Price_per_lesson, Length_of_lessons from studentList WHERE teacher = '" username "';");
        modal->setQuery(tempquery);
        ui->tableView->setModel(modal);
        ui->tableView->resizeColumnsToContents();
        ui->tableView->resizeRowsToContents();
        tempdb.close();
    }
    else{
        QMessageBox::warning(this,"Error","Something unexpected has happened.");
    }
}
  

мой диалог для добавления студентов

 studentManagement::studentManagement(QString username, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::studentManagement)
{
    this->username = username;
    ui->setupUi(this);
    QFont information_font = ui->informationLabel->font();
    information_font.setPointSize(14);
    information_font.setBold(true);
    ui->informationLabel->setFont(information_font);
    ui->startdate->setMinimumDate(QDate::currentDate());
    ui->dayOfLessonsBox->addItem("Monday");
    ui->dayOfLessonsBox->addItem("Tuesday");
    ui->dayOfLessonsBox->addItem("Wednesday");
    ui->dayOfLessonsBox->addItem("Thursday");
    ui->dayOfLessonsBox->addItem("Friday");
    ui->dayOfLessonsBox->addItem("Saturday");
    ui->dayOfLessonsBox->addItem("Sunday");
}

studentManagement::~studentManagement()
{
    delete ui;
}

void studentManagement::on_buttonBox_accepted()
{
    QString firstname = ui->firstname->text();
    QString lastname = ui->lastname->text();
    QString DOB = ui->dateofbirth->text();
    QString dayOfLessons = ui->dayOfLessonsBox->currentText();
    QString startdate = ui->startdate->text();
    QString pricing = ui->pricing->text();
    QString lengthoflessons = ui->lengthoflessons->text();
    QSqlDatabase mydb = QSqlDatabase::addDatabase("QSQLITE");
    mydb.setDatabaseName("accounts.db");
    if(!mydb.open())QMessageBox::warning(this,"File Not Found Error", "The database file cannot be find.");
    else{
        QSqlQuery query;
        if(query.exec("INSERT INTO studentList VALUES('" firstname "', '" lastname "', '" DOB "', '" dayOfLessons "', '" startdate "', '" pricing "', '" lengthoflessons "', '" username "');")){
            mydb.close();
        }
    }
}
  

Если бы кто-нибудь мог мне немного помочь или дать мне несколько советов о том, где искать, я был бы очень признателен!

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

1. Вам нужно поместить connect в свой конструктор и полностью исключить вашу первую функцию. Поместите refresh и show в конец on_buttonBox_accepted . Я публикую ответ, если вы не можете его понять.

2. О, вам нужно изменить параметры подключения. Подключите сигнал нажатия кнопки к слоту on_buttonBox_accepted (сделайте его общедоступным слотом: в заголовке, если это не так)

3. @Iman Большое вам спасибо! Это имеет большой смысл! Если возможно, не могли бы вы опубликовать ответ, у меня возникли небольшие проблемы с соединительной частью. Я действительно ценю это!

4. Прочитайте о синтаксисе проверяемого соединения во время компиляции wiki.qt.io/New_Signal_Slot_Syntax

5. @Jonny 21099 извините за задержку, я был в процессе переезда на новое место. Я смиренно предлагаю ознакомиться с документацией Qt и их официальными видеороликами на YouTube. Удачи.

Ответ №1:

Прежде всего, вы должны были использовать свой connect оператор в конструкторах, иначе при каждом on_addStudent_clicked() вызове будет выполняться новое соединение, которое не формулирует ошибку, но это совершенно не нужно.

Во-вторых, когда мы добавляем запись в список, мы хотим убедиться, что список обновляется сразу, поэтому это должно быть сразу после insert инструкции.

В-третьих, Qt очень умен, чтобы находить неявные соединения, которые вы хотите создать, если вы создаете функцию с общей формой on_something_someevent() , тогда она автоматически будет искать объект / класс (типа QObject ) с именем something и подключает его сигнал, который находится someevent в this и on_something_someevent() как слот. В результате написание функции, подобной thisobject::on_something_someevent(){} будет автоматически отображаться в :

  QObject::connect(something, SIGNAL(someevent()), this, SLOT(on_something_someevent()));
  

что очень удобно, но может попытаться создать нежелательное connect или, по крайней мере, вызвать предупреждение или ошибку.

Наконец, не забудьте определить свой слот с public slot: помощью в вашем заголовочном файле. Необходима общедоступная часть, иначе вы получите ошибку нарушения доступа, поскольку Qt framework не может вызвать вашу функцию slot (из другого объекта).

Вот исправленная форма вашего кода, которая, я думаю, могла бы выполнить эту работу (у меня не было ваших файлов .ui или .h, ни полного источника ваших обоих классов, ни вашей main() функции, поэтому, пожалуйста, рассматривайте это как частичный источник, который, я надеюсь, передает суть)

 void viewStudents::refreshwindow()
{
    QSqlQueryModel modal = QSqlQueryModel::QSqlQueryModel();
    QSqlDatabase tempdb = QSqlDatabase::addDatabase("QSQLITE");
    tempdb.setDatabaseName("accounts.db");
    if (tempdb.open()) {
        QSqlQuery tempquery;
        tempquery.exec("SELECT firstname, lastname, DOB, Day_of_lessons, Start_date, Price_per_lesson, Length_of_lessons from studentList WHERE teacher = '"   username   "';");
        modal->setQuery(tempquery);
        ui->tableView->setModel(modal);
        ui->tableView->resizeColumnsToContents();
        ui->tableView->resizeRowsToContents();
        tempdb.close();
    }
    else {
        QMessageBox::warning(this, "Error", "Something unexpected has happened.");
    }
}

studentManagement::studentManagement(QString username, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::studentManagement)
{
    this->username = username;
    ui->setupUi(this);
    QFont information_font = ui->informationLabel->font();
    information_font.setPointSize(14);
    information_font.setBold(true);
    ui->informationLabel->setFont(information_font);
    ui->startdate->setMinimumDate(QDate::currentDate());
    ui->dayOfLessonsBox->addItem("Monday");
    ui->dayOfLessonsBox->addItem("Tuesday");
    ui->dayOfLessonsBox->addItem("Wednesday");
    ui->dayOfLessonsBox->addItem("Thursday");
    ui->dayOfLessonsBox->addItem("Friday");
    ui->dayOfLessonsBox->addItem("Saturday");
    ui->dayOfLessonsBox->addItem("Sunday");

    // This connect statment could be quit unnecessary as Qt will create it automatically
    // Since you have created the function name as it is expected by Qt (on_class_event)    
    QObject::connect(addStudent, SIGNAL(clicked()), this, SLOT(on_addStudent_clicked()));
}

studentManagement::~studentManagement()
{
    delete ui;
}

void studentManagement::on_addStudent_clicked()
{
    QString firstname = ui->firstname->text();
    QString lastname = ui->lastname->text();
    QString DOB = ui->dateofbirth->text();
    QString dayOfLessons = ui->dayOfLessonsBox->currentText();
    QString startdate = ui->startdate->text();
    QString pricing = ui->pricing->text();
    QString lengthoflessons = ui->lengthoflessons->text();
    QSqlDatabase mydb = QSqlDatabase::addDatabase("QSQLITE");
    mydb.setDatabaseName("accounts.db");
    if (!mydb.open()) 
    {
        QMessageBox::warning(this, "File Not Found Error", "The database file cannot be find.");
    }
    else 
    {
        QSqlQuery query;
        if (query.exec("INSERT INTO studentList VALUES('"   firstname   "', '"   lastname   "', '"   DOB   "', '"   dayOfLessons   "', '"   startdate   "', '"   pricing   "', '"   lengthoflessons   "', '"   username   "');"))
            mydb.close();       
    }
    studentWindow = new studentManagement(username, this);
    studentWindow->show();

    viewStudents::refreshwindow();
    // OR
    // define refreshwindow as a public slot and emit a signal from here
    emit(viewStudents::refreshwindow());
}