I try to let a QLabel show images like a video.
I want this display my images from f0000.png to f0039.png slowly so I can see progress.
For some reason my for loop starts with 50.
When I see the program run it only show one image or it change too fast I can't see the progress.
How to fix it let it show images like video.
you can use a Qtimer and set the speed as faster as you need
header:
#include <QMainWindow>
#include <QTimer>
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
public slots:
void updateLabel();
private:
Ui::MainWindow *ui;
QTimer* _timer;
int index{0};
QString pixResource{};
};
and impl.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
_timer = new QTimer(parent);
connect(_timer, SIGNAL(timeout()), this, SLOT(updateLabel()));
_timer->start(1000);
}
MainWindow::~MainWindow()
{
delete ui;
_timer->stop();
delete _timer;
}
void MainWindow::updateLabel()
{
if (index >= 10)
{
index = 0;
}
qDebug() << "index: " << index;
pixResource = "res/foo/image/" + QString::number(index) + ".png";
qDebug() << "now the res: " << pixResource;
index++;
}
Related
I want to insert a QComboBox inside a QTableWidget. When I change the Index of the CB I'll call a methode to change the status in the sqlite table. But for this, I need do pass two parameters to the methode. The ID(First element of the row), and the current index of the CB.
I generate the QTableWidget like that:
...
for(int i = 0; i < dbModel->rowCount();i++){
row = dbModel->record(i);
ui->tW_Services->setItem(i,0,new QTableWidgetItem(row.field(0).value().toString()));
ui->tW_Services->setItem(i,1,new QTableWidgetItem(row.field(1).value().toString()));
ui->tW_Services->setItem(i,2,new QTableWidgetItem(row.field(2).value().toString()));
ui->tW_Services->setItem(i,3,new QTableWidgetItem(row.field(3).value().toString()));
ui->tW_Services->setItem(i,4,new QTableWidgetItem(row.field(4).value().toString() + "€"));
ui->tW_Services->setItem(i,5,new QTableWidgetItem(row.field(5).value().toString() + "€"));
//ui->tW_Services->setItem(i,6,new QTableWidgetItem(row.field(6).value().toString()));
QComboBox* combo = new QComboBox();
combo->addItem("open");
combo->addItem("paid");
if(row.field(6).value().toString() != "paid") combo->setCurrentIndex(0);
else combo->setCurrentIndex(1);
connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboChanged(int)));
ui->tW_Services->setCellWidget(i,6,combo);
}
...
and the slot looks like that:
void MainWindow::onComboChanged(int ID)
{
qDebug() << "ID:" << QString::number(ID);
}
But when I try to create the method with 2 args:
void MainWindow::onComboChanged(int ID,int index)
{
qDebug() << "ID:" << QString::number(ID);
}
and attach a second parameter and calling the slot like:
connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboChanged(row.field(0).value().toInt(),int)));
I get:
qt.core.qobject.connect: QObject::connect: No such slot MainWindow::onComboChanged(row.field(0).value().toInt(),int)
A minimal reproducible example:
There's just a single pushbutton and a qtablewidget
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();
private slots:
void on_pushButton_clicked();
void onComboChanged(int ID, int index);
void onComboChanged2(int index);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QComboBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->tableWidget->setColumnCount(4);
ui->tableWidget->setRowCount(3);
for(int i = 0; i < 3;i++){
ui->tableWidget->setItem(i,0,new QTableWidgetItem(QString::number(i)));
ui->tableWidget->setItem(i,1,new QTableWidgetItem("Test"));
ui->tableWidget->setItem(i,2,new QTableWidgetItem("Test 2"));
QComboBox* combo = new QComboBox();
combo->addItem("open");
combo->addItem("paid");
combo->setCurrentIndex(0);
int j = i+1;
//NOT WORKING
//connect(combo, SIGNAL(currentIndexChanged(int)),this,
// [=](int index) {this->onComboChanged(j, index);});
//WORKING
//connect(combo, SIGNAL(currentIndexChanged(int)),SLOT(onComboChanged2(int)));
ui->tableWidget->setCellWidget(i,3,combo);
}
}
void MainWindow::onComboChanged(int ID, int index)
{
qDebug() << "ID: " << ID << "index: "<< index;
}
void MainWindow::onComboChanged2(int index)
{
qDebug() << "ID: " << index;
}
Since currentIndexChanged only has one parameter, your slot cannot capture more than that. But, since the row ID does not change on emission, you can wrap onComboChanged into a lambda as shown here, which captures the row by copy:
connect(combo, &QComboBox::currentIndexChanged,
this, [=](int index) {this->onComboChanged(i, index);});
Since your code is not a minimal reproducible example, I could not test this. Let me know, if it doesn't work.
I am quite new to programming, so hopefully someone can help me out. After calculating a value with a function and storing it into the variable with a setter, I want to call it in my viswindow.cpp to visualize it in a Graph. In the mainwindow the right value is calculated and stored by pressing a button, which also opens the viswindow. I tried to pass it with a pointer or with signals and slots, but it wouldn't work.
mainwindow.cpp:
double MainWindow::berechneFussabdruck(double strecke, int anzahl, double sfcWert)
{
if(strecke <= 1500 && strecke > 0){
double aequivalente_Co2 = (((sfcWert*3.116*50*(((0.0011235955)*(strecke-2*48.42))+0.233))*0.001)/anzahl);
setAequivalente(aequivalente_Co2);
}
else{
double aequivalente_Co2 = (((sfcWert*3.116*75*(((0.0011235955)*(strecke-2*208))+0.833))*0.001)/anzahl);
setAequivalente(aequivalente_Co2);
}
return aequivalente_Co2;
}
Button to open viswindow:
void MainWindow::on_pushButton_clicked()
{
MainWindow::berechneFussabdruck(strecke, anzahl, sfcWert);
visWindow = new VisWindow(this);
visWindow->show();
}
viswindow.cpp:
VisWindow::VisWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::VisWindow)
{
ui->setupUi(this);
...
*set0 << aequivalente_Co2 << aequivalente_Co2;
*set1 << 11.07 << 0;
*set2 << 0 << 0.49;
...
}
Thanks for helping!
Here are examples of:
Single time value transfer from MainWindow to VisWindow in constructor parameter.
Value update from MainWindow to VisWindow by slot-signal chain.
Value update from MainWindow to VisWindow by direct call of VisWindow->updateValue() slot as regular function.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "viswindow.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_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
signals:
void updatevalue(const double value);
private:
Ui::MainWindow *ui;
VisWindow * m_viswindow;
};
#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_pushButton_clicked() {
m_viswindow = new VisWindow(12.34, nullptr);
connect(this, &MainWindow::updatevalue,
m_viswindow, &VisWindow::updateValue);
m_viswindow->show();
}
void MainWindow::on_pushButton_2_clicked() {
emit updatevalue(23.45);
}
void MainWindow::on_pushButton_3_clicked() {
m_viswindow->updateValue(45.67);
}
viswindow.h
#ifndef VISWINDOW_H
#define VISWINDOW_H
#include <QWidget>
namespace Ui {
class VisWindow;
}
class VisWindow : public QWidget
{
Q_OBJECT
public:
explicit VisWindow(const double value, QWidget *parent = nullptr);
~VisWindow();
public slots:
void updateValue(const double value);
private:
Ui::VisWindow *ui;
};
#endif // VISWINDOW_H
viswindow.cpp
#include "viswindow.h"
#include "ui_viswindow.h"
VisWindow::VisWindow(const double value, QWidget *parent) :
QWidget(parent),
ui(new Ui::VisWindow)
{
ui->setupUi(this);
ui->lblValue->setText(QString::number(value,'f',2));
this->setWindowTitle("VisWindow");
}
VisWindow::~VisWindow() {
delete ui;
}
void VisWindow::updateValue(const double value) {
ui->lblValue->setText(QString::number(value,'f',2));
}
My programm can add new QLabels and QLineEdits to a QScrollArea after a button is clicked. The idea is to create a grocery list. My problem is when a second Button is clicked I want to get the text of all the QLineEdits. But I don't know how to use those elements, because every new QLineEdit-variable has the same name and I don't know how to change that.
Below is a small example:
my MainWindow.h:
#ifndef MainWINDOW_H
#define MainWINDOW_H
#include <QMainWindow>
#include <string>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
int i;
private:
Ui::MainWindow *ui;
private slots:
void on_create_clicked();
read_text();
};
#endif // MainWINDOW_H
my MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(on_create_clicked()));
connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(read_text()));
i = 1;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_create_clicked()
{
if(i < 10)
{
i ++;
QLabel *label_2 = new QLabel();
QString s = QString::number(zaehlerHeight) + ". ";
label_2->setText(s);
ui->scrollArea->widget()->layout()->addWidget(label_2);
QLineEdit *lineEdit = new QLineEdit();
ui->scrollArea_2->widget()->layout()->addWidget(lineEdit);
}
else{
ui->label->setText("already 10");
}
}
void MainWindow::read_text()
{
QString mytext = ui->lineEdit->text();
}
I would simply store the pointer to each QLineEdit in a QVector, and then loop in this vector to get the text of each.
Header:
#ifndef MainWINDOW_H
#define MainWINDOW_H
#include <QMainWindow>
#include <string>
#include <QVector>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
int i;
private:
Ui::MainWindow *ui;
QVector<QLineEdit *> m_VecLineEdits;
private slots:
void on_create_clicked();
private:
void read_text();
void GetAllTextEdit();
};
#endif // MainWINDOW_H
In Cpp file, change the following:
void MainWindow::on_create_clicked()
{
if(i < 10)
{
i ++;
QLabel *label_2 = new QLabel();
QString s = QString::number(zaehlerHeight) + ". ";
label_2->setText(s);
ui->scrollArea->widget()->layout()->addWidget(label_2);
QLineEdit *lineEdit = new QLineEdit();
m_VecLineEdits.push_back(lineEdit); // <-- Line added here to save the pointers in a QVector.
ui->scrollArea_2->widget()->layout()->addWidget(lineEdit);
}
else{
ui->label->setText("already 10");
}
}
void MainWindow::GetAllTextEdit()
{
for(int j = 0; j<m_VecLineEdits.size(); ++j)
{
QString lineEditText = m_VecLineEdits.at(j)->text();
/* Do anything with this value */
}
}
If you delete your QLineEdit, remember to also remove them from the QVector.
If you want to change the name of the variable ( ie the pointer to the QLineEdit ) each time you slot is called, and provided that i will stay small ( < 10 ), you can use switch(i) for example and choose a different variable name for each case, but you will have to store all those variables as members of your class. So it's better to store the pointers in a QList or a QVector and loop over those containers to access the text() method on each QLineEdit.
you can't, because you don't have any pointer or reference to those objects, one solution would be having a array of QLabel in your class definition.
ex:
QVector<QLabel*> _labels;
and adding and instantiating one by one with the press of the button and then you will have the whole list of objects, thus their names
I have a mainwindow that generates random int numbers every second in "numbers" and I have a button that opens a new dialog. In that dialog is a button "Get Number" and a qlabel. If I press "Get Number" I want the current generated number from the mainwindow set to the dialog label text. I tried to write a member function in the mainwindow class that returns the actual value but I cant call it from the dialog and I think that's the wrong way. How can I get this current generated int "numbers" into the dialog? My plain code:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void generateNumbers();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
#include <QTimer>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QTimer *timer = new QTimer(this);
connect(timer,SIGNAL(timeout()), this, SLOT(generateNumbers()));
timer->start(1000);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
Dialog dialog;
dialog.setModal(true);
dialog.exec();
}
void MainWindow::generateNumbers()
{
int numbers = qrand() % 100;
qDebug() << numbers;
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
On mainwindow.h, add a signal:
signals:
void update_number(int);
On mainwindow.cpp, emit that signal everytime you generate a new number:
void MainWindow::generateNumbers()
{
int numbers = qrand() % 100;
emit update_number(numbers); // signals that a new number has been generated
qDebug() << numbers;
}
and your on_pushButton_clicked() should look like this:
void MainWindow::on_pushButton_clicked()
{
Dialog dialog(this); // main window as the parent of dialog
dialog.setModal(true);
dialog.exec();
}
On dialog.h, add an attribute called number_ and add the following slot:
public slots:
void on_update_number(int number); // updates the number_
private:
int number_; // it will be updated with the most recent number
Ui::Dialog *ui;
On dialog.cpp, connect the signal to the slot:
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(parent, SIGNAL(update_number(int)), this, SLOT(on_update_number(int)));
}
add the slot code:
void Dialog::on_update_number(int number)
{
number_ = number;
}
Finally, when the user clicks the button "Get Number" in the dialog, set the label text:
void Dialog::on_pushButton_clicked()
{
ui->label->setText(QString::number(number_));
}
For more information on Signals & Slots go here.
I have an mainwindow app, with 3 main modules and each modules have 6 sub-modules. Each submodel consists of different kind of Gui widgets (like Qlineedit, Qlabel, QPushbutton,QGroupBox etc…).
I would subclass all each main and sub-modules (inheriths QWidget). Each main and sub module is created dynamically. For ex, when the 1st main module is constructed, it also allocates for the 6 submodules. But, when the app is closed, it doesn’t free all 6 submodules. There may be a leakage problem but I didn’t figure out. why. I think I have a problem with subclassing of my modules.
My app is too big to post here so I would post 2 benchmark codes. To show the issue, this mainwindow app has 100 my custom QLineEdit object (I know it is weird but it adresses my problem well). But when the app is closed, doesn’t free all the 100 custom Qlineedit objects. (Here, my custom QLineedit class represents my modules…)
I have tried 2 kind of subclassing to understand the problem. 1. BcInputBox inherits QLineEdit 2. BcInputBox inherits QWidget
I’ve tried both of them separately but the issue is the same. I’ve spent more than 1 week but I haven’t figured it out yet.
Which approach would be better? What is the mistake about my design?
1st Benchmark
// #####################################################
// Benchmark 1 //
// #####################################################
//
//BcInputBox.h
#ifndef BCINPUTBOX_H
#define BBCINPUTBOX_H
#include <QLineEdit>
namespace BC {
const bool ReadOnly = true;
const bool Edit = false;
const bool Double = true;
const bool Name = false;
}
class BcInputBox: public QWidget
{
Q_OBJECT
public:
explicit BcInputBox(QWidget *parent = 0, bool editInfo = BC::Edit, bool inputInfo = BC::Double);
~BcInputBox();
void setEditInfo(bool editInfo);
void setInputInfo(bool inputInfo);
QLineEdit *getInputBox() const;
static int objCounter;
private:
QLineEdit *inputBox;
};
#endif // BCINPUTBOX_H
//******************************************
//BcInputBox.cpp
#include <QDebug>
#include <QHBoxLayout>
#include <QValidator>
#include "BcInputBox.h"
#include "BcDoubleValidator.h"
int BcInputBox :: objCounter = 0;
BcInputBox::BcInputBox(QWidget *parent, bool editInfo, bool inputInfo):QWidget(parent)
{
QHBoxLayout *hlay = new QHBoxLayout(this);
inputBox = new QLineEdit(this);
setEditInfo(editInfo);
setInputInfo(inputInfo);
hlay -> addWidget(inputBox);
inputBox -> setStyleSheet("background-color: yellow;"
"border-radius: 8px;");
qDebug() << objCounter++ << "BcInputBox()";
}
BcInputBox :: ~BcInputBox()
{
//qDebug() << objCounter ;
qDebug() << "~BcInputBox";
delete inputBox;
}
void BcInputBox :: setEditInfo(bool editInfo)
{
inputBox -> setReadOnly(editInfo);
}
void BcInputBox :: setInputInfo(bool inputInfo)
{
if (!inputInfo){
QRegExp rExp ("[A-Za-z0-9]{1,16}");
inputBox -> setValidator(new QRegExpValidator(rExp, inputBox));
}
else {
inputBox -> setValidator( new BcDoubleValidator( 0.0, 1000, 3,inputBox));
}
}
QLineEdit *BcInputBox :: getInputBox() const
{
return inputBox;
}
//******************************************
//MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLineEdit>
#include "subconsmod1.h"
#include "BcInputBox.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
BcInputBox *subSection[100];
};
#endif // MAINWINDOW_H
//******************************************
//MainWindow.cpp
#include <QtCore>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout *hlay = new QVBoxLayout(ui->centralWidget);
for (int i = 0; i < 100; ++i ){
subSection[i] = new BcInputBox (ui->centralWidget);
hlay -> addWidget(subSection[i]);}
ui->centralWidget ->setLayout(hlay);
}
MainWindow::~MainWindow()
{
delete ui;
}
2nd Benchmark
// #####################################################
// Benchmark 2 //
// #####################################################
//
//BcInput.h
#ifndef BCINPUT_H
#define BCINPUT_H
#include <QLineEdit>
class BcInput : public QLineEdit
{
Q_OBJECT
public:
explicit BcInput(QWidget *parent = 0);
~BcInput();
static int counter;
signals:
public slots:
};
#endif // BCINPUT_H
//******************************************
//BcInput.cpp
#include <QDebug>
#include "bcinput.h"
int BcInput :: counter = 0;
BcInput::BcInput(QWidget *parent) :
QLineEdit(parent)
{
qDebug() << "BcInput()";
qDebug() << counter++;
}
BcInput :: ~BcInput()
{
qDebug() << "~BcInput()";
}
//******************************************
//MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "bcinput.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
BcInput *subSection[100];
};
#endif // MAINWINDOW_H
//******************************************
//MainWindow.cpp
#include <QtGui>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "bcinput.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout *hlay = new QVBoxLayout(ui->centralWidget);
for(int i = 0; i<100;i++){
subSection[i] = new BcInput(ui->centralWidget);
hlay->addWidget(subSection[i]);}
ui->centralWidget->setLayout(hlay);
}
MainWindow::~MainWindow()
{
for(int i = 0; i<100;i++)
delete subSection[i];
delete ui;
}