I'm new in Qt and C++. I want to implement a vector with using a class called Item. I think I'm doing a beginners mistake. I'm getting the below error. Can someone please help?
C:\Qt\Qt5.6.1\5.6\msvc2015_64\include\QtCore\qvector.h:631: error: C2280: 'Item::Item(const Item &)': attempting to reference a deleted function
Below is my mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVector>
#include <QtCore>
#include <QtGui>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
void MainWindow::AddRoot(QString item)
{
QTreeWidgetItem *itm = new QTreeWidgetItem(ui->treeWidget);
itm->setText(0,item);
ui->treeWidget->addTopLevelItem(itm);
}
void MainWindow::AddChild(QTreeWidgetItem *parent,QString item)
{
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
Item item;
item.setDescription(ui->lineEdit->text());
data.push_back(item);
ui->treeWidget->setColumnCount(1);
AddRoot(item.getDescription());
}
And my item.cpp class
#include "item.h"
#include <QtCore>
#include <QtGui>
Item::Item()
{
}
void Item::setDescription(QString desc)
{
Description = desc;
}
void Item::setEnterDate(QDateTime enterDate)
{
EnterDate = enterDate;
}
void Item::setEndDate(QDateTime endDate)
{
EndDate = endDate;
}
QString Item::getDescription()
{
return Description;
}
QDateTime Item::getEnterDate()
{
return EnterDate;
}
QDateTime Item::getEndDate()
{
return EndDate;
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <item.h>
#include <QtGui>
#include <QtCore>
#include <QTreeWidget>
mainwindow.h:
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QVector<Item> data;
void AddRoot(QString item);
void AddChild(QTreeWidgetItem *parent,QString item);
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
item.h:
#ifndef ITEM_H
#define ITEM_H
#include <QtCore>
#include <QtGui>
class Item : public QObject
{
Q_OBJECT
public:
explicit Item(QObject *parent = 0);
QString Description;
QDateTime EnterDate;
QDateTime EndDate;
QString getDescription();
QDateTime getEnterDate();
QDateTime getEndDate();
void setDescription(QString desc);
void setEnterDate(QDateTime enterDate);
void setEndDate(QDateTime endDate);
};
#endif // ITEM_H
Item is a QObject. QObjects are know for not having a copy constructor. In order to use the QVector, the item needs to have a copy constructor. Either change Item to not being a QObject, or use QSharedPointer (but only if you understand ownership).
Related
doit is a Qthread subclass with a signal kif() but the signal emitting is not working I want to show the resualt of gav() on one of my editLines at the same time as its changes inside gav() pls help :((((((( I wasted so much time to find out how I can do it :((((((
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
doit.h
#ifndef DOIT_H
#define DOIT_H
#include <QThread>
class doit : public QThread
{
Q_OBJECT
public:
doit();
int i;
QString z;
void run() ;
void gav(int &i);
signals:
void kif(const QString &text);
};
#endif // DOIT_H
#include "doit.h"
doit::doit()
{
}
void doit::run()
{
gav(i);
}
void doit::gav(int &i)
{
int k=i;
for (int b=0;b<k;b++){
i=b;
z= QString::number(i);
emit kif(z);
}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "doit.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
doit *dovit=new doit;
private slots:
void checkInput(const QString &text);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//QObject::connect(dovit,doit::kif(&QString),this , MainWindow::checkInput(QString)))
connect(dovit,SIGNAL(kif(QString)),this,SLOT(checkInput(QString)));
dovit->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::checkInput(const QString &text)
{
ui->lineEdit_3->setText(text);
}
and Im new in this , so pls tell me exactlly where should I change or add and what tanx alot
Well it finally worked after wasting a lot of my time. For anyone wondering vtables was the problem (as I read its a bug (not sure)) and I should just
right click on the project folder and rebuild and run qmake the project ,
I added Qobject.h too and it worked.
working code:
(it is also a simple and good example of meta signaling in qt if you need it)
doit.h
#define DOIT_H
#include <QThread>
#include <QObject>
class doit : public QThread
{
Q_OBJECT
public:
doit();
void gav();
void run() ;
signals:
void kif(QString text);
};
#endif // DOIT_H
doit.cpp
#include "doit.h"
#include <QDebug>
doit::doit()
{
}
void doit::run()
{
gav();
}
void doit::gav()
{
QString z;
for (int i=0;i<11;i++){
z="mamad";
z = z + QString::number(i);
QThread::sleep(1);
qDebug()<<z;
emit kif(z);
}
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "doit.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
doit *dovit=new doit;
//doit dovit;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(dovit,SIGNAL(kif(QString)),this->ui->lineEdit_3,SLOT(setText(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
dovit->start();
}
I'm writing QT deskop app and I have a small issue.
I want to open new tab with text that I put from a file.
I have two class one in mainwindow.h and second in form.h
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void on_open_file_clicked();
void on_search_keyword_clicked();
void on_search_tag_clicked();
void on_tabWidget_tabCloseRequested(int index);
void show_tab(QString keywords);
QString return_text();
public:
Ui::MainWindow *ui;
private slots:
void on_actionOpen_file_triggered();
void on_actionShow_text_file_triggered();
QVector<QString>find_logs_keywords(QString keywords);
private:
QString text = "example text";
};
#endif // MAINWINDOW_H
form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
public slots:
void on_pushButton_2_clicked();
void text_to_plain(QString& text);
private:
Ui::Form *ui;
};
#endif // FORM_H
mainwindow.cpp
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QDir>
#include <QVector>
#include <QStringList>
#include <iostream>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "search_keyword.h"
#include "search_tag.h"
#include "form.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_open_file_clicked()
{
QString filter = "log file (*log) ;; Tex File (*.txt)";
QString file_name = QFileDialog::getOpenFileName(this, "Open a file", QDir::homePath(), filter);
QMessageBox::information(this,"..",file_name);
QFile file(file_name);
if (!file.open(QFile::ReadOnly | QFile::Text)) QMessageBox::warning(this,"title","file not open");
else
{
QTextStream in(&file);
text = in.readAll();
ui->plainTextEdit->setPlainText(text);
ui->lineEdit->setPlaceholderText(file_name);
}
file.close();
}
void MainWindow::on_actionShow_text_file_triggered()
{
show_tab("all logs");
Form Fr;
Fr.text_to_plain(text);
}
void MainWindow::show_tab(QString keywords)
{
ui->tabWidget->addTab(new Form(), QString("%1").arg(keywords));
ui->tabWidget->setCurrentIndex(ui->tabWidget->count()-1);
}
form.cpp
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::text_to_plain(QString& text)
{
ui->plainTextEdit->setPlainText(text);
}
My problem is after call method void MainWindow::on_actionShow_text_file_triggered() plain text in QWidget in Form is still empty i tried: this->update, this->repaint, Form::update(); Form::repaint(), QWidget::repaint(); QWidget::update();. Everything fail.
the problem is that your Form exists only in this function scope.
void MainWindow::on_actionShow_text_file_triggered()
{
show_tab("all logs");
Form Fr;
Fr.text_to_plain(text);
}
Here -> Form Fr; the Form is created: constructor(explicit Form(QWidget *parent = nullptr);) of the class Form is called
And at this place -> } your Form is deleted: destructor(~Form();) of class Form is called.
This happens because you create your Form instance on the function stack. So Fr is local object and exist only in the scope of the function on_actionShow_text_file_triggered() after the function is executed/finished all local variables are freed/destructed.
if your Fr object should exist not just in this function you need to create it on the heap instead of stack.
P.S.: for case study read about stack vs heap for example hear: What and where are the stack and heap?
Your on_actionShow_text_file_triggered function should then look like this:
void MainWindow::on_actionShow_text_file_triggered()
{
show_tab("all logs");
Form * Fr = new Form(this); //if you set parent object your Form will be automatically deleted/destructed then MainWindow is deleted/destructed
Fr->text_to_plain(text);
Fr->show(); // you should call show() function of QWidget class and subclasses to get your widget visible
}
This Form * Fr = new Form(this); will create new form pointer every time. Would not it be better to create one global pointer to the form, call the functions and delete it later?
My app, consists in 2 different object (QObject and QMainWIndow), and I am wondering how to communicate between them with SLOT/SIGNAL. Moreover, does existing better approach ?
Can someone make an simple example ? Thank :)
sample
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "ui_mainwindow.h"
#include "object.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "object.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->chkState, SIGNAL(clicked()), this, SLOT(object->chkState();));
}
MainWindow::~MainWindow()
{
delete ui;
}
object.h
#ifndef OBJET_H
#define OBJET_H
#include "mainwindow.h"
#include <QMainWindow>
#include <QObject>
class Object : public QObject
{
Q_OBJECT
public:
explicit Object(QObject *parent = 0);
bool state;
signals:
private slots:
void chkState(Ui::MainWindow *ui);
};
#endif // OBJET_H
objet.cpp
#include "object.h"
#include "mainwindow.h"
Object::Object(QObject *parent) : QObject(parent)
{
}
void Object::chkState(Ui::MainWindow *ui)
{
if (ui->chkState->isChecked())
{
ui->state->setText("true");
state = true;
}
else
{
ui->state->setText("false");
state = false;
}
}
Here is a simple example of how to emit signals and slots.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "object.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void transmit_to_object(bool value);
private slots:
void receive_from_object(bool value);
void on_checkBox_clicked();
private:
Ui::MainWindow *ui;
object m_object;
};
#endif // MAINWINDOW_H
#ifndef OBJECT_H
#define OBJECT_H
#include <QObject>
class object : public QObject
{
Q_OBJECT
public:
explicit object(QObject * parent = 0);
signals:
void transmit_to_gui(bool value);
private slots:
void receive_from_gui(bool value);
private:
bool state;
};
#endif // OBJECT_H
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&m_object,SIGNAL(transmit_to_gui(bool)),this,SLOT(receive_from_object(bool)));
connect(this,SIGNAL(transmit_to_object(bool)),&m_object,SLOT(receive_from_gui(bool)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::receive_from_object(bool value)
{
if(value)
{
ui->lineEdit->setText("true");
}
else
{
ui->lineEdit->setText("false");
}
}
void MainWindow::on_checkBox_clicked()
{
if(ui->checkBox->isChecked())
{
emit transmit_to_object(true);
}
else
{
emit transmit_to_object(false);
}
}
#include "object.h"
#include "mainwindow.h"
object::object(QObject *parent)
{
}
void object::receive_from_gui(bool value)
{
state = value;
emit transmit_to_gui(state);
}
There are several errors in your code.
First:
connect(ui->chkState, SIGNAL(clicked()), this, SLOT(object->chkState();));
Here you say:
"when we click on the ui->chkState, I want you call a function in this, which is the object->chkState slot". That's definitly not what you want.
What is object ? this object hasn't been created. What you want is :
connect(ui->chkState, SIGNAL(clicked()), myobject, SLOT(chkState()));
with myobject an object of type Object so you need to add in your mainwindow.h a
Object *myobject;
and in your mainwindow.cpp before the connect:
myobject = new Object(this);
Moreover, your function void chkState(Ui::MainWindow *ui); won't work because you cannot get the mainwindow ui in parameter like that.
What I advise you to do, if it's only for tests so you know that parent is the type of MainWindow, you can do:
void Object::chkState()
{
MainWindow* parent = static_cast<MainWindow*>(parent());
if (parent->ui->chkState->isChecked())
{
parent->ui->state->setText("true");
state = true;
}
else
{
parent->ui->state->setText("false");
state = false;
}
}
So the parameter in your slot is removed.
I want to get the currentIndex of combobox in the main Widget, then send this value to another class. I tried to make a function to return the currentIndex, however, I always get '0'. Could someone explain me why, or give me an example? Plus, I think it's because I create a new object in another class, but how can I get the actived Widget's pointer? Here are the codes:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui { class Widget; }
class Widget : public QWidget {
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
int comboboxText();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui; };
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include "database.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
int Widget::comboboxText(){
return ui->comboBox->currentIndex();
}
void Widget::on_pushButton_clicked()
{
qDebug() << "from Widget: " << comboboxText();
Database database;
database.getIndex();
}
database.h
#ifndef DATABASE_H
#define DATABASE_H
#include <QObject>
#include <QDebug>
class Database : public QObject
{
Q_OBJECT
public:
explicit Database(QObject *parent = 0);
void getIndex();
signals:
public slots:
};
#endif // DATABASE_H
database.cpp
#include "database.h"
#include <widget.h>
Database::Database(QObject *parent) : QObject(parent)
{
}
void Database::getIndex(){
Widget a;
qDebug()<< "from database: " << a.comboboxText();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileSystemModel>
#include <QThread>
#include <statusdialog.h>
#include <pbt.h>
#include <stdint.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//void on_treeView_clicked(const QModelIndex &index);
void onCustomContextMenuTV(const QPoint &point);
void dirSize();
void getSelectedTreeItemSize();
void resultHandle(uint64_t);
signals:
void sizeCalculation(uint64_t);
private:
Ui::MainWindow *ui;
QString sPath;
QFileSystemModel *dirmodel;
QFileSystemModel *filemodel;
QAction *dirSizeAct;
statusDialog statusdialog;
};
#endif // MAINWINDOW_H
pbt.h
#ifndef STATUSDIALOG_H
#define STATUSDIALOG_H
#include <QDialog>
#include <stdint.h>
namespace Ui {
class statusDialog;
}
class statusDialog : public QDialog
{
Q_OBJECT
public:
explicit statusDialog(QWidget *parent = 0);
~statusDialog();
void setProgressbarMax(uint64_t);
private slots:
void on_pushButton_clicked();
private:
Ui::statusDialog *ui;
};
#endif // STATUSDIALOG_H
statusdialog.h
#ifndef STATUSDIALOG_H
#define STATUSDIALOG_H
#include <QDialog>
#include <stdint.h>
namespace Ui {
class statusDialog;
}
class statusDialog : public QDialog
{
Q_OBJECT
public:
explicit statusDialog(QWidget *parent = 0);
~statusDialog();
void setProgressbarMax(uint64_t);
private slots:
void on_pushButton_clicked();
private:
Ui::statusDialog *ui;
};
#endif // STATUSDIALOG_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
sPath = "C:/";
dirmodel = new QFileSystemModel(this);
dirmodel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
dirmodel->setRootPath(sPath);
ui->treeView->setModel(dirmodel);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenuTV(const QPoint &)));
connect(this,SIGNAL(sizeCalculation(uint64_t)),this,SLOT(resultHandle(uint64_t)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::resultHandle(uint64_t t_size)
{
statusdialog.setProgressbarMax(t_size);
}
void MainWindow::onCustomContextMenuTV(const QPoint &point)
{
dirSizeAct = new QAction(tr("Size"), this);
connect(dirSizeAct, SIGNAL(triggered()), this, SLOT(dirSize()));
QMenu contextMenu(this);
contextMenu.addAction(dirSizeAct);
QModelIndex index = ui->treeView->indexAt(point);
if (index.isValid()){
contextMenu.exec(ui->treeView->mapToGlobal(point));
}
}
void MainWindow::dirSize()
{
pBT pbt;
pbt.setFP(this->getSelectedTreeItemSize);
QThread thread1;
connect(&thread1,SIGNAL(started()),&pbt,SLOT(startThreadAction()));//Clone the object and it will not work, becouse it is QWidget
pbt.moveToThread(&thread1);
thread1.start();//Starts in the same thread
statusdialog.setModal(true);
statusdialog.exec();
}
void MainWindow::getSelectedTreeItemSize()
{
QModelIndex index = ui->treeView->selectionModel()->selectedIndexes().takeFirst();
QString dirPath = dirmodel->filePath(index);
QDirIterator it(dirPath, QStringList() << "*.*", QDir::Files, QDirIterator::Subdirectories);
uint64_t t_size = 0;
while (it.hasNext()) {
QFile myFile(it.next());
if (myFile.open(QIODevice::ReadOnly)){
t_size += myFile.size();
myFile.close();
}
}
emit sizeCalculation(t_size);
}
pbt.cpp
#include "pbt.h"
pBT::pBT(QObject *parent) : QObject(parent)
{
}
void pBT::startThreadAction()
{
this->fp1();
}
void pBT::setFP(void (*fp1)())
{
this->fp1 = fp1;
}
statusdialog.cpp
#include "statusdialog.h"
#include "ui_statusdialog.h"
statusDialog::statusDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::statusDialog)
{
ui->setupUi(this);
}
statusDialog::~statusDialog()
{
delete ui;
}
void statusDialog::on_pushButton_clicked()
{
this->close();
}
void statusDialog::setProgressbarMax(uint64_t size)
{
ui->progressBar->setMaximum(size);
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
To see more info of what I am doing you can look this topic(It is all about prograssbar and threaded execution of job). Theoretically I whant to run a member function of mainwindow(which use member variables of mainwindow) into new thread(the function is not static) inside slot dirSize()(also member slot of the same class mainwindow), but it seems with QThread it is necessary to create new class(no matter if I will inherit QThread class or use moveToThread function of QObject) and run that class in new thread. If I use C++ thread.h the function I run must be static, nevermind I have tried to create pBT class in which I have function pointer fp1 and public slot startThreadedAction, but when try to buil this error occures:
C:\Users\niki\Documents\EPsimple\mainwindow.cpp:54: error: C3867:
'MainWindow::getSelectedTreeItemSize': function call missing argument
list; use '&MainWindow::getSelectedTreeItemSize' to create a pointer
to member
I don`t want to create function pointer to static function! How can I fix this?