Progress Bar gtkmm Glade - c++

Working with the buttons and handling its events is easy but I couldn't interact with progress bars. How do I get a Gtk::ProgressBar from a Glade file and set its fraction?
I use Gtkmm 3.24 and I want to update a progress bar when I click a button. here is my glade file:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkApplicationWindow" id="MainWindow">
<property name="can-focus">False</property>
<property name="title" translatable="yes">My Main Window</property>
<property name="default-width">200</property>
<property name="default-height">150</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="LittleButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="MyProgressBar">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
My main.cpp file
#include <memory>
#include <gtkmm.h>
class MainWindow : public Gtk::ApplicationWindow
{
public:
MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder)
: Gtk::ApplicationWindow(obj)
, builder{builder}
{
}
virtual ~MainWindow() = default;
private:
Glib::RefPtr<Gtk::Builder> builder;
};
int main(int argc, char* argv[])
{
auto app = Gtk::Application::create(argc, argv, "de.engelmarkus.example");
auto builder = Gtk::Builder::create_from_file("MyGladeGUI.glade");
MainWindow* mwindow = nullptr;
builder->get_widget_derived("MainWindow", mwindow);
auto littleButton = builder->get_object("LittleButton");
auto r = app->run(*mwindow);
delete mwindow;
return r;
}
I build my application from the command line with:
g++ -rdynamic main.cpp -o hello $(pkg-config gtkmm-3.0 --libs --cflags)

Here is code that does what you want:
#include <memory>
#include <gtkmm.h>
constexpr int ERROR = 1;
int main(int argc, char* argv[])
{
auto app = Gtk::Application::create(argc, argv, "de.engelmarkus.example");
auto builder = Gtk::Builder::create_from_file("MyGladeGUI.glade");
// Get the window. First a `Glib::Object` handle to it and then cast it
// to the `Gtk::ApplicationWindow` type:
Glib::RefPtr<Glib::Object> mainWindowAsObject = builder->get_object("MainWindow");
Glib::RefPtr<Gtk::ApplicationWindow> mainWindow = Glib::RefPtr<Gtk::ApplicationWindow>::cast_dynamic(mainWindowAsObject);
if(!mainWindow)
{
return ERROR;
}
// At this point, the main window is valid, and as bonus, wrapped in a smart
// pointer, which means you do not have to manage its memory yourself. Now get
// the button. First get a `Glib::Object` handle to it and then cast it to the
// `Gtk::Button` type:
Glib::RefPtr<Glib::Object> buttonAsObject = builder->get_object("LittleButton");
Glib::RefPtr<Gtk::Button> button = Glib::RefPtr<Gtk::Button>::cast_dynamic(buttonAsObject);
if(!button)
{
return ERROR;
}
// At this point, the button is valid. We have to get the progress bar. You get
// the idea now ;):
Glib::RefPtr<Glib::Object> pBarAsObject = builder->get_object("MyProgressBar");
Glib::RefPtr<Gtk::ProgressBar> pBar = Glib::RefPtr<Gtk::ProgressBar>::cast_dynamic(pBarAsObject);
if(!pBar)
{
return ERROR;
}
// At this point, both the button and the progress bar have been extracted
// from the builder and are valid. We can now connect the button's 'clicked'
// signal handler:
button->signal_clicked().connect([&pBar](){
const double currentFraction = pBar->get_fraction();
pBar->set_fraction(currentFraction + 0.10);
});
// The syntax is ugly the basically:
// 1. Call `get()` to retreive the stored pointer
// 2. Call operator* on this pointer to get a reference
return app->run(*(mainWindow.get()));
} // mainWindow automatically deleted here by its RefPtr container!
Output:
I have taken the liberty to simplify it a bit. Most importantly, I reviewed your memory management model and completely removed the usage of delete, through the use of Glib::RefPtr which can do that for you.
You can build with:
g++ -rdynamic main.cpp -o hello `pkg-config gtkmm-3.0 --libs --cflags`
Note: I wrote this using Gtkmm 3.22.

Related

Deleting items from QT's QListWidget leading to undeletion/corruption of other entries

