UI doesn' t update in qt app - c++

In the code above uitablewidget does not update using signal and slot.
It seems as if (ui->tableWidget->setItem(0,0,newItemx);) doesn't work.
Am I doing something wrong or is there a better way to update my qtablewidget from my class B?
Class_A::Class_A(QWidget *parent):QDialog(parent),ui(new Ui::Class_A)
{
ui->setupUi(this);
}
Class_A::~Class_A()
{
delete ui;
}
void Class_A::change_TableWidget(double x,double y) // this is the public slot
{
QTableWidgetItem *newItemx = new QTableWidgetItem(QString::number(x));
ui->tableWidget->setItem(0,0,newItemx);
QTableWidgetItem *newItemy = new QTableWidgetItem(QString::number(y));
ui->tableWidget->setItem(0,0,newItemy);
}
Class_B::Class_B(QWidget *parent) :
QGLWidget(parent)
{
Class_A *t=new Class_A;
connect(this,SIGNAL(mySignal(double,double)),t,SLOT(change_TableWidget(double,double)));
}
void Class_B::mousePressEvent(QMouseEvent *event)
{
double x = event->x();
double y = event->y();
emit mySignal(x,y);
}

You don't have a SLOT(change_TableWidget(double,double)) - yours takes 3 doubles, not two.
You should check that connect() returned true. I like to write
if (!connect(....)) Q_ASSERT(false);
or if (!connect(....)) Q_ASSERT(!"connect");
Also, connect prints out messages to the debug output when it fails to match the signals and slots. You should look for that output.
(Or use the new Qt 5 connect(), which is all checked at compile time.)

Related

how to recognize which signal emitted in slot?

I connect two signals to same slot. like this:
check = new QCheckBox();
connect(check, SIGNAL(clicked()), this, SLOT(MySlot()));
connect(check, SIGNAL(toggled(bool)),this,SLOT(MySlot()));
I don't want to define an other slot. In MySlot is it possible to recognize which signal callbacks the slot?
How can I do this?
You might be able to use the QMetaObject/QMetaMethod data associated with the sender to get what you want (untested)...
void MyClass::MySlot ()
{
auto index = senderSignalIndex();
if (index == sender()->indexOfSignal("clicked()")) {
/*
* Got here as the result of a clicked() signal.
*/
} else if (index == sender()->indexOfSignal("toggled(bool)")) {
/*
* Got here as the result of a toggled(bool) signal.
*/
}
}
Rather than that, however, if you're using Qt5 I would suggest making use of the new signal/slot syntax along with lambdas...
check = new QCheckBox();
connect(check, &QCheckBox::clicked,
[this]()
{
MySlot(false);
});
connect(check, &QCheckBox::toggled,
[this](bool toggled)
{
MySlot(true, toggled);
});
Along with a change to the signature of MySlot...
/**
* #param from_toggled_signal If true this call was triggered by a
* QCheckBox::toggled signal, otherwise it's
* the result of a QCheckBox::clicked signal.
*
* #param toggle_value If from_toggled_signal is true then this was the
* value passed to QCheckBox::toggled, otherwise unused.
*/
void MyClass::MySlot (bool from_toggled_signal, bool toggle_value = false)
{
.
.
.
}
New slots can be defined on the fly using lambdas :)
class MyClass : public QWidget {
QSomeLayout m_layout{this};
QCheckBox m_check;
enum Signal { Clicked, Toggled };
Q_SLOT void mySlot(Signal);
public:
MyClass( ... ) : ... {
m_layout.addWidget(&m_check);
connect(&m_check, &QCheckBox::clicked, this, [this]{ mySlot(Clicked); });
connect(&m_check, &QCheckBox::toggled, this, [this]{ mySlot(Toggled); });
}
};
You can also add your own context to the signal if that helps. For instance I had a service that downloaded user avatars for multiple windows. I needed the window to only load the user it was interested in something so I would pass in the user's id as the context. Something like:
void UserService::downloadAvatar(const QString& url, const int context = 0) {
...// Make the http request, on finished:
emit onAvatarDownloaded(context, responseBody);
}

Stop slots from being executed

