Qtest access to ui member - c++

I need to simulate mouse click on UI button using QTest but I can't figure out how to access it.
I've got a MediaPanel class :
class PhMediaPanel : public QWidget
{
Q_OBJECT
public:
explicit PhMediaPanel(QWidget *parent = 0);
//... a lot of functions
private:
Ui::PhMediaPanel *ui;
};
And a MediaPanelTest :
#include "MediaPanelTest.h"
#include <QObject>
class MediaPanelTest : public QObject
{
Q_OBJECT
public:
explicit MediaPanelTest(QObject *parent = 0);
private slots:
//The tests
};
So how can I simulate button click on Ui::PhMediaPanel *ui member?

Try the following approach:
BUTTONCLASS* button = WIDGET->findChild<BUTTONCLASS*>("name of the button");
As far is i know this should give you the widget without exposing the UI pointer.

Related

QWidget "access violation" exeption

A have a class, inherited from QWidget and Ui_Form (automaticaly generated class, appears when you create a .ui in Qt). It looks like
class MyClass: public QWidget, public Ui_Form {}
Ui_Form has some members, which connected with relevant widgets in the .ui file (for example, QLineEdits, QButtons, etc).
class Ui_Form {
public:
QLineEdit *fileNameEdit;
void setupUi(QWidget *Form) {
fileNameEdit = new QLineEdit(layoutWidget);
fileNameEdit->setObjectName(QStringLiteral("fileNameEdit"));
}
}
As MyClass is inherited from Ui_Form, I can use this membes. But, when I try to do something, I have an exeption "Access violation reading location". For example:
fileNameEdit->setText("String");
Can somebody give an advice?
The way you are incorporating the Ui_Form part is not how Qt proposes it by default. If you look into this button example you can see how the ui part is incorporated diferently:
Header file
#ifndef BUTTON_H
#define BUTTON_H
#include <QWidget>
namespace Ui {
class Button;
}
class Button : public QWidget
{
Q_OBJECT
public:
explicit Button(int n, QWidget *parent = 0);
~Button();
private slots:
void removeRequested();
signals:
void remove(Button* button);
private:
Ui::Button *ui;
};
#endif // BUTTON_H
CPP code
#include "button.h"
#include "ui_button.h"
Button::Button(int n, QWidget *parent) :
QWidget(parent),
ui(new Ui::Button)
{
ui->setupUi(this);
ui->pushButton->setText("Remove button "+QString::number(n));
addAction(ui->actionRemove);
connect(ui->actionRemove,SIGNAL(triggered()),this,SLOT(removeRequested()));
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(removeRequested()));
}
Button::~Button()
{
delete ui;
}
void Button::removeRequested()
{
emit remove(this);
}
The main difference is that I believe you are not calling Ui_From::setupUi function. It is clear to me that you do not need to follow the Qt suggested template (incorporating the ui as a class member rather than inheriting from it), however, it is much clearer from my point of view if you follow the Qt suggestions.