Disclaimer : I am pretty new to UI and QT.
I have UI that have QListWidget comprising of some numbers (1 to 5), now I am trying to delete the item one by one..
Problem :
After deletion of all entries are done, I can still see some entries (specifically 2 & 4).
Code:
File : main.cpp
Here I have created one async thread that will call MainWindows::display function.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
static MainWindow w;
w.show();
std::thread([]{
w.display();
}).detach();
a.exec();
return 0;
}
File : mainwindow.cpp
Here display function is deleting the items.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
void MainWindow::display()
{
sleep(15);
for(int i = 0; i < 5 ; i++)
{
auto j = ui->listWidget->takeItem(i);
delete j;
}
}
MainWindow::~MainWindow()
{
delete ui;
}
File : mainwindow.UI
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QListWidget" name="listWidget">
<property name="geometry">
<rect>
<x>180</x>
<y>20</y>
<width>256</width>
<height>192</height>
</rect>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>3</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>5</string>
</property>
</item>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>19</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Output:
Questions:
Why this is happening? am I doing something wrong?
If this leads to undeletion/corruption is there any other way to achieve it?
Any help is very much appreciated.
The reason is not really related to Qt but has to do with arrays and loops in general.
Say, initially, I start with a list:
0. Apple
1. Orange
2. Jackfruit
I remove the item at index 0:
0. Orange
1. Jackfruit
Now in the loop, we do i++, and then remove the item at index 1.
0. Orange
Notice that we completely skipped Orange because it moved down as we incremented our index.
If you want to delete everything, you can use QListWidget::clear() instead.
As for memory "corruption", the delete j is ok, since you need to manage the pointer yourself after calling takeItem.
On a side note, I wouldn't mix std::thread with Qt (see comments here).

Unable to get ros::params defined in bash and roslaunch to print in c++ script

I have a bash script as follows:
foldername=camera_calibration_$(date +"%m-%d-%Y")
im_name="/cam0"
roslaunch image_pub cam_calibration.launch foldername:=$foldername image_name:=$im_name
My roslaunch script is as follows:
<launch>
<arg name = "foldername" default="camera_calibration" />
<arg name = "image_name" default="/cam1" />
<param name="foldername" type="string" value="$(arg foldername)" />
<param name="image_name" type="string" value="$(arg image_name)" />
<param name="size_name" type="string" value="12x8" />
<param name="square" type="string" value="0.05" />
<node name="im_pub_sub_node" pkg="image_pub" type="im_pub_sub" output="screen"/>
<node name="cameracalibrator_node" pkg="camera_calibration" type="cameracalibrator.py" output="screen"/>
</launch>
My C++ script (im_pub_sub.cpp) as follows:
int main(int argc, char** argv) {
std::string foldername;
std::string imagename;
std::string si_name;
ros::param::get("/size_name", si_name);
ros::param::get("/foldername", foldername);
ros::param::get("/image_name", imagename);
std::cout<<imagename<<std::endl;
std::cout<<foldername<<std::endl;
std::cout<<si_name<<std::endl;
std::cout<<"hi"<<std::endl;
}
When I launch it I only get "hi" print on my console but not foldername, image_name defined from bash and si_name param defined in launch file. It prints empty like nothing for other params defined.
I can get these params printed in my python script, but I am unable to do the same using c++. This is completely "weird".
Can anyone please let me know what is wrong in my syntax?
I got it. That's because you can't get rosparams from launch file until rosnode initilaization and node Nodehandler is being defined.
int main(int argc, char** argv) {
ros::init(argc, argv, "im_sub_pub_cpp");
ros::NodeHandle nh_;
std::string foldername;
std::string imagename;
std::string si_name;
ros::param::get("/size_name", si_name);
ros::param::get("/foldername", foldername);
ros::param::get("/image_name", imagename);
std::cout<<imagename<<std::endl;
std::cout<<foldername<<std::endl;
std::cout<<si_name<<std::endl;
std::cout<<"hi"<<std::endl;
}
Then this works.

How to call a ROS service with a launch file every time press the joystick to control UUV vehicle in Gazebo simulation?

