I have a tool button in one .cpp (i.e. ExerciseControl.cpp). When the button is clicked, it will trigger two timers in another .cpp (i.e. StatusBar.cpp).
However, the following codes does not work. The timers do not start when I click the button in ExerciseControl.cpp to trigger startExercise().
ExerciseControl.cpp:
ExerciseControl::ExerciseControl(void)
{
myStatusBar = new StatusBar;
}
void ExerciseControl::startExercise()
{
myStatusBar ->simulationTimer->start(1000);
myStatusBar ->elapsedTimer->start(1000);
}
StatusBar.cpp:
StatusBar::StatusBar()
{
simulationTimer = new QTimer;
QObject::connect(simulationTimer, SIGNAL(timeout()), this, SLOT(tickSimulation()));
elapsedTimer = new QTimer;
QObject::connect(elapsedTimer, SIGNAL(timeout()), this, SLOT(tickSimulation()));
createButtons();
};
void StatusBar::createButtons()
{
...
}
void StatusBar::tickSimulation()
{
...
}
However, if I declare the following in my constructor, the timers can start automatically, which is not I wanted.
StatusBar::StatusBar()
{
simulationTimer = new QTimer;
simulationTimer->start(1000);
QObject::connect(simulationTimer, SIGNAL(timeout()), this, SLOT(tickSimulation()));
elapsedTimer = new QTimer;
elapsedTimer->start(1000);
QObject::connect(elapsedTimer, SIGNAL(timeout()), this, SLOT(tickSimulation()));
}
I need to trigger the timers through my button in ExerciseControl.cpp.
Please help.
Thanks.
On the example below, ExerciseControl is a specialization of QMainWindow that does 2 things:
Display a QTooButton inside the window;
Allocate a StatusBar object.
Clicking the button invokes the slot _timers_must_start() of the class. This slot is responsible to call start_timers() from the StatusBar object, which in turn starts the timers of that object.
I made each timer call a slot that prints something to the screen when the timeout() is triggered.
Enjoy.
main.cpp:
#include "exercise_control.h"
#include <QApplication>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
ExerciseControl ec;
ec.show();
return app.exec();
}
exercise_control.h:
#pragma once
#include "status_bar.h"
#include <QMainWindow>
#include <QToolButton>
class ExerciseControl : public QMainWindow
{
Q_OBJECT
public:
ExerciseControl()
{
_button = new QToolButton(this);
_button->setText("Press Me!");
QObject::connect(_button, SIGNAL(clicked()), this, SLOT(_timers_must_start()));
_statusbar = new StatusBar;
// Set the size of the window to the size of the button
setFixedSize(_button->width() ,_button->height());
}
private slots:
/* This slot is called by clicking the button */
void _timers_must_start()
{
qDebug() << "ExerciseControl::_timers_must_start: button clicked! Trying to start timers...";
_statusbar->start_timers();
}
private:
QToolButton* _button;
StatusBar* _statusbar;
};
status_bar.h:
#pragma once
#include <QObject>
#include <QTimer>
#include <QDebug>
class StatusBar : public QObject
{
Q_OBJECT
public:
StatusBar()
{
_timer1 = new QTimer;
QObject::connect(_timer1, SIGNAL(timeout()), this, SLOT(_timer1_task()));
_timer2 = new QTimer;
QObject::connect(_timer2, SIGNAL(timeout()), this, SLOT(_timer2_task()));
}
~StatusBar()
{
_timer1->stop();
delete _timer1;
_timer2->stop();
delete _timer2;
}
void start_timers()
{
if (!_timer1->isActive() && !_timer2->isActive())
{
qDebug() << "StatusBar::start_timers: OK!";
_timer1->start(1000); // 1 second interval
_timer2->start(5000); // 5 seconds interval
return;
}
qDebug() << "StatusBar::start_timers: timers already started, nothing to be done here!";
}
private:
QTimer* _timer1;
QTimer* _timer2;
private slots:
/* These slots are called by the timers of this class, hence PRIVATE SLOTS */
void _timer1_task()
{
qDebug() << "StatusBar::_timer1_task: 1 second has elapsed";
}
void _timer2_task()
{
qDebug() << "StatusBar::_timer2_task: 5 seconds has elapsed";
}
};
test.pro:
QT += widgets
SOURCES += \
main.cpp
HEADERS += \
exercise_control.h \
status_bar.h
Related
I have a QProgressDialog and I would like to override its cancel() slot to change its behavior.
Instead of closing the dialog, I would like to do some other operations and then close the dialog after a QThread to finish before closing the dialog.
I tried to disconnect the canceled/cancel signal/slot couples and the reconnect with the new behavior but it does not seem to change much.
As as soon as I click on the cancel button, the progress dialog gets closed first and then my lambda get executed anyway.
Qobject::disconnect(m_progressdialog, &QProgressDialog::canceled, m_progressdialog, &QProgressDialog::cancel);
Qobject::connect(m_progressdialog, &QProgressDialog::canceled, [](){
// continue displaying the dialog as an occupation bar
m_progressdialog->setValue(0);
// do some other things
// a lot of code
// ...
// only later close the dialog
m_progressdialog->close();
});
Is there a way to do this correctly?
I don't know your whole code, but according to the documentation, the idea is more or less the same you're saying: a slot to connect the signal QProgressDialog::canceled().
The following code is just an example but it's working. In this case, instead of using the own Qt property wasCanceled, it is used a boolean to control when to stop and cancel the QProgressDialog.
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
class QProgressDialog;
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void on_pushButton_clicked();
void my_custom_cancel();
private:
Ui::Dialog *ui;
QProgressDialog *progress;
int numTasks = 100000;
bool canceled = false;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QProgressDialog>
#include <QThread>
#include <QDebug>
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
progress = new QProgressDialog("Task in progress...", "Cancel", 0, numTasks);
connect(progress, SIGNAL(canceled()), this, SLOT(my_custom_cancel()));
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
progress->open();
for (int i = 0; i < numTasks; i++) {
progress->setValue(i);
QThread::usleep(100);
if (canceled)
break;
}
progress->setValue(numTasks);
}
void Dialog::my_custom_cancel()
{
qDebug() << "do something";
canceled = true;
}
I want to update a modal QProgressDialog from my worker thread. However, if I set the dialog to be modal, my application crashes (and the dialog did not show any progress). If I do not, everything goes fine (but the user can tinker around with the rest of the program, which may cause issues).
What am I doing wrong?
Minimum code sample follows:
filereader qfr;
QProgressDialog progress("Importing file.", "Cancel", 0, file_size);
connect(&qfr, &filereader::signalProgress, &progress, &QProgressDialog::setValue, Qt::QueuedConnection);
QThread worker_thread;
std::atomic<bool> success = false;
connect(&worker_thread, &QThread::started,
[&]() {
success = qfr.read_file(/* parameters */);
worker_thread.quit();});
worker_thread.start();
//progress.setWindowModality(Qt::WindowModal); // Works only fine when this line is commented !!
while (worker_thread.isRunning()) {
QApplication::processEvents();
QThread::sleep(0);
}
progress.close();
Your thread is pretty much pointless. It serves no real purpose. You could have as well just called QApplication::processEvents in your read_file method. But you shouldn't, calling processEvents is bad practice.
What you should do is remove that while loop, and make your progress dialog a member of your class. I don't really like how that lambda looks either. I would personally just use filereader::read_file as a slot.
Note that Qt::windowModal blocks input to the parent window. Your progress dialog has no parent. So you would either have to call progress->setModal(true), or progress.setWindowModality(Qt::ApplicationModal);. Or set a parent to it.
Here is a small example (it is not tailor made for your application, but it should point you in the right direction):
#include <QtWidgets>
class Worker : public QObject
{
Q_OBJECT
public:
Worker(QObject *parent = nullptr) : QObject(parent){}
public slots:
void simulateLongProcess()
{
for(int i = 0; i < 101; i++)
{
emit progressChanged(i);
QThread::msleep(100);
}
emit finishedWorking(true);
}
signals:
void progressChanged(int progress);
void finishedWorking(bool result);
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr) : QWidget(parent)
{
setLayout(new QHBoxLayout);
progress_dialog.setModal(true);
progress_dialog.setAutoReset(false);
progress_dialog.setCancelButton(nullptr);
QThread *thread = new QThread(this);
connect(thread, &QThread::started, &worker, &Worker::simulateLongProcess);
connect(&worker, &Worker::finishedWorking, thread, &QThread::quit);
connect(&worker, &Worker::progressChanged, &progress_dialog, &QProgressDialog::setValue);
connect(&worker, &Worker::finishedWorking, &progress_dialog, &QProgressDialog::close);
connect(&worker, &Worker::finishedWorking, this, &Widget::handleResult);
QPushButton * start_button = new QPushButton("START");
connect(start_button, &QPushButton::clicked, this, [=]
{
progress_dialog.show();
thread->start();
});
layout()->addWidget(start_button);
resize(400, 300);
}
public slots:
void handleResult(bool result)
{
// do something with the result
}
private:
QProgressDialog progress_dialog;
Worker worker;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
I'm having issues implementing timing. What i want to do is run this:
//relay 1 power cycle
void MainWindow::relay1PCycle()
{
relay1High();
while (true){
QTimer::singleShot(750, this, SLOT(relay1Low()));
QTimer::singleShot(750, this, SLOT(relay1High()));
}
}
as while a button is pressed.
//power cycle button
void MainWindow::on_pushButton_3_toggled(bool checked)
{
if (checked){
//run relay1PCycle as a thread.
}
else{
//Terminate relay1PCycle thread.
}
}
however, so far everything i've tried so far has been a failure.
What's the correct way to go about this?
Thanks
The task they want to implement is not blocking, so it is not necessary to use threads, only a timer with an adequate logic. To make it simple we will assign that task to the next class:
relaycontroller.h
#ifndef RELAYCONTROLLER_H
#define RELAYCONTROLLER_H
#include <QObject>
#include <QTimer>
#include <QDebug>
class RelayController : public QObject
{
Q_OBJECT
public:
explicit RelayController(QObject *parent = 0):QObject(parent){
timer = new QTimer(this);
state = false;
timer->setInterval(750);
//old style
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
//new style
//connect(timer, &QTimer::timeout, this, &RelayController::onTimeout);
}
void start(){
qDebug()<<"timer";
timer->start();
}
void stop(){
timer->stop();
}
void relayLow(){
//code here: relay off
qDebug()<<"low";
}
void relayHigh(){
//code here: relay on
qDebug()<<"high";
}
private slots:
void onTimeout(){
if(state)
relayHigh();
else
relayLow();
state = !state;
}
private:
QTimer *timer;
bool state;
};
#endif // RELAYCONTROLLER_H
Then an object is created and used in the slot pressed:
mainwindow.h
private:
RelayController *controller;
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
controller = new RelayController(this);
ui->pushButton_3->setCheckable(true);
}
void MainWindow::on_pushButton_toggled(bool checked)
{
if(checked)
controller->start();
else
controller->stop();
}
I have the following method in one of my C++ classes (using QtWebEngine):
QString get()
{
QString result;
view->page()->runJavaScript("test();", [this](const QVariant &v)
{
result = v.toString();
});
return result;
}
It is to execute test() JS function and return the result of this invocation.
Unfortunately, the callback is asynchronous and the program crashes. How can I make it work?
The callback is asynchronous because the JavaScript execution occurs not only in another thread but in another process. So there is no way to make it fully synchronous.
The best possible solution would be to migrate your C++ code to work asynchronously. If you can't do that, the only feasible solution is to use QEventLoop, somewhat like this:
void ranJavaScript()
{
emit notifyRanJavaScript();
}
QString get()
{
QString result;
QEventLoop loop;
QObject::connect(this, SIGNAL(notifyRanJavaScript()), &loop, SLOT(quit()));
view->page()->runJavaScript("test();", [this](const QVariant &v)
{
result = v.toString();
this.ranJavaScript();
});
loop.exec();
return result;
}
However, note that this example is oversimplified for a real-world usage: you need to ensure the JavaScript was not ran before the event loop is started. The most proper way to do that would involve implementing a proper slot instead of a lambda + factoring out the call to view->page()->runJavaScript() into another slot which would be called asynchronously after starting the event loop. It is a lot of glue code for such a seemingly simple task but that's what it takes. Here's an example:
MainWindow.h
#ifndef TMP_MAIN_WINDOW_H
#define TMP_MAIN_WINDOW_H
#include <QMainWindow>
#include <QVariant>
class QWebEngineView;
class QPushButton;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget * parent = 0);
QString get();
void onScriptEnded(const QVariant & data);
Q_SIGNALS:
void notifyRanJavaScript();
private Q_SLOTS:
void onButtonPressed();
void startScript();
private:
QWebEngineView * m_view;
QPushButton * m_button;
QString m_scriptResult;
};
#endif // TMP_MAIN_WINDOW_H
MainWindow.cpp
#include "MainWindow.h"
#include <QWebEngineView>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QEventLoop>
#include <QDebug>
#include <QTimer>
MainWindow::MainWindow(QWidget * parent) :
QMainWindow(parent)
{
m_view = new QWebEngineView;
QWebEnginePage * page = new QWebEnginePage(m_view);
m_view->setPage(page);
QString html = QStringLiteral("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
"\"http://www.w3.org/TR/html4/strict.dtd\"><html>"
"<head><h3>head</h3>\n</head>"
"<script type=\"text/javascript\">function test() { return \"A!\"; }</script>"
"<body>text\n</body></html>");
m_view->page()->setHtml(html);
m_button = new QPushButton;
m_button->setMinimumWidth(35);
m_button->setText(QStringLiteral("Test"));
QObject::connect(m_button, SIGNAL(pressed()), this, SLOT(onButtonPressed()));
QHBoxLayout * buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(m_button);
buttonLayout->addStretch();
QVBoxLayout * viewLayout = new QVBoxLayout;
viewLayout->addLayout(buttonLayout);
viewLayout->addWidget(m_view);
QWidget * widget = new QWidget(this);
widget->setLayout(viewLayout);
setCentralWidget(widget);
}
QString MainWindow::get()
{
QEventLoop loop;
QObject::connect(this, SIGNAL(notifyRanJavaScript()), &loop, SLOT(quit()));
// Schedule the slot to run in 0 seconds but not right now
QTimer::singleShot(0, this, SLOT(startScript()));
// The event loop would block until onScriptEnded slot is executed
loop.exec();
// If we got here, the script has been executed and the result was saved in m_scriptResult
return m_scriptResult;
}
void MainWindow::onScriptEnded(const QVariant & data)
{
qDebug() << QStringLiteral("Script ended: ") << data;
m_scriptResult = data.toString();
emit notifyRanJavaScript();
}
void MainWindow::onButtonPressed()
{
QString str = get();
QMessageBox::information(this, QStringLiteral("Script result"), str,
QMessageBox::StandardButton::Ok);
}
struct Functor
{
Functor(MainWindow & window) : m_window(window) {}
void operator()(const QVariant & data)
{
m_window.onScriptEnded(data);
}
MainWindow & m_window;
};
void MainWindow::startScript()
{
qDebug() << QStringLiteral("Start script");
m_view->page()->runJavaScript(QStringLiteral("test();"), Functor(*this));
}
Dmitry's solution only works partially, unfortunately. In his example the code is invoked upon pressing a button. However, if the same code is moved to execute while the window is loading, the slot for the finished script (onScriptEnded) is never called. To fix this, I had to wrap the call to the evaluation of JS itself (called evaluateJavaScript in my project) in another QTimer::singleShot:
QTimer::singleShot(0, this, [&] { evaluateJavaScript(); });
Unfortunately, in my real project I have many calls, often one evaluation waiting for another before it to finish. It's practically impossible to use this every single time so I still look for a solution.
In the kchmviewer project, I found a very easy way to wait for the result of the runJavaScript function. The following code is part of the ViewWindow class which inherits from QWebEngineView.
int ViewWindow::getScrollbarPosition()
{
QAtomicInt value = -1;
page()->runJavaScript("document.body.scrollTop", [&value](const QVariant &v)
{
qDebug( "value retrieved: %d\n", v.toInt());
value = v.toInt();
});
while (value == -1)
{
QApplication::processEvents();
}
qDebug( "scroll value %d", value.load() );
return value;
}
Hi my program runs with no errors but nothing is displayed on screen, a window is meant to pop up which runs another program with a QProcess, this program runs fine. code follows:
header file:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtGui>
#include <QTimer>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void setTimer();
void displayAdvice();
void cancelTimer();
void addAdvice();
void processDone(int);
private:
QLabel* timerLbl;
QLineEdit* timerEdt;
QTextEdit* adviceEdt;
QPushButton* okBtn;
QPushButton* cancelBtn;
QTimer* timer;
QProcess *process;
void setupGui();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setupGui();
}
Widget::~Widget()
{
delete ui;
}
void Widget::setupGui()
{
timerLbl = new QLabel("Timer set interval in seconds");
timerEdt = new QLineEdit();
adviceEdt = new QTextEdit();
this->adviceEdt->setReadOnly(true);
okBtn = new QPushButton("OK");
cancelBtn = new QPushButton("Cancel");
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(timerLbl);
layout->addWidget(timerEdt);
layout->addWidget(okBtn);
layout->addWidget(adviceEdt);
layout->addWidget(cancelBtn);
this->setWindowTitle("Advice");
this->setLayout(layout);
connect(okBtn,SIGNAL(clicked()), this, SLOT(setTimer()));
connect(cancelBtn, SIGNAL(clicked()), this, SLOT(cancelTimer()));
connect(timer, SIGNAL(timeout()),this, SLOT(displayAdvice()));
}
void Widget::setTimer()
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()),this, SLOT(cancelTimer()));
QString setting = this->timerEdt->text();
bool ok;
int set = setting.toInt(&ok,10);
set = set * 1000;
timer->setInterval(set);
timer->start();
timerEdt->setReadOnly(true);
okBtn->setDown(true);
}
void Widget::cancelTimer()
{
timer->stop();
adviceEdt->clear();
okBtn->setDown(false);
timerEdt->clear();
timerEdt->setReadOnly(false);
}
void Widget::displayAdvice()
{
process = new QProcess(this);
process->start("C:/Users/Dmon/Desktop/47039949 COS3711 Assignment 2/Question 4/Ass2Q4Part1-build-desktop/debug/Ass2Q4Part1.exe");
connect(process, SIGNAL(readyReadStandardOutput()),this, SLOT(addAdvice()));
connect(process, SIGNAL(finished(int)),this, SLOT(processDone(int)));
}
void Widget::addAdvice()
{
QByteArray data = process->readAllStandardOutput();
QString strToWrite = data;
this->adviceEdt->clear();
this->adviceEdt->append(strToWrite);
}
void Widget::processDone(int)
{
process->close();
process->deleteLater();
process=0;
}
main.cpp
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Program runs with nothing displayed then eventually exits with no errors after about 15 seconds.
Your problem is that you're already using a user interface coming from the form file (.ui file). You need to decide which one you wish to use.
To fix your code, all you need to do is remove all references to the Ui namespace. Simply remove the below:
namespace Ui {
class Widget;
}
//
private:
Ui::Widget *ui;
//
#include "ui_widget.h"
//
delete ui;
Also, note that this line is working with a null or undefined pointer value - you never create the timer instance:
connect(timer, SIGNAL(timeout()),this, SLOT(displayAdvice()));
Finally, there's no reason whatsoever to allocate the member widgets on the heap. It does, in fact, waste a bit of heap memory since QWidget instances are very small.
Here's how your code could look. I've put it all in a single file, to keep it short. You obviously don't need it in a single file. I've also made the UI a bit more compliant with usual expectations. E.g. controls that can't be interacted with should be disabled.
// main.cpp
#include <QApplication>
#include <QtWidgets>
#include <QTimer>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
private slots:
void setTimer();
void displayAdvice();
void cancelTimer();
void addAdvice();
void processDone(int);
private:
QLabel m_timerLbl;
QLineEdit m_timerEdt;
QTextEdit m_adviceEdt;
QPushButton m_okBtn;
QPushButton m_cancelBtn;
QTimer m_timer;
QProcess m_process;
void setupGui();
};
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
setupGui();
}
void Widget::setupGui()
{
m_timerLbl.setText("Timer set interval in seconds");
m_adviceEdt.setReadOnly(true);
m_okBtn.setText("OK");
m_cancelBtn.setText("Cancel");
m_cancelBtn.setEnabled(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(&m_timerLbl);
layout->addWidget(&m_timerEdt);
layout->addWidget(&m_okBtn);
layout->addWidget(&m_adviceEdt);
layout->addWidget(&m_cancelBtn);
setWindowTitle("Advice");
connect(&m_okBtn, SIGNAL(clicked()), SLOT(setTimer()));
connect(&m_cancelBtn, SIGNAL(clicked()), SLOT(cancelTimer()));
connect(&m_timer, SIGNAL(timeout()), SLOT(displayAdvice()));
connect(&m_timer, SIGNAL(timeout()), SLOT(cancelTimer()));
connect(&m_process, SIGNAL(readyReadStandardOutput()), SLOT(addAdvice()));
connect(&m_process, SIGNAL(finished(int)), SLOT(processDone(int)));
}
void Widget::setTimer()
{
QString const setting = m_timerEdt.text();
bool ok;
int set = setting.toInt(&ok,10) * 1000;
m_timer.setInterval(set);
m_timer.start();
m_timerEdt.setEnabled(false);
m_okBtn.setEnabled(false);
m_cancelBtn.setEnabled(true);
}
void Widget::cancelTimer()
{
m_timer.stop();
m_adviceEdt.clear();
m_timerEdt.clear();
m_okBtn.setEnabled(true);
m_timerEdt.setEnabled(true);
m_cancelBtn.setEnabled(false);
}
void Widget::displayAdvice()
{
m_process.start("bash", QStringList() << "-c" << "echo 'Hello!'");
#if 0
m_process.start(QDir::homePath() +
"/Desktop/47039949 COS3711 Assignment 2/Question 4/Ass2Q4Part1-build-desktop/debug/Ass2Q4Part1.exe");
#endif
}
void Widget::addAdvice()
{
QByteArray const data = m_process.readAllStandardOutput();
m_adviceEdt.setPlainText(QString::fromLocal8Bit(data));
}
void Widget::processDone(int)
{
m_process.close();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"