In Qt, I can emit a signal, to which I have multiple slots connected, where in the case of direct connections, the connected slots are called on after another.
Let void mySignal(int x) be the signal of the class MyClass.
Depending on the value of x I want to perform a different action, and under the assumption, I want to do exactly one action, I can connect a slot, with a switch-case construct to execute the relevant action.
This implies that I need to know beforehand what kind of values I can get, and what the actions are.
I can also connect a slot for each of my actions, and guard the execution by a if clause. Now I can just connect whatever I want, whenever I want it. But under the assumption that I want to do exactly one action, it would be performance-wise beneficial if I could stop further execution of the slots, when I found the 'match'.
[...]
QObject::connect(this, &MyClass::mySignal, this, [this](int x) {
if (x == 0) {
qDebug() << x; // Stop it now!;
}
});
QObject::connect(this, &MyClass::mySignal, this, [this](int x) {
if (x == 4) {
qDebug() << x; // Stop it now!;
}
});
QObject::connect(this, &MyClass::mySignal, this, [this](int x) {
if (x == 109) {
qDebug() << x; // Stop it now!;
}
});
Is there a way, to tell the signal, to not execute anymore slots, until the signal is emitted again?
One way to do something like this, (ab) using the Qt framework would use the QEvent-system.
The signal handler won't do more, than translating the signal in an QEvent. Instead of all the separate slots, install eventFilter. If the eventFilter accepts the event, return true to stop the propagation to other (filter)objects.
The code is just a quick and dirty test and has no security precautions. It might easily crash hard.
// testevent.h
#ifndef TESTEVENT_H
#define TESTEVENT_H
#include <QObject>
#include <QEvent>
class TestEvent: public QEvent
{
int m_x;
public:
TestEvent(int x = 0);
int x() { return m_x; }
};
class TestEventFilter: public QObject
{
Q_OBJECT
int m_fx;
public:
TestEventFilter(int fx, QObject* parent = nullptr);
bool eventFilter(QObject* obj, QEvent* event) Q_DECL_OVERRIDE;
};
Q_DECLARE_METATYPE(TestEvent)
#endif // TESTEVENT_H
// testevent.cpp
#include "testevent.h"
#include <QDebug>
TestEvent::TestEvent(int x)
: QEvent(QEvent::User)
, m_x(x)
{
}
TestEventFilter::TestEventFilter(int fx, QObject *parent)
: QObject(parent)
, m_fx(fx)
{
}
bool TestEventFilter::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj);
TestEvent* e = static_cast<TestEvent*>(event);
qDebug() << "EventFilter for" << m_fx << "got" << e;
if (e->x() == m_fx) {
qDebug() << "accept that event!";
event->accept();
return true;
}
event->ignore();
return false;
}
// run
QObject o;
TestEventFilter* f1 = new TestEventFilter(10);
TestEventFilter* f2 = new TestEventFilter(5);
TestEventFilter* f3 = new TestEventFilter(3);
TestEventFilter* f4 = new TestEventFilter(7);
o.installEventFilter(f1);
o.installEventFilter(f2);
o.installEventFilter(f3);
o.installEventFilter(f4);
qApp->sendEvent(&o, new TestEvent(5));
qApp->sendEvent(&o, new TestEvent(3));
Output:
EventFilter for 7 got 0x369f2fe0
EventFilter for 3 got 0x369f2fe0
EventFilter for 5 got 0x369f2fe0
accept that event!
EventFilter for 7 got 0x369f3250
EventFilter for 3 got 0x369f3250
accept that event!

Slot is not being used