Im using Gazebo 9 and ROS melodic for some UUV Simulation. I created a ROS Service that pass the IMU sensors values from the Server to Client. Now I would like to use this service as a sensor feedback to the controller every time I control the UUV( means every time I press the joystick). Here are the Server and Client Node and the .srv files first
Server
#include "ros/ros.h"
#include <sensor_msgs/Imu.h>
#include "imu_service/ImuValue.h"
ros::ServiceServer service;
double current_x_orientation_s;
double get_imu_orientation_x;
bool get_val(imu_service::ImuValue::Request &req, imu_service::ImuValue::Response &res)
{
ROS_INFO("sending back response");
res.current_x_orientation_s = get_imu_orientation_x;
//.. same for the other IMU values
}
void imuCallback(const sensor_msgs::ImuConstPtr& msg)
{
current_x_orientation_s= msg->orientation.x;
get_imu_orientation_x=current_x_orientation_s;
// ..same for other IMU values
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "imu_status_server");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/thrbot/imu", 10, imuCallback);
service = n.advertiseService("imu_status_server", get_val);
ROS_INFO("Starting server...");
ros::spin();
return 0;
}
the Client is here
#include "ros/ros.h"
#include "ros_services/ImuValue.h"
#include <cstdlib>
#include <sensor_msgs/Joy.h>
ros::ServiceClient client;
void joystick_callback(const sensor_msgs::Joy::ConstPtr& joy)
{
auto button_pressed = joy->buttons[0]; // 0 is the 'A' button on a wired xbox 360 controller
if(button_pressed){
ros_services::ImuValue srv;
client.call(srv);
std::cout << "Got accel x: " << srv.response.current_x_orientation_s << std::endl;
}
}
int main(int argc, char **argv)
{
ros::init(argc,argv,"imu_client_node");
ros::NodeHandle n;
ros::NodeHandle nh_;
ros::Subscriber joy_sub_ = nh_.subscribe<sensor_msgs::Joy>("joy", 10, joystick_callback);
client = n.serviceClient<ros_services::ImuValue>("imu_status_server");
ros_services::ImuValue srv;
client.call(srv);
std::cout << "Got accel x: " << srv.response.current_x_orientation_s << std::endl;
if (client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.current_x_orientation_s);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
the srv file
float64 current_x_orientation_c
---
float64 current_x_orientation_s
bool success
And the control launch file is here
<launch>
<arg name="namespace" default="thrbot"/>
<arg name="joy_id" default="0"/>
<arg name="axis_x" default="4"/>
<arg name="axis_y" default="3"/>
<arg name="axis_z" default="1"/>
<arg name="axis_yaw" default="0"/>
<arg name="gui_on" default="true"/>
<include file="$(find thrbot_control)/launch/start_thruster_manager.launch">
<arg name="uuv_name" value="$(arg namespace)"/>
</include>
<node name="joy_node" pkg="joy" type="joy_node">
</node>
<group ns="$(arg namespace)">
<rosparam file="$(find thrbot_control)/config/inertial.yaml" command="load"/>
<rosparam file="$(find thrbot_control)/config/vel_pid_control.yaml" command="load"/>
<node pkg="uuv_control_cascaded_pid" type="AccelerationControl.py" name="acceleration_control"
output="screen">
<param name="tf_prefix" type="string" value="$(arg namespace)/" />
</node>
<node pkg="uuv_control_cascaded_pid" type="VelocityControl.py" name="velocity_control"
output="screen">
<remap from="odom" to="pose_gt"/>
</node>
</group>
<include file="$(find uuv_teleop)/launch/uuv_teleop.launch">
<arg name="uuv_name" value="$(arg namespace)"/>
<arg name="joy_id" value="$(arg joy_id)"/>
<arg name="output_topic" value="cmd_vel"/>
<arg name="message_type" value="twist"/>
<arg name="axis_yaw" value="$(arg axis_yaw)"/>
<arg name="axis_x" value="$(arg axis_x)"/>
<arg name="axis_y" value="$(arg axis_y)"/>
<arg name="axis_z" value="$(arg axis_z)"/>
<arg name="gain_yaw" default="0.1"/>
<arg name="gain_x" default="0.2"/>
<arg name="gain_y" default="0.2"/>
<arg name="gain_z" default="0.2"/>
<!--arg name="gain_yaw" default="0.1"/> -->
<!--arg name="gain_x" default="0.2"/> -->
<!--arg name="gain_y" default="0.2"/> -->
<!--arg name="gain_z" default="0.2"/> -->
</include>
Any help?
Since you want to use a joystick input to trigger events in ros I would say to use the joy package and just add it to your launch file like so:
<node name="joy_node" pkg="joy" type="joy_node">
</node>
Then you just need to setup a subscriber in your client to handle joystick input and call the service appropriately like so
joy_sub_ = nh_.subscribe<sensor_msgs::Joy>("joy", 10, joystick_callback, this);
and the callback
void joystick_callback(const sensor_msgs::Joy::ConstPtr& joy)
{
auto button_pressed = joy->buttons[0]; // 0 is the 'A' button on a wired xbox 360 controller
if(button_pressed){
imu_service::ImuValue srv;
client.call(srv);
std::cout << "Got accel x: " << srv.response.current_x_orientation_s << std::endl;
}
}
Note that the above code assumes client is a global variable.

Can't modify global integer variable with user input from a GtkSpinButton widget

I wrote a simple program using GTK and glade to allow the user to enter a number in a GtkSpinButton. Once the user hits the enter key (activate signal) the global variable should be changed to whatever the user entered in. Unfortunately that doesn't work and when I print out the global variable in the main function it simply spits out a zero. When I did this same thing with a string and a GtkEntry box it worked just fine. Here is the source code:
//gtkspinbox test program
// g++ -rdynamic -c lol.cpp $(pkg-config --cflags --libs gtk+-3.0 gmodule-2.0)
// g++ lol.o -o lol $(pkg-config --cflags --libs gtk+-3.0 gmodule-2.0)
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <math.h>
#include <ctype.h>
using namespace std;
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>
#include <limits>
#include <cmath>
#include <regex>
GtkWidget *lolwindow;
GtkWidget *lolfixed;
GtkWidget *lolentry;
GtkBuilder *builder;
int lol;
extern "C" void on_lolentry_activate(GtkEntry *e, gpointer user_data){
lol = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(lolentry));
gtk_widget_destroy(lolwindow);
}
int main(int argc, char **argv){
gtk_init(&argc, &argv);//initializes gtk
builder = gtk_builder_new_from_file ("lol.glade");//reads the xml file generated by glade
gtk_builder_connect_signals(builder, NULL);
lolwindow = GTK_WIDGET(gtk_builder_get_object(builder, "lolwindow"));
g_signal_connect(lolwindow, "destroy", G_CALLBACK(gtk_main_quit), NULL);
lolfixed = GTK_WIDGET(gtk_builder_get_object(builder, "lolfixed"));
lolentry = GTK_WIDGET(gtk_builder_get_object(builder, "lolentry"));
gtk_widget_show(lolwindow);
gtk_main();
cout << lol << "\n";
}
and the glade file
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="lower">1</property>
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkWindow" id="lolwindow">
<property name="can_focus">False</property>
<property name="title" translatable="yes">enter a number lmao</property>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkFixed" id="lolfixed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkSpinButton" id="lolentry">
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment1</property>
<signal name="activate" handler="on_lolentry_activate" swapped="no"/>
</object>
<packing>
<property name="x">161</property>
<property name="y">95</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Thanks for the help!
Apparently the maximum value of the adjustment variable in glade was set to zero and that's why the global variable was being set to zero. Once I entered a different value for the maximum value the problem went away.