How to use the creating class` methods from the created class?

I have a question:
I have a class userinterface that has a class MoveSeries. From MoveSeries I want to have access to the methods of my class userinterface. In this example I want to have access to the method get_MoveCurve_Delta() of userinterface. How do I get access to the creating class (userinterface) from the created class (MoveSeries ? I tried the Signal-Slot-Approach but since I have to use several methods of userinterface several times this makes lots of signal-slots...
here is my code:
Userinterface.h:
class UserInterface : public QMainWindow
{
Q_OBJECT
public:
UserInterface(QWidget *parent = 0, Qt::WFlags flags = 0);
~UserInterface();
...
private:
double MoveCurve_Delta;
MoveSeries *MOVE_SERIES ;
public:
void set_MoveCurve_Delta( double val) { MoveCurve_Delta = val;}
double get_MoveCurve_Delta() { return MoveCurve_Delta ;}
}
Userinterface.cpp:
UserInterface::UserInterface(QWidget *parent, Qt::WFlags flags) :
QMainWindow(parent, flags)
{
ui.setupUi(this);
...
MOVE_SERIES = new MoveSeries( this);
}
MoveSeries.h:
class MoveSeries : public QDialog
{
Q_OBJECT
public:
explicit MoveSeries(QWidget *parent = 0);
~MoveSeries();
...
MoveSeries.cpp:
MoveSeries::MoveSeries(QWidget *parent) :
QDialog(parent),ui(new Ui::MoveSeries)
{
ui->setupUi(this);
this->parent = parent;
parent->set-MoveSeries_Delta_Val();
}
Rather than assume that the parent QWidget in MoveSeries is UserInterface, you can also require that it is.
MoveSeries.h:
class UserInterface; // only need a forward declaration
class MoveSeries : public QDialog
{
Q_OBJECT
public:
explicit MoveSeries(UserInterface *parent = 0);
~MoveSeries();
...
UserInterface * uiparent;
}
MoveSeries.cpp:
#include "Userinterface.h" // include the header where it is required
MoveSeries::MoveSeries(UserInterface *parent) :
QDialog(parent), ui(new Ui::MoveSeries), uiparent(parent)
{
ui->setupUi(this);
uiparent->set-MoveSeries_Delta_Val();
}
It looks like you want to cast the parent to the class you want:
static_cast<UserInterface *>(parent)->get_MoveCurve_Delta();
Bear in mind that this could be dangerous as it makes an assumption about the type of the parent.
If you want only UserInterface be the parent of MoveSeries, say so:
explicit MoveSeries(UserInterface *parent = 0);
If you want any widget to be able to act as the parent, you cannot access UserInterface methods because the parent does not necessarily have them.

QT extend MainWindow to other class or diffrent way

I have class printrectangle
class PrintRectangle : public QWidget
{
Q_OBJECT
public:
explicit PrintRectangle(QWidget *parent = 0);
private:
void resetClickedIndex();
void updateIndexFromPoint( const QPoint& point);
public:
int mXIndex;
int mYIndex;
QVector<QPoint> points;
bool clicked[5][5] = {};
teacher tech;
perceptron p[5][5];
double techconst = 0.1;
signals:
public slots:
protected:
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *eventPress);
};
and MainWindow
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_learn_clicked();
void on_classify_clicked();
private:
Ui::MainWindow *ui;
};
When I click button I call to on_learn_clicked() function. I would like to transfer clicked[5][5] array into on_learn_clicked becasue I send this array to other object when user click button. How to do this?
It is not clear what is exactly the relation between MainWindow and the PrintRectangle widget. I suppose the button signal and PrintRectangle slot are connected somewhere in the MainWindow implementation.
One way to solve the problem would be to use to use the QSignalMapper as #Noidea stated.
Another way would be to use a lambda as a slot when connecting. This way you could capture the sender/receiver or other objects in scope and use their members.
You can find some information about the connect syntax in New Signal Slot Syntax
But basically you could write something like:
connect(button, &QPushButton::clicked, this, [this, printRectangle]()
{
// do smth with clicked[5][5] from printRectangle or just
// retrieve it and call another method like:
// this->processClicked(printRectangle->clicked);
// or pass it to another object
}
This way you could modify your on_classify_clicked slot to a regular method with bool[5][5] argument to do the processing.

QT program crashes after connect()

I'm trying to write my new app, but it crashes every time I press a button on QDialog.
Here's my code :
mainwindow.h
#include <QMainWindow>
#include "creatlist.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QDialog* creatList;
public slots:
void tableFull(){
...some code here...
}
private:
Ui::MainWindow *ui;
};
creatlist.h :
#include <QDialog>
#include "mainwindow.h"
namespace Ui {
class creatlist;
}
class MainWindow;
class creatlist : public QDialog
{
Q_OBJECT
public:
explicit creatlist(QWidget *parent = 0);
~creatlist();
MainWindow* mainwindow;
signals:
void updateList();
public slots:
void ready(){
///////////////////////////////////////////////////////////crash
connect(this,SIGNAL(updateList()),mainwindow,SLOT(tableFull()));
emit updateList();
}
private:
Ui::creatlist *ui;
};
If i try to send some signals my app crashes with a Segmentation Fault.
I did:
void creatlist::ready()
{
mainwindow = new MainWindow(this);
emit mainwindow->linktableFull();
}
but if I try to do QTextBroser.append("hue hue"); in linktableFull(), QTextBrowser is always empty.
Your QTextBrowser always empty because you create new mainwindow object in every ready() function. You should create mainwindow object once and use same mainwindow object throughout code. You can create new mainwindow object in creatlist constructor.

connect signals on a child widget slot

I have some problems with inheritance in widgets and connecting slots. I have created an abstract Widget which inherits from QWidget. Here is the prototype :
class WidgetParams : public QWidget
{
Q_OBJECT
public:
explicit WidgetParams(QWidget *parent = 0) : QWidget(parent){}
virtual bool paramChanged() = 0;
protected:
bool paramsChanged;
};
Then I created derivated class from WidgetParams, for example WidgetParamsWindows:
class WidgetParamsWindows : public WidgetParams
{
public:
explicit WidgetParamsWindows(QWidget *parent = 0);
virtual bool paramChanged(){return paramsChanged;}
private:
QFormLayout *layout;
QSpinBox *svertical;
QSpinBox *shorizontal;
signals:
public slots:
void changeSomeParam(int value);
};
In WidgetParamsWindows, I have some QSpinBox, QPushButton etc. to adjust the params.
I connect the QSpinBox in WidetParamsWindows like this :
connect(spinbox,SIGNAL(valueChanged(int)),this,SLOT(changeSomeParam(int));
After that, I created a WidgetParamsWindows and put It in a list of WidgetParams, in order to show the correct WidgetParams when the user clicks on it.
But when I tried to change the value in the QSpinBox, nothing change and I have the following message in the console :
QObject::connect: No such slot WidgetParams::changeSomeParam(int)
I don't know why the parent Widget takes the slot, instead of WidgetParamsWindows, do you have any ideas?
There is no Q_OBJECT macro in WidgetParamsWindow, so moc doesn't resolve slot macros, try to add Q_OBJECT in WidgetParamsWindow