Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.79/19: Рейтинг темы: голосов - 19, средняя оценка - 4.79
TLSofter
1

Посылка сигнала от кнопки одной формы в слот другой формы

25.10.2012, 00:59. Просмотров 3796. Ответов 4
Метки нет (Все метки)

Доброго времени, форумчане.
Программировать на Qt начал совсем недавно - несколько дней назад. С++ тоже сравнительно недавно начал изучать. Конечно, провалы в обучении есть, но и результаты есть - получилось написать небольшой клиент БД MySQL. Формы делал через Designer. На основной форме (объект MainWindow) реализован функционал просмотра таблицы через QTableWidget, для добавления данных используется форма add.ui (объект add). В форме add реализован функционал добавления данных в таблицу - каждое поле БД заполняется по-отдельности.
Теперь пойду ближе к теме. В mainwindow.cpp В слоте "on_pushButton_clicked()", реализовано обновление таблицы - очистка row'ов и перезапись данных в таблицу с БД. Я вызываю форму "add" через кнопку "добавить данные..." на форме mainwindow, заполняю поля данными и после нажимаю "применить" - вызывается слот "on_pushButtonInsert_clicked()", в котором описан функционал добавления данных в БД. Слот описан в "add.cpp".
Проблема состоит в том, что у меня никак не получается с помощью этой же кнопки вызвать и слот обновления таблицы. Фактически, получается, что я хочу отправить сигнал из одной формы в слот другой формы. Собственно, вопрос: как это правильно реализовать? Так же само не получается вызвать ф-цию sql_db_open() из формы add.cpp, хотя пробовал объявлять публично. Поэтому там пришлось пока продублировать функционал этой функции, а это не есть хорошо... А может просто банальная невнимательность и "протупиль", что я просто недочитал, как вызывать ф-ции, описанные в других файлах.
Вот пример кода:

main.cpp:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "add.h"
#include "mainwindow.h"
#include <QApplication>
#include <QMainWindow>
#include <QtSql>
#include <QMessageBox>
#include <QTableWidget>
#include <QPlainTextEdit>
#include <qsqldatabase.h>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    a.addLibraryPath(a.applicationDirPath() + "/plugins");
    w.show();
    return a.exec();
}

mainwindow.cpp:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "add.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    QTextCodec *codec = QTextCodec::codecForName("UTF8"); 
    QTextCodec::setCodecForTr(codec);
    ui->setupUi(this);
    connect(ui->pushButton_4, SIGNAL(clicked()), this, SLOT(sql_delete_string()));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::on_pushButton_clicked()
{
    sql_db_open();
    QSqlQuery query;
    query.exec("SET NAMES UTF8");
    int ComboParametr = ui->comboBox->currentIndex();
 
    query.prepare("SELECT * FROM test");
    query.exec();
 
    int n = ui->tableWidget->rowCount();
    for(int i = 0; i < n;i++) ui->tableWidget->removeRow(0);
 
    qDebug("QUERY");
    qDebug() << ui->comboBox->currentIndex();
    qDebug() << ui->lineEdit->text();
    while(query.next())
    {
        ui->tableWidget->insertRow(0);
        QString name = query.value(0).toString();  // id 0
        QString name1 = query.value(1).toString(); // 1
        QString name2 = query.value(2).toString(); // 2
        QString name3 = query.value(3).toString(); // 3
        QString name4 = query.value(4).toString(); // 4
        QString name5 = query.value(5).toString(); // 5
        QString name6 = query.value(6).toString(); // 6
        QString name7 = query.value(7).toString(); // 7
        QString namex = name2 + " " + name3 + " " + name4;
        qDebug() << name << name1 << name2 << name3 << name7;
        QTableWidgetItem *twItem = new QTableWidgetItem(name);
        QTableWidgetItem *twItem1 = new QTableWidgetItem(name1);
        QTableWidgetItem *twItem2 = new QTableWidgetItem(namex);
        QTableWidgetItem *twItem3 = new QTableWidgetItem(name5);
        QTableWidgetItem *twItem5 = new QTableWidgetItem(name7);
        QTableWidgetItem *twItem4 = new QTableWidgetItem(name6);
        ui->tableWidget->setShowGrid(true);
        ui->tableWidget->setItem(0,0,twItem);
        ui->tableWidget->setItem(0,1,twItem1);
        //ui->tableWidget->setItem(0,2,twItem2);
        ui->tableWidget->setItem(0,2,twItem2);
        ui->tableWidget->setItem(0,3,twItem3);
        ui->tableWidget->setItem(0,5,twItem5);
        ui->tableWidget->setItem(0,4,twItem4);
        ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
        ui->tableWidget->verticalHeader()->setResizeMode(QHeaderView::Fixed);
        ui->tableWidget->resizeColumnsToContents();
    }
}
 