Segfault when clicking menu in QT

I'm pretty new to QT development, and I'm trying to create my first window with a menu. The problem is that I get a segmentation fault whenever I actually click on the File menu when trying to debug it.
This is QT 5.10, running on Fedora Linux 64-bit
My header file has:
private:
QApplication app;
Ui::MainWindow ui;
QMainWindow mainWindow;
public:
explicit ProgName(int argc, char *argv[], QObject *parent = nullptr);
int run();
...and the rest is just standard QT boilerplate omitted for brevity. My main source file:
#include "progname.h"
int main(int argc, char *argv[])
{
ProgName pn(argc, argv, nullptr);
return pn.run();
}
ProgName::ProgName(int argc, char *argv[], QObject *parent) :
QObject(parent),
app(argc, argv)
{
ui.setupUi(&mainWindow);
}
int ProgName::run()
{
mainWindow.show();
return app.exec();
}
And the really long one, the UI file, made with QT creator:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QTreeView" name="mainTreeView"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="mainMenuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>28</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
</widget>
<addaction name="menuFile"/>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Any ideas?
Edit: Here's the stack trace:
1 __strlen_avx2 0x7ffff5832c37
2 QCoreApplication::arguments() 0x7ffff6a7a63b
3 argv0BaseName() 0x7fffe88d0101
4 QXcbIntegration::wmClass() const 0x7fffe88d05fd
5 QXcbWindow::create() 0x7fffe88e596b
6 QXcbIntegration::createPlatformWindow(QWindow *) const 0x7fffe88d153e
7 QWindowPrivate::create(bool, unsigned long long) 0x7ffff6fd32fe
8 QWidgetPrivate::create_sys(unsigned long long, bool, bool) 0x7ffff7714ced
9 QWidget::create(unsigned long long, bool, bool) 0x7ffff77153ad
10 QMenuPrivate::adjustMenuScreen(QPoint const&) 0x7ffff785bf68
11 QMenu::popup(QPoint const&, QAction *) 0x7ffff785f801
12 QMenuBarPrivate::popupAction(QAction *, bool) 0x7ffff786c402
13 QMenuBarPrivate::setCurrentAction(QAction *, bool, bool) 0x7ffff786e508
14 QMenuBar::mousePressEvent(QMouseEvent *) 0x7ffff786ee72
15 QWidget::event(QEvent *) 0x7ffff7722baf
16 QMenuBar::event(QEvent *) 0x7ffff787014b
17 QApplicationPrivate::notify_helper(QObject *, QEvent *) 0x7ffff76e392c
18 QApplication::notify(QObject *, QEvent *) 0x7ffff76eb6cf
19 QCoreApplication::notifyInternal2(QObject *, QEvent *) 0x7ffff6a76be7
20 QApplicationPrivate::sendMouseEvent(QWidget *, QMouseEvent *, QWidget *, QWidget *, QWidget * *, QPointer<QWidget>&, bool) 0x7ffff76ea6a2
21 QWidgetWindow::handleMouseEvent(QMouseEvent *) 0x7ffff773d47b
22 QWidgetWindow::event(QEvent *) 0x7ffff773fb1f
23 QApplicationPrivate::notify_helper(QObject *, QEvent *) 0x7ffff76e392c
24 QApplication::notify(QObject *, QEvent *) 0x7ffff76eb174
25 QCoreApplication::notifyInternal2(QObject *, QEvent *) 0x7ffff6a76be7
26 QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *) 0x7ffff6fc98a3
27 QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *) 0x7ffff6fcb495
28 QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x7ffff6fa479b
29 userEventSourceDispatch(_GSource *, int ( *)(void *), void *) 0x7fffe892cb60
30 g_main_context_dispatch 0x7ffff2195b77
31 g_main_context_iterate.isra 0x7ffff2195f20
32 g_main_context_iteration 0x7ffff2195fac
33 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x7ffff6ac7c2f
34 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) 0x7ffff6a7596a
35 QCoreApplication::exec() 0x7ffff6a7e094
36 ProgName::run progname.cpp 21 0x401aaf
37 main progname.cpp 7 0x401961
Please have a look at the constructors of QCoreApplication and QApplication.
The constructors expect the argc argument to be a reference to an integer.
In your case, you pass the argc argument by value to the constructor of your ProgName class. Inside, you pass a reference to this (local) value down to the constructor of QApplication. The issue is that the reference will be invalid/dangling, as soon as the constructor call is finished. In particular, when calling exec() later in the run method, the application object will try to access the reference which fails and produces the observed crash.
Long story short: as a workaround, just pass through the argc argument as a reference:
ProgName::ProgName(int &argc, char *argv[], QObject *parent) :
QObject(parent),
app(argc, argv)
{
ui.setupUi(&mainWindow);
}