PDA

View Full Version : How to create an Insert/Submit button for a form.



fnmblot
2nd August 2006, 21:57
Hello Everyone... Long time reader, first time poster. I must say, I have learned so much from this forum, and I thank you all. I have a form that I will be entering info about the pieces of music I write, and they will be saved into a MySQL database on another machine. I can connect to the database just fine. I am trying to create a button on the form that will insert the info on the form into the database:

model->insertRecord(-1, rec);

Would I have to create a seperate header file, or could I create this in the main.cpp? I tried adding a Submit Button like these two ways, but both did not work:

QPushButton *submitButton = new QPushButton("Submit");
QObject::connect(submitButton, SIGNAL(clicked()), &app, SLOT(model->insertRecord(-1, rec)));
or
QPushButton *submitButton = new QPushButton("Submit");
QObject::connect(submitButton, SIGNAL(clicked()), &app, SLOT(exec(model->insertRecord(-1, rec))));

If I put that directly into the code like this:
QSqlTableModel *model = new QSqlTableModel;
model->setTable("main");
QSqlRecord rec;
rec.append(QSqlField("piece_name", QVariant::String));
rec.append(QSqlField("status", QVariant::String));
rec.setValue("piece_name", pieceNameLineEdit->text());
rec.setValue("status", statusComboBox->currentText());
model->insertRecord(-1, rec);
it will create a new record with nothing in the piece_name field, and "In Progress" in the status field.

Any advice would be very much appreciated.

Brian
QT 4 on Windows XP

jacek
2nd August 2006, 22:21
You need a custom slot for this. To make one, you need a class.

http://doc.trolltech.com/4.1/tutorial-t4.html

Chicken Blood Machine
2nd August 2006, 22:24
Read the section in the Qt docs on 'signals and slots' very carefully. This:


QObject::connect(submitButton, SIGNAL(clicked()), &app, SLOT(model->insertRecord(-1, rec)));
is not valid. You cannot pass parameters to slots in a connect statement. Also, the QApplication object has no slot called "model->insertRecord()" (which would be impossible anyway). It should be


QObject::connect(submitButton, SIGNAL(clicked()), &myWidget, SLOT(insertRecordSlot()));

Where myWidget is an instance of your GUI form.
Since the clicked() signal does not have any parameters, the slot you connect it to cannot have any parameters either.

Then in your insertRecordSlot() implementation, you can do this:


void MyWidget::insertRecordSlot()
{
...
model->insertRecord(-1, rec));
}

In answer to your question of whether you will need to create a separate header file or not, that is just a question of good modular design, i.e. it is your decision. You will have to declare your MyWidget class in some header file, so that moc can process your slots declaration. Whether that is in main.h or MyClass.h or whatever.h is up to you...

Also, it's usually cleaner to put your internal GUI connection code in the constructor of your GUI class and not outside of it in main (in most cases).

fnmblot
4th August 2006, 13:32
ok, so I did as suggested... read the tutorial. I created a class, and it compiles without errors. But when I click on the submit button, nothing happens. This is what I wrote:

pieceInsert.h

#ifndef PIECEINSERT_H
#define PIECEINSERT_H

#include <QDialog>

class QLabel;
class QLineEdit;
class QComboBox;
class QSqlTableModel;

class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);

private slots:
void insertRecordSlot();

private:
QLabel *itemLabel;
QSqlTableModel *model;
QLabel *pieceNameLabel;
QLineEdit *pieceNameLineEdit;
QLabel *statusLabel;
QComboBox *statusComboBox;
QPushButton *closeButton;
QPushButton *submitButton;
};

#endif
pieceInsert.cpp

#include <QApplication>
...
#include "pieceInsert.h"

Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
// Window Title
QWidget *window = new QWidget;
window->setWindowTitle("NNBS Piece Entry");
window->setFixedSize(450, 270);

// Piece Entry Section
pieceNameLabel = new QLabel();
pieceNameLabel->setText("Piece Name");
pieceNameLineEdit = new QLineEdit();
statusLabel = new QLabel();
statusLabel->setText("Status");
statusComboBox = new QComboBox();
statusComboBox->addItem("In Progress");
statusComboBox->addItem("Dormant");
statusComboBox->addItem("Complete");

QHBoxLayout *h2BoxLayout = new QHBoxLayout;
h2BoxLayout->addWidget(pieceNameLabel);
h2BoxLayout->addWidget(pieceNameLineEdit);
h2BoxLayout->addWidget(statusLabel);
h2BoxLayout->addWidget(statusComboBox);

// **** Start Create Buttons ****//
// Close Button Layout
closeButton = new QPushButton("Close");
QObject::connect(closeButton, SIGNAL(clicked()), qApp, SLOT(quit()));
// Submit Button
submitButton = new QPushButton("Submit");
QObject::connect(submitButton, SIGNAL(clicked()), qApp, SLOT(insertRecordSlot()));
// Create Buttons Layout
QHBoxLayout *hBoxLayout = new QHBoxLayout;
QSpacerItem *spacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
hBoxLayout->addItem(spacerItem);
hBoxLayout->addWidget(submitButton);
hBoxLayout->addWidget(closeButton);
// **** End Buttons **** //

// Entire Layout
QVBoxLayout *vBoxLayout = new QVBoxLayout;
vBoxLayout->addLayout(h2BoxLayout);
vBoxLayout->addLayout(hBoxLayout);
window->setLayout(vBoxLayout);
window->show();
}
void Dialog::insertRecordSlot()
{
// SQL Insert Record
QSqlRecord rec;
rec.append(QSqlField("piece_name", QVariant::String));
rec.append(QSqlField("status", QVariant::String));
rec.setValue("piece_name", pieceNameLineEdit->text());
rec.setValue("status", statusComboBox->currentText());
model = new QSqlTableModel;
model->setTable("main");
model->insertRecord(-1, rec);
}
Any suggestions?

jacek
4th August 2006, 15:10
But when I click on the submit button, nothing happens.
You have connected clicked() signal to QApplication instance (qApp) instead of Dialog.

It should be:
connect(closeButton, SIGNAL(clicked()), this, SLOT(quit()));
...
connect(submitButton, SIGNAL(clicked()), this, SLOT(insertRecordSlot()));

BTW. Qt should warn you that you try to connect to slot that doesn't exist. If you can't see the message on the console, you will have to compile your application in debug mode. To do this add CONFIG += debug to your .pro file. On windows your application should be compiled in both debug and release modes by default, but you need CONFIG += console, to actually see the console.

fnmblot
4th August 2006, 16:18
I never knew about the CONFIG += debug or console tricks.

Thanks!

Brian