I'm learning the signals/slots in Qt and I have found a problem. I need to create my own slot that is called when items on QGraphicsScene (in QGraphicsView) are moved or selected.
I'm starting with a simple app that has one widget and on it is graphicsView and label. I've created a slot in my window and connected it to QGraphicsScene's signal, but it is not being used. Where is my mistake?
Here is the code:
//MainWindow.h
//as generated by QtCreator, just added one slot to it
...omitted for brevity...
public slots:
void selectedItemChanged(QGraphicsItem * newItem, QgraphicsItem * oldItem);
..omitted for brevity...
//------------------------------------------------------------------
//MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsScene * scene = new QGraphicsScene();
scene->setBackgroundBrush (QBrush(Qt::gray));
ui->graphicsView->setScene (scene);
for(int x = 10; x < 250; x+=20)
{
QGraphicsEllipseItem * item = scene->addEllipse (x,x,5,5,QPen(Qt::darkGreen),QBrush(Qt::darkGreen));
item->setFlag (QGraphicsItem::ItemIsFocusable,true);
}
QObject::connect (scene,SIGNAL(focusItemChanged),this,SLOT(selectedItemChanged));
}
void MainWindow::selectedItemChanged (QGraphicsItem *newItem, QGraphicsItem *oldItem)
{
qDebug()<<"called";
if(newItem == 0)
{
ui->label->setText ("Není vybrán bod");
}
else
{
ui->label->setText (QString::number (newItem->scenePos ().x ()) + "," + QString::number (newItem->scenePos ().y ()));
}
}
Now, when I run the probram it rins ok, but I cannot set Focus on the circles(ellipses) drawn on the scene and the slot is not used. I tried setting IsSelectable flag, but it does not help. Is there any other preferred way to get this done or solution to my problem?
You're not linking against the signal's right signature, according to the documentation:
void QGraphicsScene::focusItemChanged( QGraphicsItem * newFocus, QGraphicsItem * oldFocus,
Qt::FocusReason reason)
and also notice that you can check the connection's success/failure status via the bool return type of the QObject::connect method
So, in the end i found the answer to my own question. It was a mistake on my side.
in the connect() i used the slots without parenthesis/parameters. It should have looked like:
QObject::connect (scene,
SIGNAL(focusItemChanged(QGraphicsItem*,QGraphicsItem*,Qt::FocusReason)),
this,
SLOT(selectedItemChanged(QGraphicsItem*,QGraphicsItem*)));

SIGNAL and SLOT parameters issue in QT

Could someone please advise how to correctly implement SLOT execution?
my code:
prog::prog(QWidget *parent): QMainWindow(parent) //constructor (VisualStudio):
{
ui.setupUi(this);
QCustomPlot * customPlot = new QCustomPlot(this);
setupRealtimeDataDemo(customPlot);
// + more code
}
void prog::setupRealtimeDataDemo(QCustomPlot * customPlot)
{
customPlot->addGraph(); //
// + more related with graph methods
// setup a timer that repeatedly calls realtimeDataSlot:
connect(&dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot(QCustomPlot)));
dataTimer.start(0); // Interval 0 means to refresh as fast as possible
}
void prog::realtimeDataSlot(QCustomPlot *customPlot)
{
// calculate two new data points:
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
double key = 0;
#else
double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
#endif
static double lastPointKey = 0;
if (key-lastPointKey > 0.01) // at most add point every 10 ms
{
double value0 = qSin(key); //sin(key*1.6+cos(key*1.7)*2)*10 + sin(key*1.2+0.56)*20 + 26;
double value1 = qCos(key); //sin(key*1.3+cos(key*1.2)*1.2)*7 + sin(key*0.9+0.26)*24 + 26
// add data to lines:
customPlot->graph(0)->addData(key, value0);
customPlot->graph(1)->addData(key, value1);
// + more code related with graph
}
}
Here are my findings:
SIGNAL and SLOT need the same signature, build program won't run
SLOT ( because SLOT become undefined).
Possible solution: remove QCustomPlot argument form SLOT, but how
then should I send to realtimeDataSlot pointer to QCustomPlot? Maybe
it possible to overload timeout() ? Maybe other solution?
I discovered when I use #include "winsock2.h" and try to "Promote to..." option
like in http://www.qcustomplot.com/index.php/tutorials/settingup errors
appears about parameters redefinition , so this workaround I cannot
use. I also don't won't to use qwt
Thanks is advance for help!
There is a multitude of solutions. Two come to mind:
Make the QCustomPlot* a member of the prog class:
class prog : public QWidget {
Q_OBJECT
QScopedPointer<QCustomPlot> m_plot;
...
}
prog::prog(QWidget *parent): QMainWindow(parent) :
m_plot(new QCustomPlot)
{
ui.setupUi(this);
setupRealtimeDataDemo(m_plot.data());
}
Use C++11 and Qt 5 features:
connect(&dataTimer, &QTimer::timeout, this, [=]{
realtimeDataSlot(customPlot); // doesn't need to be a slot anymore
});

