Way to find clicked ListItem on ListWidget - c++

I want to get ListItem in ListWidget that I clicked. But I can't find the way. All the things say get from text but I want the clicked one. Also I'm new in qt and c++.
stackoverflow says add more detail but I don't know how to add more detail so I write this line to get enough "detail".
Here is my .h file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <string.h>
#include <QListWidgetItem>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
class rsu
{
public:
std::string id;
std::string name;
double coorx;
double coory;
std::string ip;
int port;
};
std::vector<rsu> r;
QListWidgetItem *rsuitem;
private:
Ui::MainWindow *ui;
private slots:
void addRSU();
void deleteRSU();
};
#endif // MAINWINDOW_H
And my .cpp file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "string"
#include "string.h"
#include "QCheckBox"
#include "QString"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->rsuWidget->hide();
connect(ui->addRSU, SIGNAL(clicked()), ui->rsuWidget, SLOT(show()));
connect(ui->cancelRSU, SIGNAL(clicked()), ui->rsuWidget, SLOT(hide()));
connect(ui->saveRSU, SIGNAL(clicked()), this, SLOT(addRSU()));
}
MainWindow::~MainWindow()
{
delete ui;
delete rsuitem;
}
void MainWindow::addRSU()
{
rsu *baz = new rsu;
baz->id = ui->ID->text().toStdString();
baz->name = ui->Name->text().toStdString();
baz->coorx = ui->CoorX->text().toFloat();
baz->coorx = ui->CoorX->text().toFloat();
baz->ip = ui->IP->text().toStdString();
baz->port = ui->Port->text().toInt();
r.push_back(*baz);
rsuitem = new QListWidgetItem(QString::fromUtf8(baz->name.c_str()),ui->listRSU);
rsuitem->setFlags(rsuitem->flags() | Qt::ItemIsUserCheckable);
rsuitem->setCheckState(Qt::Unchecked);
}
void MainWindow::deleteRSU()
{
}
And my ui:

Related

QT5 Switching between Widgets size problem

I try to switch between two different Widgets in QT5.
The first problem was that my first window was visible in the background of my second window. I solve this with a check in "autoFillBackground". Now i can switch between them, but if i resize them it only resize the Main content.
Both Widgets have a grid layout.
Resize Problem
Im new at QT5, so is there a better way to make a switching between 2 widgets without this problem?
I try it with wMessages = new Messages(); and hide() but then my program crash after going back.
Code:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "messages.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnMessages_clicked();
private:
Ui::MainWindow *ui;
Messages *wMessages;
};
#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);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnMessages_clicked()
{
wMessages = new Messages(this);
wMessages->show();
}
messages.h:
#ifndef MESSAGES_H
#define MESSAGES_H
#include <QWidget>
namespace Ui {
class Messages;
}
class Messages : public QWidget
{
Q_OBJECT
public:
explicit Messages(QWidget *parent = nullptr);
~Messages();
QString NewsGenerator();
private slots:
void on_bBack_clicked();
void on_pushButton_clicked();
private:
Ui::Messages *ui;
};
#endif // MESSAGES_H
messages.cpp:
#include "messages.h"
#include "ui_messages.h"
Messages::Messages(QWidget *parent) :
QWidget(parent),
ui(new Ui::Messages)
{
ui->setupUi(this);
}
Messages::~Messages()
{
delete ui;
}
void Messages::on_bBack_clicked()
{
this->close();
QWidget *parent = this->parentWidget();
parent->show();
}
Edit 1 - working Main Window Button (from G.M.´s answer):
void MainWindow::on_btnMessages_clicked()
{
wPlaner = new Planer();
QMainWindow::setCentralWidget(wPlaner);
}
Update (based on the comments):
The best solution was to use the QStackedWidget to navigate between the views.
Docu: https://doc.qt.io/qt-5/qstackedwidget.html#details
Example-Code for Button:
// return back to first view
void MainWindow::on_btnret_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
}

How to change drag cursor by dragging in Qt?

