I Keep getting this error when i try and build this app. Help?
The inferior stopped because it received a signal from the operating system.
Signal name: SIGSEGV
Signal meaning: Segmentation fault
Here is the code for the mainwindow.cpp file
It says the error is on line 122 which is the
copyAct->setEnabled(false);
this is about half way down.
#include "mainwindow.h"
#include <QtGui>
MainWindow::MainWindow(QWidget *parent)
{
textEdit = new QPlainTextEdit;
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
connect(textEdit->document(), SIGNAL(contentsChanged()),this, SLOT(documentWasModified()));
setCurrentFile("");
setUnifiedTitleAndToolBarOnMac(true);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if(maybeSave()){
writeSettings();
event->accept();
}
else{
event->ignore();
}
}
void MainWindow::newFile()
{
if(maybeSave()){
textEdit->clear();
setCurrentFile("");
}
}
void MainWindow::open()
{
if(maybeSave()){
QString fileName = QFileDialog::getOpenFileName(this);
if(!fileName.isEmpty())
loadFile(fileName);
}
}
bool MainWindow::save()
{
if(curFile.isEmpty()){
return saveAs();
}
else{
return saveFile(curFile);
}
}
bool MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this);
if(fileName.isEmpty())
return false;
return saveFile(fileName);
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About Application"),
tr("Whatever you want it to say here!"));
}
void MainWindow::documentWasModified()
{
setWindowModified(textEdit->document()->isModified());
}
void MainWindow::createActions()
{
newAct = new QAction(tr("&New"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(tr("&Save"), this);
saveAct->setShortcuts(QKeySequence::Save);
saveAct->setStatusTip(tr("Save an open file"));
connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr("&Save As"), this);
saveAsAct->setShortcuts(QKeySequence::SaveAs);
saveAsAct->setStatusTip(tr("Save a new file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(saveAs()));
exitAct = new QAction(tr("&Exit"), this);
exitAct->setShortcuts(QKeySequence::Close);
exitAct->setStatusTip(tr("Exit the application"));
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
cutAct = new QAction(tr("&Cut"), this);
cutAct->setShortcuts(QKeySequence::Cut);
cutAct->setStatusTip(tr("Cut the selected text"));
pasteAct = new QAction(tr("&Paste"), this);
pasteAct->setShortcuts(QKeySequence::Paste);
pasteAct->setStatusTip(tr("Paste selected text"));
connect(pasteAct, SIGNAL(triggered()), this, SLOT(setEnabled(bool)));
aboutAct = new QAction(tr("&About"), this);
aboutAct->setShortcuts(QKeySequence::UnknownKey);
aboutAct->setStatusTip(tr("About the application"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(show()));
cutAct->setEnabled(false);
copyAct->setEnabled(false);
connect(textEdit, SIGNAL(copyAvailable(bool)), cutAct, SLOT(setEnabled(bool)));
connect(textEdit, SIGNAL(copyAvailable(bool)), copyAct, SLOT(setEnabled(bool)));
}
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
void MainWindow::readSettings()
{
QSettings settings("Zach Starnes", "Zach's Text Editor");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(400, 400)).toSize();
resize(size);
move(pos);
}
void MainWindow::writeSettings()
{
QSettings settings("Zach Starnes", "Zach's Text Editor");
settings.setValue("pos", pos());
settings.setValue("size", size());
}
bool MainWindow::maybeSave()
{
if (textEdit->document()->isModified()) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("Application"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
}
return true;
}
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
textEdit->setPlainText(in.readAll());
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
}
bool MainWindow::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
out << textEdit->toPlainText();
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
statusBar()->showMessage(tr("File saved"), 2000);
return true;
}
void MainWindow::setCurrentFile(const QString &fileName)
{
curFile = fileName;
textEdit->document()->setModified(false);
setWindowModified(false);
QString shownName = curFile;
if (curFile.isEmpty())
shownName = "untitled.txt";
setWindowFilePath(shownName);
}
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
Looks like for every other action you have (which I assume are member data pointers), you've allocated some memory for:
aboutAct = new QAction(tr("&About"), this);
copyAct seems to be the only action you haven't allocated anything for, and therefore you are dereferencing an invalid pointer.
copyAct->setEnabled(false); // segfault :(
You are missing something like this, I assume:
copyAct = new QAction(tr("&Copy"), this);
I hope this isn't your entire cpp file either, as I don't see a destructor nor any delete's to match all those new commands.
Related
I am trying to program a interface that has a push button and a menu bar using Qt 5.15.
Problem: The main issue is even though a menu bar (menuBar) is instantiated it is not visible in the .ui output window. Also, a push button (quitButton) is instantiated it is visible in the .ui output window. I might be missing something. I am getting a feeling that in Qt either you get a menu bar or a push button widgets but not both. Is it right? Moreover, how can I get both the menu bar and push button in the same .ui window?
This is my QtNotepad.cpp code
#include "qtnotepad.h"
QtNotepad::QtNotepad(QWidget *parent)
: QWidget(parent)
{
openAction = new QAction(tr("&Open"), this);
saveAction = new QAction(tr("&Save"), this);
exitAction = new QAction(tr("&Exit"), this);
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
connect(exitAction, SIGNAL(triggered()), this, SLOT(quit()));
QMenuBar* menuBar = new QMenuBar(nullptr);
fileMenu = menuBar->addMenu(tr("&File"));
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
textEdit = new QTextEdit;
quitButton = new QPushButton(tr("Quit"));
connect(quitButton, SIGNAL(clicked()), this, SLOT(quit()));
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(textEdit);
layout->addWidget(quitButton);
setLayout(layout);
setWindowTitle(tr("Notepad"));
}
void QtNotepad::open()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Text Files (*.txt);; C++ Files(*.cpp *.h);;.dat Files(*.dat)"));
if (fileName != "")
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
return;
}
QTextStream in(&file);
textEdit->setText(in.readAll());
file.close();
}
}
void QtNotepad::save()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), ""), tr("Text Files (*.txt);;C++ Files (*.cpp *.h)");
if (fileName != "")
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
//error message
}
else
{
QTextStream stream(&file);
stream << textEdit->toPlainText();
stream.flush();
file.close();
}
}
}
void QtNotepad::quit()
{
QMessageBox messageBox;
messageBox.setWindowTitle(tr("Notepad"));
messageBox.setText(tr("Do you really want to quit?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
messageBox.setDefaultButton(QMessageBox::No);
if (messageBox.exec() == QMessageBox::Yes)
qApp->quit();
}
This is my QtNotepad.h code
#include <QtWidgets/QMainWindow>
#include "ui_qtnotepad.h"
#include<qtextedit.h>
#include<qpushbutton.h>
#include<qlayout.h>
#include<qobject.h>
#include<qmessagebox.h>
#include<qwidget.h>
#include<qdialog.h>
#include<qfiledialog.h>
#include<qtextstream.h>
#include<qmenubar.h>
class QtNotepad : public QWidget
{
Q_OBJECT
public:
QtNotepad(QWidget *parent = Q_NULLPTR);
private slots:
void quit();
void open();
void save();
private:
Ui::QtNotepadClass ui;
QTextEdit* textEdit;
QPushButton* quitButton;
QAction* openAction;
QAction* saveAction;
QAction* exitAction;
QMenu* fileMenu;
};
This is my main function code.
#include "qtnotepad.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtNotepad window;
window.show();
return a.exec();
}
This is my .ui output window.
QMenuBar* menuBar = new QMenuBar(nullptr);
This line may be the problem. There is one way to approach this -
Add a QMenuBar menuBar as a member of the class QtNotepad
Initialise the menu bar in constructor with parent as this, not nullptr
Since the menuBar is initialised with a nullptr parent, The Window will not take ownership of the menuBar.
I Keep getting this error when i try and build this app. Help?
The inferior stopped because it received a signal from the operating system.
Signal name: SIGSEGV
Signal meaning: Segmentation fault
Here is the code for the mainwindow.cpp file
It says the error is on line 122 which is the
copyAct->setEnabled(false);
this is about half way down.
#include "mainwindow.h"
#include <QtGui>
MainWindow::MainWindow(QWidget *parent)
{
textEdit = new QPlainTextEdit;
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
connect(textEdit->document(), SIGNAL(contentsChanged()),this, SLOT(documentWasModified()));
setCurrentFile("");
setUnifiedTitleAndToolBarOnMac(true);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if(maybeSave()){
writeSettings();
event->accept();
}
else{
event->ignore();
}
}
void MainWindow::newFile()
{
if(maybeSave()){
textEdit->clear();
setCurrentFile("");
}
}
void MainWindow::open()
{
if(maybeSave()){
QString fileName = QFileDialog::getOpenFileName(this);
if(!fileName.isEmpty())
loadFile(fileName);
}
}
bool MainWindow::save()
{
if(curFile.isEmpty()){
return saveAs();
}
else{
return saveFile(curFile);
}
}
bool MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this);
if(fileName.isEmpty())
return false;
return saveFile(fileName);
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About Application"),
tr("Whatever you want it to say here!"));
}
void MainWindow::documentWasModified()
{
setWindowModified(textEdit->document()->isModified());
}
void MainWindow::createActions()
{
newAct = new QAction(tr("&New"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(tr("&Save"), this);
saveAct->setShortcuts(QKeySequence::Save);
saveAct->setStatusTip(tr("Save an open file"));
connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr("&Save As"), this);
saveAsAct->setShortcuts(QKeySequence::SaveAs);
saveAsAct->setStatusTip(tr("Save a new file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(saveAs()));
exitAct = new QAction(tr("&Exit"), this);
exitAct->setShortcuts(QKeySequence::Close);
exitAct->setStatusTip(tr("Exit the application"));
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
cutAct = new QAction(tr("&Cut"), this);
cutAct->setShortcuts(QKeySequence::Cut);
cutAct->setStatusTip(tr("Cut the selected text"));
pasteAct = new QAction(tr("&Paste"), this);
pasteAct->setShortcuts(QKeySequence::Paste);
pasteAct->setStatusTip(tr("Paste selected text"));
connect(pasteAct, SIGNAL(triggered()), this, SLOT(setEnabled(bool)));
aboutAct = new QAction(tr("&About"), this);
aboutAct->setShortcuts(QKeySequence::UnknownKey);
aboutAct->setStatusTip(tr("About the application"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(show()));
cutAct->setEnabled(false);
copyAct->setEnabled(false);
connect(textEdit, SIGNAL(copyAvailable(bool)), cutAct, SLOT(setEnabled(bool)));
connect(textEdit, SIGNAL(copyAvailable(bool)), copyAct, SLOT(setEnabled(bool)));
}
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
void MainWindow::readSettings()
{
QSettings settings("Zach Starnes", "Zach's Text Editor");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(400, 400)).toSize();
resize(size);
move(pos);
}
void MainWindow::writeSettings()
{
QSettings settings("Zach Starnes", "Zach's Text Editor");
settings.setValue("pos", pos());
settings.setValue("size", size());
}
bool MainWindow::maybeSave()
{
if (textEdit->document()->isModified()) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("Application"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
}
return true;
}
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
textEdit->setPlainText(in.readAll());
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
}
bool MainWindow::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
out << textEdit->toPlainText();
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
#endif
setCurrentFile(fileName);
statusBar()->showMessage(tr("File saved"), 2000);
return true;
}
void MainWindow::setCurrentFile(const QString &fileName)
{
curFile = fileName;
textEdit->document()->setModified(false);
setWindowModified(false);
QString shownName = curFile;
if (curFile.isEmpty())
shownName = "untitled.txt";
setWindowFilePath(shownName);
}
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
Looks like for every other action you have (which I assume are member data pointers), you've allocated some memory for:
aboutAct = new QAction(tr("&About"), this);
copyAct seems to be the only action you haven't allocated anything for, and therefore you are dereferencing an invalid pointer.
copyAct->setEnabled(false); // segfault :(
You are missing something like this, I assume:
copyAct = new QAction(tr("&Copy"), this);
I hope this isn't your entire cpp file either, as I don't see a destructor nor any delete's to match all those new commands.
I've been trying to learn c++ and qt framework by doing a point of sale software project.my main window has couple of tabs and with in one tab i have a qpushbutton which open a newpurchase dialog which takes input from user to record a new purchase from supplier.this newpurchase dialog has a lineedit which, when recieves product barcode from a barcode reader ,triggers another quanity dialog which, user can use to enter the quantity of the product. but when i click ok on the button box of the quantity dialog instead of closing just the quantity dialog ,it closes the newpurchase dialog as well.i debugged the qt application and it shows that a qpushbutton (which saves and closes the newpurchase dialog)on the newpuchase dialog gets triggered automatically.additionally this behaviour is only spotted when quantity dialog is triggered through the barcode lineedit,i have another lineedit which accepts description of the product and triggers the same quantity dialog ,but clicking ok button when quantity dialog is triggered through description lineedit does not closes the newpurchase dialog or trigger the qpushbutton which saves and closes the newpurchase dialog.im attaching the screen shots of the dialog and code for the dialogs
on mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
newpurchase mypurchase;
connect(&mypurchase,SIGNAL(purchase_added()),this,SLOT(update_view()));
mypurchase.exec();
}
newpurchase dialog
newpurchase.cpp
#include "newpurchase.h"
#include "ui_newpurchase.h"
#include <QtDebug>
#include <qtablewidget.h>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QCompleter>
#include <QObject>
#include <QWidget>
#include <QDate>
newpurchase::newpurchase(QWidget *parent) :
QDialog(parent),
ui(new Ui::newpurchase)
{
ui->setupUi(this);
QSqlQuery qry;
qry.prepare("select description from product");
if(!qry.exec())
{
qDebug() << "error getting description from product";
}
QStringList items;
while(qry.next())
{
items <<qry.value(0).toString();
}
QCompleter *completer =new QCompleter(items,this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
ui->lineEdit_descripion->setCompleter(completer);
connect(completer,static_cast<void (QCompleter::*)(const QString&)>(&QCompleter::activated),
[&](const QString &text)->void
{
newpurchase::clear(text);
});
QSqlQuery supqry;
supqry.prepare("select supplier_name from supplier");
if(!supqry.exec())
{
qDebug() << "error getting suppliername from supplier";
}
QStringList supitems;
while(supqry.next())
{
supitems <<supqry.value(0).toString();
}
QCompleter *supcompleter =new QCompleter(supitems,this);
supcompleter->setCaseSensitivity(Qt::CaseInsensitive);
ui->lineEdit_sup->setCompleter(supcompleter);
}
newpurchase::~newpurchase()
{
delete ui;
}
void newpurchase::on_lineEdit_barcode_returnPressed()
{
if(!ui->lineEdit_sale->text().isEmpty() && !ui->lineEdit_sup->text().isEmpty() && !ui->lineEdit_inv->text().isEmpty())
{
quantity_dialog quandialog;
connect(&quandialog,SIGNAL(purdetails(QString)),this,SLOT(code(QString)));
quandialog.exec();
}
else
{
Errdialog myerror("please provide supplier and invoice" );
myerror.exec();
}
}
void newpurchase::saveDataIntoTable(QString item,double price,int quantity,QString code,QString date)
{
double rupee =price*quantity*1.00;
//qDebug() <<date;
QString mrp= QString::number(rupee,'f',2);
QString qty= QString::number(quantity);
QString prc= QString::number(price);
// QString kod= QString::number(code);
if (!ui->tableWidget)
return;
const int currentRow = ui->tableWidget->rowCount();
ui->tableWidget->setRowCount(currentRow + 1);
ui->tableWidget->setItem(currentRow, 0, new QTableWidgetItem(item));
ui->tableWidget->setItem(currentRow, 1, new QTableWidgetItem(prc));
ui->tableWidget->setItem(currentRow, 2, new QTableWidgetItem(qty));
ui->tableWidget->setItem(currentRow, 3, new QTableWidgetItem(mrp));
ui->tableWidget->setItem(currentRow, 4, new QTableWidgetItem(code));
ui->tableWidget->setItem(currentRow, 5, new QTableWidgetItem(date));
double total=ui->label_3->text().toDouble();
total = total+rupee;
ui->label_3->setText(QString::number(total,'f',2));
}
void newpurchase::clear(QString item)
{
if(!item.isEmpty())
{
if(!ui->lineEdit_des->text().isEmpty() && !ui->lineEdit_sup->text().isEmpty() && !ui->lineEdit_inv->text().isEmpty())
{
quantity_dialog quandialog;
connect(&quandialog,SIGNAL(purdetails(QString)),this,SLOT(descr(QString)));
quandialog.exec();
}
else
{
Errdialog myerror("please provide supplier and invoice" );
myerror.exec();
}
}
}
void newpurchase::descr(QString q)
{
QStringList elements = q.split(':');
QSqlQuery qry;
qry.prepare("select * from product where description='"+ui->lineEdit_des->text()+"'");
if(!qry.exec())
{
qDebug() << "error getting table product";
}
if (qry.next())
{
QString result=qry.value(1).toString();
double cost= elements[1].toDouble();
QString itemco=qry.value(2).toString();
int quan=elements[0].toInt();
QString mfd=elements[2];
saveDataIntoTable(result,cost,quan,itemco,mfd);
ui->lineEdit_des->clear();
}
}
void newpurchase::on_pushButton_clicked()
{
QItemSelectionModel *select =ui->tableWidget->selectionModel();
int row = select->selectedRows().takeFirst().row();
double rupee=ui->tableWidget->item(row,3)->text().toDouble();
ui->tableWidget->removeRow(row);
double total=ui->label_3->text().toDouble();
total = total-rupee;
ui->label_3->setText(QString::number(total,'f',2));
}
void newpurchase::on_lineEdit_des_returnPressed()
{
}
void newpurchase::code(QString q)
{
QStringList elements = q.split(':');
QSqlQuery qry;
qry.prepare("select * from product where code="+ui->lineEdit_sale->text());
if(!qry.exec())
{
qDebug() << "error getting table product";
}
if (qry.next())
{
QString result=qry.value(1).toString();
double cost= elements[2].toDouble();
QString itemco=qry.value(2).toString();
int quan=elements[0].toInt();
QString mfd=elements[1];
saveDataIntoTable(result,cost,quan,itemco,mfd);
}
ui->lineEdit_sale->clear();
}
void newpurchase::on_pushButton_2_clicked()
{
QString datetime= QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString supplier=ui->lineEdit_sup->text();
QString invoice=ui->lineEdit_inv->text();
int numrow=ui->tableWidget->rowCount();
// qDebug() << numrow;
for (int i = 0; i < numrow; i++)
{
QSqlQuery query;
query.prepare("SELECT MAX(Id) FROM stock_transaction");
if(!query.exec())
{
qDebug() << "error getting id";
}
int id=0 ;
if (query.next())
{
id=query.value(0).toInt()+1;
}
QString coder=ui->tableWidget->item(i,4)->text();
QString qua=ui->tableWidget->item(i,2)->text();
double rate=ui->tableWidget->item(i,1)->text().toDouble();
QString date= ui->tableWidget->item(i,5)->text();
QString d=QString::number(id);
QString batch=supplier+"_"+invoice+"_"+d;
QSqlQuery querysale;
querysale.prepare("INSERT INTO stock_transaction(id,code,stock,mfd,supplier,invoice,cost,date_time) VALUES(:id,:code,:stock,:mfd,:supplier,:invoice,:cost,:date_time)");
querysale.bindValue(":id", id);
querysale.bindValue(":code",coder);
querysale.bindValue(":stock", qua.toInt());
querysale.bindValue(":mfd",date);
querysale.bindValue(":supplier", supplier);
querysale.bindValue(":invoice", invoice);
querysale.bindValue(":cost", rate*1.00);
querysale.bindValue(":date_time", datetime);
if(!querysale.exec())
{
qDebug() << "error recording sale";
}
}
emit this->purchase_added();
close();
}
quantity dialog
quantity.cpp
#include "quantity_dialog.h"
#include "ui_quantity_dialog.h"
quantity_dialog::quantity_dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::quantity_dialog)
{
ui->setupUi(this);
ui->lineEdit_quan->setFocus();
ui->buttonBox->setEnabled(false);
connect(ui->lineEdit_quan, SIGNAL(textChanged(QString)), this, SLOT(checkLineEdits()));
connect(ui->dateEdit, SIGNAL(dateChanged(QDate)), this, SLOT(checkLineEdits()));
connect(ui->lineEdit_3, SIGNAL(textChanged(QString)), this, SLOT(checkLineEdits()));
}
quantity_dialog::~quantity_dialog()
{
delete ui;
}
void quantity_dialog::on_buttonBox_accepted()
{
emit purdetails(ui->lineEdit_quan->text()+":"+ui->dateEdit->text()+":"+ui->lineEdit_3->text());
ui->lineEdit_quan->clear();
}
Please let me know if i can provide any other details
the auto default property of the autoclicking qpushbutton was set.changing this property solved my issue
I´m starting multiple QProcesses from a textfile (for example different programs like notepad.exe and so on) and want to regularly check if they are still running.
A while loop isn´t the solution, since it is blocking the ui-thread.
How can this be achieved? In Java (Android) I would do this with a asynctask
connected to a ScheduldExecutorService. Is something similar available for qt?
This is where I start my processes:
void mywidget::startprocesses(QString &text)
{
QProcess *process = new QProcess(this);
this->myprocess.append(process);
process->start(text);
int state = process->state();
addlabelstatus(state);
}
And here the method is called:
while(!stream->atEnd()) //check stream until empty and assign line as a caption to a new QLabel
{
this->fileread = stream->readLine();
if(!this->fileread.isEmpty())
{
central->addlabel(this->fileread);
central->startprocesses(this->fileread);
}
}
void mywidget::addlabelstatus(QProcess::ProcessState newstate)
{
QString sstring;
if(newstate == 0)
{
QString sstring = "Wird nicht ausgeführt";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
else if (newstate == 1)
{
QString sstring = "Wird gestartet!";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
else if (newstate == 2)
{
QString sstring = "Wird ausgeführt!";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
else
{
QString sstring = "kein Status vorhanden!";
QLabel *label = new QLabel(sstring);
this->processstatus.append(label);
this->vrarea->addWidget(label);
}
}
Each QProcess has finished(int exitCode, QProcess::ExitStatus exitStatus) and stateChanged(QProcess::ProcessState newState) signals, that emits when some process has been terminated or changed (by type of). So your code can be:
.H side:
public slots:
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
void addlabelstatus(QProcess::ProcessState newState);
.CPP side:
void mywidget::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
<...>
}
void mywidget::addlabelstatus(QProcess::ProcessState newState)
{
switch(newState) {
<...>
};
}
// Your code change
QProcess *process = new QProcess(this);
this->myprocess.append(process);
connect(process, &QProcess::finished, this, &mywidget::processFinished);
connect(process, &QProcess::stateChanged, this, &mywidget::addlabelstatus);
process->start(text);
UPDATE FOR COMMENT QUESTION
You can try this way:
.H side
public slots:
void processFinished(QLabel *label, int exitCode, QProcess::ExitStatus exitStatus);
void addlabelstatus(QLabel *label, QProcess::ProcessState newState);
.CPP side
void mywidget::processFinished(QLabel *label, int exitCode, QProcess::ExitStatus exitStatus)
{
<...>
}
void mywidget::addlabelstatus(QLabel *label, QProcess::ProcessState newState)
{
switch(newState) {
<...>
};
}
while(!stream->atEnd()) {
this->fileread = stream->readLine();
if(!this->fileread.isEmpty()) {
QLabel *label = new QLabel(this->fileread);
QProcess *process = new QProcess(this);
this->myprocess.append(process);
connect(process, &QProcess::finished, [=]
(int exitCode, QProcess::ExitStatus exitStatus)
{ processFinished(label, exitCode, exitStatus); });
connect(process, &QProcess::stateChanged, [=]
(QProcess::ProcessState newState)
{ addlabelstatus(label, newState); });
process->start(text);
}
}
A while loop isn´t the solution, since it is blocking the ui-thread.
Correct. However, since Qt is an event-driven framework, you could use a timer:-
// Assuming we have a list of processes QList<QProcess*> called timerList
QTimer* pTimer = new QTimer;
connect(pTimer, &QTimer::timeout, [=](){
foreach(QProcess* proc, timerList)
{
// get state
int state = process->state();
// update UI
addlabelstatus(state);
}
});
pTimer->start(1000); // every second
Or alternatively, as #someoneinthebox answered, connect to each QProcess's stateChanged signal to notify you when it occurs and react to that.
I am new in Qt and I need to do a program who export html page to PDF
So, the main idea is use QWebPage for interpret html and export itself to pdf with QPrinter.
I have two class webview who use QWebPage and Print who use QPrinter.
In main.cpp I have connect LoadFinished to PrintPDF slot:
Print *pdf = new Print(args);
webview *nav = new webview();
nav->setPrinter(pdf->getPrinter());
if(nav->load(args) == false) {
qDebug() << "can't load page";
return 0;
}
//when the page page is ready, we will print it
QObject::connect(nav->getFrame(), SIGNAL(loadFinished(bool)), nav, SLOT(printPDF(bool)));
My webview.cpp class:
#include "webview.h"
webview::webview()
{
page = new QWebPage;
printer = 0;
}
webview::~webview()
{
delete page;
}
bool webview::load(Arguments *args)
{
QRegularExpression url("^(file|http)://");
QRegularExpression fullPath("^/");
QRegularExpressionMatch pathMatch = fullPath.match(args->getSource());
QRegularExpressionMatch urlMatch = url.match(args->getSource());
// see http://qt-project.org/doc/qt-4.8/qwebsettings.html#WebAttribute-enum for more informations
page->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
page->settings()->setAttribute(QWebSettings::AutoLoadImages, true);
page->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
page->settings()->setAttribute(QWebSettings::PrintElementBackgrounds, true);
page->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
if(pathMatch.hasMatch()) {
page->mainFrame()->load(QUrl::fromLocalFile(args->getSource()));
} else {
if (urlMatch.hasMatch()) {
page->mainFrame()->load(QUrl(args->getSource()));
} else {
fprintf(stderr, "%s\n", qPrintable(QApplication::translate("main", "Error: Invalide source file")));
return false;
}
}
return true;
}
void webview::printPDF(bool ok)
{
if(ok == true) {
qDebug() << "okay";
} else
qDebug() << "non okay";
if(printer != 0)
page->mainFrame()->print(printer);
}
This is what my console display:
non okay
QPainter::begin: A paint device can only be painted by one painter at a time.
I have no idea where the error might be due. The whole project is here
The arguments are:
./htmltopdf http://stackoverflow.com destinationFolder
(destinationFolder is not yet implemented, you must directly modify the source code)
You have more than one Painter in your Code. Search for it.
I thing the Problem is in your "Printer Class". With a Local Printer in the printPDF Method it works. Try it:
void webview::printPDF(bool ok)
{
QPrinter printer(QPrinter::HighResolution);
QString fileName = QFileDialog::getSaveFileName(this, "Export PDF",
QString(), "*.pdf");
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
page()->mainFrame()->print(&printer);
}
UPDATE: Here a small working Example:
testview.cpp
#include "testview.h"
#include <QWebFrame>
#include "webview.h"
#include <QWebPage>
#include <QGridLayout>
testview::testview(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QGridLayout* Layout = new QGridLayout(this);
webview* w = new webview(this);
w->setMinimumSize(500, 500);
centralWidget()->setLayout(Layout);
bool a = connect(w->page()->mainFrame(), SIGNAL(loadFinished(bool)), w, SLOT(printPDF(bool)));
w->page()->mainFrame()->load(QUrl("http://stackoverflow.com"));
}
testview::~testview()
{
}
webview.cpp
#include "webview.h"
#include <QPrinter>
#include <QWebFrame>
#include <QFileDialog>
webview::webview(QWidget *parent)
: QWebView(parent)
{
}
webview::~webview()
{
}
void webview::printPDF(bool ok)
{
QPrinter printer(QPrinter::HighResolution);
QString fileName = QFileDialog::getSaveFileName(this, "Export PDF",
QString(), "*.pdf");
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
page()->mainFrame()->print(&printer);
}
The problem was elsewhere :
In my main.cpp I had this :
QObject::connect(nav->getFrame(), SIGNAL(loadFinished(bool)), nav, SLOT(printPDF(bool)));
[...]
delete args;
delete pdf;
delete nav;
return app.exec();
app.exec() is a kind of infinit loop who thaht handles Qt events and thus allows the program does not close.
If I proceed to delete before calling this function,then I will have freshly deallocated pointers that will be used
If I Do :
bool result = app.exec();
delete args;
delete pdf;
delete nav;
return result;
It's work fine !