How to get this Qt state machine to work?

I have two widgets that can be checked, and a numeric entry field that should contain a value greater than zero. Whenever both widgets have been checked, and the numeric entry field contains a value greater than zero, a button should be enabled. I am struggling with defining a proper state machine for this situation. So far I have the following:
QStateMachine *machine = new QStateMachine(this);
QState *buttonDisabled = new QState(QState::ParallelStates);
buttonDisabled->assignProperty(ui_->button, "enabled", false);
QState *a = new QState(buttonDisabled);
QState *aUnchecked = new QState(a);
QFinalState *aChecked = new QFinalState(a);
aUnchecked->addTransition(wa, SIGNAL(checked()), aChecked);
a->setInitialState(aUnchecked);
QState *b = new QState(buttonDisabled);
QState *bUnchecked = new QState(b);
QFinalState *bChecked = new QFinalState(b);
employeeUnchecked->addTransition(wb, SIGNAL(checked()), bChecked);
b->setInitialState(bUnchecked);
QState *weight = new QState(buttonDisabled);
QState *weightZero = new QState(weight);
QFinalState *weightGreaterThanZero = new QFinalState(weight);
weightZero->addTransition(this, SIGNAL(validWeight()), weightGreaterThanZero);
weight->setInitialState(weightZero);
QState *buttonEnabled = new QState();
buttonEnabled->assignProperty(ui_->registerButton, "enabled", true);
buttonDisabled->addTransition(buttonDisabled, SIGNAL(finished()), buttonEnabled);
buttonEnabled->addTransition(this, SIGNAL(invalidWeight()), weightZero);
machine->addState(registerButtonDisabled);
machine->addState(registerButtonEnabled);
machine->setInitialState(registerButtonDisabled);
machine->start();
The problem here is that the following transition:
buttonEnabled->addTransition(this, SIGNAL(invalidWeight()), weightZero);
causes all the child states in the registerButtonDisabled state to be reverted to their initial state. This is unwanted behaviour, as I want the a and b states to remain in the same state.
How do I ensure that a and b remain in the same state? Is there another / better way this problem can be solved using state machines?
Note. There are a countless (arguably better) ways to solve this problem. However, I am only interested in a solution that uses a state machine. I think such a simple use case should be solvable using a simple state machine, right?
After reading your requirements and the answers and comments here I think merula's solution or something similar is the only pure Statemachine solution.
As has been noted to make the Parallel State fire the finished() signal all the disabled states have to be final states, but this is not really what they should be as someone could uncheck one of the checkboxes and then you would have to move away from the final state. You can't do that as FinalState does not accept any transitions. The using the FinalState to exit the parallel state also causes the parallel state to restart when it is reentered.
One solution could be to code up a transition that only triggers when all three states are in the "good" state, and a second one that triggers when any of those is not. Then you add the disabled and enabled states to the parallel state you already have and connect it with the aforementioned transitions. This will keep the enabled state of the button in sync with all the states of your UI pieces. It will also let you leave the parallel state and come back to a consistent set of property settings.
class AndGateTransition : public QAbstractTransition
{
Q_OBJECT
public:
AndGateTransition(QAbstractState* sourceState) : QAbstractTransition(sourceState)
m_isSet(false), m_triggerOnSet(true), m_triggerOnUnset(false)
void setTriggerSet(bool val)
{
m_triggerSet = val;
}
void setTriggerOnUnset(bool val)
{
m_triggerOnUnset = val;
}
addState(QState* state)
{
m_states[state] = false;
connect(m_state, SIGNAL(entered()), this, SLOT(stateActivated());
connect(m_state, SIGNAL(exited()), this, SLOT(stateDeactivated());
}
public slots:
void stateActivated()
{
QObject sender = sender();
if (sender == 0) return;
m_states[sender] = true;
checkTrigger();
}
void stateDeactivated()
{
QObject sender = sender();
if (sender == 0) return;
m_states[sender] = false;
checkTrigger();
}
void checkTrigger()
{
bool set = true;
QHashIterator<QObject*, bool> it(m_states)
while (it.hasNext())
{
it.next();
set = set&&it.value();
if (! set) break;
}
if (m_triggerOnSet && set && !m_isSet)
{
m_isSet = set;
emit (triggered());
}
elseif (m_triggerOnUnset && !set && m_isSet)
{
m_isSet = set;
emit (triggered());
}
}
pivate:
QHash<QObject*, bool> m_states;
bool m_triggerOnSet;
bool m_triggerOnUnset;
bool m_isSet;
}
Did not compile this or even test it, but it should demonstrate the principle
The state machine you used above does not correspond to what you described. Using a final state is not correct because after enter a value greater zero I don't see anything that prevents the user from enter zero again. Therefore the valid states can't be final. As far as I can see from your code the user is allowed to change the state of the widgets in any order. Your state machine has to pay attention to this.
I would use a state machine with four child states (no valid input, one valid input, two valid inputs, three valid inputs). You obviously start with no valid input. Each widget can make a transition from no to one an back (same counts for two and three). When three is entered all widgets are valid (button enabled). For all other states the button has to be disabled when the state is entered.
I wrote a sample app. The main window contains two QCheckBoxes a QSpinBox and a QPushButton. There are signals in the main window the ease write down the transitions of the states. There are fired when the state of the widgets are changed.
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
namespace Ui
{
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
bool m_editValid;
bool isEditValid() const;
void setEditValid(bool value);
private slots:
void on_checkBox1_stateChanged(int state);
void on_checkBox2_stateChanged(int state);
void on_spinBox_valueChanged (int i);
signals:
void checkBox1Checked();
void checkBox1Unchecked();
void checkBox2Checked();
void checkBox2Unchecked();
void editValid();
void editInvalid();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), m_editValid(false)
{
ui->setupUi(this);
QStateMachine* stateMachine = new QStateMachine(this);
QState* noneValid = new QState(stateMachine);
QState* oneValid = new QState(stateMachine);
QState* twoValid = new QState(stateMachine);
QState* threeValid = new QState(stateMachine);
noneValid->addTransition(this, SIGNAL(checkBox1Checked()), oneValid);
oneValid->addTransition(this, SIGNAL(checkBox1Checked()), twoValid);
twoValid->addTransition(this, SIGNAL(checkBox1Checked()), threeValid);
threeValid->addTransition(this, SIGNAL(checkBox1Unchecked()), twoValid);
twoValid->addTransition(this, SIGNAL(checkBox1Unchecked()), oneValid);
oneValid->addTransition(this, SIGNAL(checkBox1Unchecked()), noneValid);
noneValid->addTransition(this, SIGNAL(checkBox2Checked()), oneValid);
oneValid->addTransition(this, SIGNAL(checkBox2Checked()), twoValid);
twoValid->addTransition(this, SIGNAL(checkBox2Checked()), threeValid);
threeValid->addTransition(this, SIGNAL(checkBox2Unchecked()), twoValid);
twoValid->addTransition(this, SIGNAL(checkBox2Unchecked()), oneValid);
oneValid->addTransition(this, SIGNAL(checkBox2Unchecked()), noneValid);
noneValid->addTransition(this, SIGNAL(editValid()), oneValid);
oneValid->addTransition(this, SIGNAL(editValid()), twoValid);
twoValid->addTransition(this, SIGNAL(editValid()), threeValid);
threeValid->addTransition(this, SIGNAL(editInvalid()), twoValid);
twoValid->addTransition(this, SIGNAL(editInvalid()), oneValid);
oneValid->addTransition(this, SIGNAL(editInvalid()), noneValid);
threeValid->assignProperty(ui->pushButton, "enabled", true);
twoValid->assignProperty(ui->pushButton, "enabled", false);
oneValid->assignProperty(ui->pushButton, "enabled", false);
noneValid->assignProperty(ui->pushButton, "enabled", false);
stateMachine->setInitialState(noneValid);
stateMachine->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::isEditValid() const
{
return m_editValid;
}
void MainWindow::setEditValid(bool value)
{
if (value == m_editValid)
{
return;
}
m_editValid = value;
if (value)
{
emit editValid();
} else {
emit editInvalid();
}
}
void MainWindow::on_checkBox1_stateChanged(int state)
{
if (state == Qt::Checked)
{
emit checkBox1Checked();
} else {
emit checkBox1Unchecked();
}
}
void MainWindow::on_checkBox2_stateChanged(int state)
{
if (state == Qt::Checked)
{
emit checkBox2Checked();
} else {
emit checkBox2Unchecked();
}
}
void MainWindow::on_spinBox_valueChanged (int i)
{
setEditValid(i > 0);
}
This should do the trick. As you yourself mentioned already there are better ways to achive this behaviour. Especially keep track of all transistions between the state is error prone.
When I have to do things like this I usually use signals and slots. Basically each of the widgets and the number box will all emit signals automatically when their states change. If you link each of these to a slot that checks if all 3 objects are in the desired state and enables the button if they are or disables it if they aren't, then that should simplify things.
Sometimes you will also need to change the button state once you've clicked it.
[EDIT]: I'm sure there is some way of doing this using state machines, will you only be reverting in the situation that both boxes are checked and you've added an invalid weight or will you also need to revert with only one checkbox checked? If it's the former then you may be able to set up a RestoreProperties state that allows you to revert to the checked box state. Otherwise is there some way you can save the state before checking the weight is valid, revert all checkboxes then restore the state.
Set up your weight input widget so that there is no way a weight less than zero can be entered. Then you don't need invalidWeight()
edit
I reopened this test, willing to use it, added to .pro
CONFIG += C++11
and I discovered that lambda syntax has changed... The capture list cannot reference member variables. Here is the corrected code
auto cs = [/*button, check1, check2, edit, */this](QState *s, QState *t, bool on_off) {
s->assignProperty(button, "enabled", !on_off);
s->addTransition(new QSignalTransition(check1, SIGNAL(clicked())));
s->addTransition(new QSignalTransition(check2, SIGNAL(clicked())));
s->addTransition(new QSignalTransition(edit, SIGNAL(textChanged(QString))));
Transition *p = new Transition(this, on_off);
p->setTargetState(t);
s->addTransition(p);
};
end edit
I used this question as exercise (first time on QStateMachine). The solution is fairly compact, using a guarded transition to move between 'enabled/disabled' state, and lambda to factorize setup:
#include "mainwindow.h"
#include <QLayout>
#include <QFrame>
#include <QSignalTransition>
struct MainWindow::Transition : QAbstractTransition {
Transition(MainWindow *main_w, bool on_off) :
main_w(main_w),
on_off(on_off)
{}
virtual bool eventTest(QEvent *) {
bool ok_int, ok_cond =
main_w->check1->isChecked() &&
main_w->check2->isChecked() &&
main_w->edit->text().toInt(&ok_int) > 0 && ok_int;
if (on_off)
return ok_cond;
else
return !ok_cond;
}
virtual void onTransition(QEvent *) {}
MainWindow *main_w;
bool on_off;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QFrame *f = new QFrame(this);
QVBoxLayout *l = new QVBoxLayout;
l->addWidget(check1 = new QCheckBox("Ok &1"));
l->addWidget(check2 = new QCheckBox("Ok &2"));
l->addWidget(edit = new QLineEdit());
l->addWidget(button = new QPushButton("Enable &Me"));
f->setLayout(l);
setCentralWidget(f);
QState *s1, *s2;
sm = new QStateMachine(this);
sm->addState(s1 = new QState());
sm->addState(s2 = new QState());
sm->setInitialState(s1);
auto cs = [button, check1, check2, edit, this](QState *s, QState *t, bool on_off) {
s->assignProperty(button, "enabled", !on_off);
s->addTransition(new QSignalTransition(check1, SIGNAL(clicked())));
s->addTransition(new QSignalTransition(check2, SIGNAL(clicked())));
s->addTransition(new QSignalTransition(edit, SIGNAL(textChanged(QString))));
Transition *tr = new Transition(this, on_off);
tr->setTargetState(t);
s->addTransition(tr);
};
cs(s1, s2, true);
cs(s2, s1, false);
sm->start();
}