void MainWindow::on_pushButton_2_clicked() // слот кнопки "добавить данные"
{
    add *frm = new add;
    frm->show();
}
 
void MainWindow::sql_db_open()
{
    QSqlDatabase db  = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("example.com");              //
    db.setDatabaseName("cat");
    db.setUserName("catuser");
    db.setPassword("yar");
    if(!db.open())
       {
           QMessageBox::critical(0,("Error"),
                                     ("Unable to connect to DB - driver QMYSQL not loaded or internet connection has been lost."),
                                     QMessageBox::Cancel);
       }
    qDebug() << "SQL_DB_OPEN FUNCTION CALLED";
}
add.cpp:
[CPPQT]
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "mainwindow.h"
#include "add.h"
#include "ui_add.h"
 
 
add::add(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::add)
{
   // MainWindow *mw = new MainWindow;
    ui->setupUi(this);
 
}
 
add::~add()
{
    delete ui;
}
 
void add::on_pushButton_2_clicked()
{
    close();
}
 
void add::on_pushButtonInsert_clicked()
{    
 
    QSqlDatabase db  = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("example.com");
    db.setDatabaseName("cat");
    db.setUserName("catuser");
    db.setPassword("yar");
    if(!db.open())
       {
           QMessageBox::critical(0,("Error"),
                                     ("Unable to connect to DB - driver QMYSQL not loaded."),
                                     QMessageBox::Cancel);
       }
     QSqlQuery query;
     query.exec("SET NAMES UTF8");
     qDebug("NAMES UTF8 HAS BEEN SET");
 
     query.prepare("INSERT INTO test (q1, q2, q3, q4, q5, q6, q7) VALUES(:q1, :q2, :q3, :q4, :q5, :q6, :q7)");
     query.bindValue(":q1", ui->addq1->text());
     query.bindValue(":q2", ui->addq2->text());
     query.bindValue(":q3", ui->addq3->text());
     query.bindValue(":q4", ui->addq4->text());
     query.bindValue(":q5", ui->addq5->text());
     query.bindValue(":q6", ui->addq6->text());
     query.bindValue(":q7", ui->addq7->text());
     qDebug() << "WARNING! INSERT QUERY";
     query.exec();
     add::close();
}
Это быдлокод, согласен. Даже знаю, что код вставки данных в таблицу (mainwindow.cpp) можно сократить в два раза
В заголовочных ничего особенного. В mainwindow.h публично объявлен слот on_pushButton_clicked(), ну и ещё sql_db_open(). Кстати говоря, connect(ui->pushButton_4, SIGNAL(clicked()), this, SLOT(sql_delete_string())) - мой первый в жизни слот, который реализован корректно, а вот другой не получается.

Посоветуйте панацею новичку-быдлокодеру Qt... Вовек буду благодарен!

Добавлено через 7 минут
Извиняюсь за даблпост, забыл добавить функцию удаления строки, а срок редактирования темы прошёл.

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
void MainWindow::sql_delete_string()
{
    sql_db_open();
    QSqlQuery query;
    query.exec("SET NAMES UTF8");
    qDebug("NAMES CP1251 HAS BEEN SET");
    query.prepare("DELETE FROM test WHERE ID = :id;");
    query.bindValue(":id", ui->tableWidget->item(ui->tableWidget->currentIndex().row(), 0)->text());
    qDebug("WARNING!!! DELETE STRING!");
    query.exec();
}
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2012, 00:59
Ответы с готовыми решениями:

Закрытие одной формы из другой
Доброго времени, подскажите пожалуйста! Не могу написать connect для закрытия двух форм, вторая...

Вызов одной формы из другой
Нужно вызвать форму2 по нажатию кнопочки на форме1, как я могу это осуществить? Добавил в проект...

Вызов одной формы из другой
добрый день вообщем есть как бы проект соответственно со структурой 1)mainwindow.h...

Вызов из одной формы другой
Доброго времени суток. Есть головная форма, вызывающая побочную (диалоговую), задача которой...

4
769 / 759 / 59
Регистрация: 06.07.2009
Сообщений: 3,016
25.10.2012, 10:53 2
Несколько раз прочитал, и так и не понял, что конкретно вы хотите и что не получается.
Где слот обновления таблицы? Как вы его пробовали соединить? Выдает ли connect ошибку при соединении?
0
Автор FAQ
2726 / 1422 / 89
Регистрация: 08.09.2011
Сообщений: 3,746
Записей в блоге: 1
25.10.2012, 11:23 3
текста много конкретики мало:
C++ (Qt)
1
connect(form1, SIGNAL(update()), form2, SLOT(update_db()))
form1 - объект класса первой формы
form2 - объект класса второй формы
update() - сигнал который отсылает первая форма
update_db() - слот второй формы который будет отработан когда будет вызван сигнал update() первой формы

Тут все просто
1
TLSofter
25.10.2012, 14:03 4
Всем спасибо большое за ответы!
solar_wind, если говорить конкретно, то я хотел отправить сигнал от кнопки “применить”, формы “add” в слот “sql_db_open” формы mainwindow, но каждый раз, когда я пробовал писать коннектор, отладчик ругался, что коннект не удался

Чистый, я попробую написать коннект, как советуешь ты, но у меня есть еще один вопрос: где лучше всего объявить коннектор: в mainwindow.cpp или в main.cpp?

И еще два маленький вопрос: во время приема БД основная форма виснет. У меня есть идея к реализации двумя способами. Первый. Он же и вопрос. Как можно добавить сообщение без кнопок типа “подождите, запрашиваю БД...”? Читал документацию про эвенты и потоки, гуглил про асинхронную работу с бд, но так и не понял. Наверное, еще не дорос до таких высоких материй. И второе: как реализовать обновление таблицы в реалтайме, когда форма не виснет и видно, как прогружается таблица? Просто, для 500 записей, мб, это не критично, а если 2000 и более?
769 / 759 / 59
Регистрация: 06.07.2009
Сообщений: 3,016
25.10.2012, 15:08 5
Что бы не было зависаний форм, нужно выполнять длительные действия в отдельном потоке. Создаешь класс наследник от QThread и запускаешь его (смотри документацию к QThread). После этого шлешь команды через сигналы, только используй в connect Qt::QueuedConnection
Форма с сообщением выводится через QMassageBox, хоть с кнопками. хоть без кнопок. И закрывать ты ее тоже можешь программно.
Обновление в реалтайме.....ну смотря что ты имеешь ввиду....если посылать в базу по одной букве, то будет большая нагрузка на проц и в многопользовательском режиме не ясно чем обернется. Либо перехватывать события конца редактирования полей...
А посылать по одной записи после подтверждения изменения это не проблема.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.10.2012, 15:08

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

Передача информации от одной формы к другой
Добрый вечер, передаю пару строк от одного окна для отображения в другом, делаю так, отправляю(из...

Заполнение виджетов одной формы из другой
Ситуация сл. Из главной формы открываю другую, в этой самой другой выбираю ини файл, передаю путь к...

Вызов одной формы из другой и наоборот
Нужно реализовать вот такую ​​штуку: есть одна форма создана дизайнером, на ней есть кнопка которая...

Слот при создании формы
Доброго времени суток. Есть ли в Qt слот &quot;При создании формы&quot; или что-то подобное? Т.е. нужен...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.