I have a widget that accepts drop. The object which is dragged in this example can be any pdf or text file. The requirement is when the dragged object goes inside my widget, the cursor should be changed into another form.
I did some search here, and there is a way to do it setDragCursor, but this function is of QDrag. I did not create the dragged widget myself and from dropEnterEvent and dropMoveEvent I don't know how to change the cursor.
DragWidget.h
#ifndef DRAGWIDGET_H
#define DRAGWIDGET_H
#include <QFrame>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
class DragWidget : public QFrame
{
public:
DragWidget(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
};
#endif // DRAGWIDGET_H
DragWidget.cpp
#include "dragwidget.h"
#include <QMimeData>
#include <QDebug>
DragWidget::DragWidget(QWidget *parent) : QFrame(parent)
{
setMinimumSize(300, 300);
setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
setAcceptDrops(true);
}
void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{
const QMimeData *mimeData = event->mimeData();
if ( mimeData->hasText() || mimeData->hasFormat( "application/json" ) )
{
qDebug()<<mimeData->text();
}
}
void DragWidget::dragMoveEvent(QDragMoveEvent *event)
{
event->acceptProposedAction();
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dragwidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
DragWidget *m_dragWidget=nullptr;
};
#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);
m_dragWidget = new DragWidget(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
With the code above, the mouse cursor off course does not change
Do you guys have any idea about this?

How to send variables between classes in Qt

I have a problem. I created two classes in my Qt project. One as the main window, and second as the settings dialog. My idea is to send the values from "Settings" to "MainWindow" (like from one TextEdit to another) but unfortunately, I have no idea how to do it. It's confusing me. I have read similar topics on the internet but none of them gives me a clear answer. Can someone help me understand the way how can I do it via example?
I have no useful code to place it here, so I will put the part of the source code and headers of mine.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
[...]
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "settings.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow()
[...]
private:
Ui::MainWindow *ui;
[...]
};
#endif // MAINWINDOW_H
settings.cpp
#include "settings.h"
#include "ui_settings.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
Settings::Settings(QWidget *parent) :
QDialog(parent),
ui(new Ui::Settings)
{
ui->setupUi(this);
}
settings.h
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QDialog>
namespace Ui {
class Settings;
}
class Settings : public QDialog
{
Q_OBJECT
public:
explicit Settings(QWidget *parent = nullptr);
~Settings();
[...]
private:
Ui::Settings *ui;
[...]
};
#endif // SETTINGS_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Use signals/slots mechanism to share values between two QObject.
For example:
The following code allows yout to send the value in a QLineEdit to another widget by clicking on a button:
class Widget1: public QWidget
{
Q_OBJECT
public:
Widget1(): QWidget(),
message(new QLineEdit())
{
QPushButton* button = new QPushButton("Send msg", this);
connect(button, &QPushButton::clicked, this, [=]() { emit this->sendMsg(message->text());}); // When you click on the button, it will emit the signal sendMsg
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(message);
layout->addWidget(button);
}
private:
QLineEdit* message;
signals:
void sendMsg(QString const& msg);
};
class Widget2: public QWidget
{
Q_OBJECT
public:
Widget2(): QWidget(),
display(new QLabel("Nothing to display", this))
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(display);
}
private:
QLabel* display;
public slots:
void receive(QString const& message)
{
display->setText(message); // When called, display the message in the label
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget* mainWidget = new QWidget();
QHBoxLayout* layout = new QHBoxLayout(mainWidget);
Widget1* w1 = new Widget1();
Widget2* w2 = new Widget2();
layout->addWidget(w1);
layout->addWidget(w2);
// When the signal sendMsg is emitted, call the slot receive
QObject::connect(w1, &Widget1::sendMsg, w2, &Widget2::receive);
mainWidget->show();
return app.exec();
}
There are multiple ways to achieve this.
For example you can provide the public Getter Methods in your dialog for provide value to the public and use them directly in the MainWindow to read those.
Or you can use Signals/Slots as stated above.
One example with Signal/Slots:
The SettingsWindow emits textEdit(QString) signal if Dialog Accepted, and MainWindow receives this signal via on_textEdit(QString) slot and writes it to its own text field:
SettingsWindow reading text input and emitting signal textEdit(QString):
MainWindow receiving signal via slot on_textEdit(QString):
And this is the code:
maindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_textEdited(QString txt);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"
#include <memory>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
auto dlg = new SettingsDialog{this};
connect(dlg, &SettingsDialog::textEdit, this, &MainWindow::on_textEdited);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
}
void MainWindow::on_textEdited(QString txt)
{
ui->textEdit->setText(txt);
}
settingsdialog.h
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QDialog>
namespace Ui {
class SettingsDialog;
}
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog();
signals:
void textEdit(QString txt);
private slots:
void on_buttonBox_accepted();
private:
Ui::SettingsDialog *ui;
};
#endif // SETTINGSDIALOG_H
settingsdialog.cpp
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
SettingsDialog::SettingsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
}
SettingsDialog::~SettingsDialog()
{
delete ui;
}
void SettingsDialog::on_buttonBox_accepted()
{
emit textEdit(ui->textEdit->toPlainText());
}
More about Signal/Slots

Example SLOT/SIGNAL between two object QT

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.

Application crashing after calling a method

I want to return a QString value from a function that exists in class called DB in my MainWindow class, but it always crashes the application.
db.h
#ifndef DB_H
#define DB_H
#include <QMainWindow>
#include <QtSQl>
#include <QSqlQuery>
#include <QSqlError>
#include <QObject>
#include <QDialog>
class DB : public QMainWindow
{
Q_OBJECT
public:
explicit DB(QWidget *parent = 0);
QString getDriver() const;
void setDriver(const QString &value);
private:
QString Driver="test";
signals:
public slots:
};
#endif // DB_H
and this is db.cpp
#include "db.h"
DB::DB(QWidget *parent) : QMainWindow(parent)
{
}
QString DB::getDriver() const
{
return Driver;
}
void DB::setDriver(const QString &value)
{
Driver = value;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QFileInfo>
#include <QDialog>
#include <QObject>
#include "Db.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
DB *conn;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QString driverfromdb = conn->getDriver();
qDebug() << driverfromdb;
}
And this what happen when I click the pushbutton: image
You are declaring a pointer to DB class inside your MainWindow class
DB *conn;
but you never initialize it. At the moment it does not point to anything, so if you try to access it:
QString driverfromdb = conn->getDriver(); // boom, conn is somewhere in the void
The solution is simple, you need to create a DB object before using it, e.g.:
void MainWindow::on_pushButton_clicked()
{
conn = new DB();
QString driverfromdb = conn->getDriver();
qDebug() << driverfromdb;
}
or just let conn be a typical variable, not an pointer:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
DB conn; // conn is created after creating MainWindow object
This way you have not to initialize anything and you will avoid crashes.
or:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), conn(new DB),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete conn;
delete ui;
}