QScrollArea and QVBoxLayout issues with dynamically added widgets - qt

Im running into a weird issue with dynamically added widgets to a QVBoxLayout contained inside a QScrollArea. If I add the widgets it works as expected, however after all widgets are removed, there are still some artifacts on the screen. See screenshot bellow:
See the code bellow:
ui_mainwindow.h
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.2.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QScrollArea>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QVBoxLayout *verticalLayout_2;
QScrollArea *scrollArea;
QWidget *scrollAreaWidgetContents;
QHBoxLayout *horizontalLayout_2;
QVBoxLayout *verticalLayout;
QPushButton *pushButton;
QPushButton *pushButton_2;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(600, 396);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
verticalLayout_2 = new QVBoxLayout(centralWidget);
verticalLayout_2->setSpacing(6);
verticalLayout_2->setContentsMargins(11, 11, 11, 11);
verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
scrollArea = new QScrollArea(centralWidget);
scrollArea->setObjectName(QStringLiteral("scrollArea"));
scrollArea->setWidgetResizable(true);
scrollAreaWidgetContents = new QWidget();
scrollAreaWidgetContents->setObjectName(QStringLiteral("scrollAreaWidgetContents"));
scrollAreaWidgetContents->setGeometry(QRect(0, 0, 574, 246));
horizontalLayout_2 = new QHBoxLayout(scrollAreaWidgetContents);
horizontalLayout_2->setSpacing(6);
horizontalLayout_2->setContentsMargins(11, 11, 11, 11);
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
verticalLayout = new QVBoxLayout();
verticalLayout->setSpacing(6);
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
horizontalLayout_2->addLayout(verticalLayout);
scrollArea->setWidget(scrollAreaWidgetContents);
verticalLayout_2->addWidget(scrollArea);
pushButton = new QPushButton(centralWidget);
pushButton->setObjectName(QStringLiteral("pushButton"));
verticalLayout_2->addWidget(pushButton);
pushButton_2 = new QPushButton(centralWidget);
pushButton_2->setObjectName(QStringLiteral("pushButton_2"));
verticalLayout_2->addWidget(pushButton_2);
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QStringLiteral("menuBar"));
menuBar->setGeometry(QRect(0, 0, 600, 22));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QStringLiteral("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
pushButton->setText(QApplication::translate("MainWindow", "add one", 0));
pushButton_2->setText(QApplication::translate("MainWindow", "remove one", 0));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
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 on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->verticalLayout->addWidget(new QLabel("This is a label", this));
qDebug() << "Labels count: " << ui->verticalLayout->count();
}
void MainWindow::on_pushButton_2_clicked()
{
delete ui->verticalLayout->takeAt(0);
qDebug() << "Labels count: " << ui->verticalLayout->count();
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

It seems like I also have to remove the QLayoutItem AND the Widget, just removing the widget or the QLayoutItem (which I did try) doesn't work, both have to be removed, like so:
QLayoutItem *child = ui->verticalLayout->takeAt(0);
if (child)
{
delete child->widget();
delete child;
}

Related

When moved a QDialog to another monitor and close it, the dialog will be blank after reopened

Env: Win10+Qt5.12.3(msvc)
code:
pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test
TEMPLATE = app
SOURCES += \
dialog.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
dialog.h \
mainwindow.h
FORMS += \
dialog.ui \
mainwindow.ui
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDialog>
#include "dialog.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void slot_btn_clicked();
private:
Ui::MainWindow *ui;
Dialog *dialog;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
dialog = new Dialog(this);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(slot_btn_clicked()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slot_btn_clicked()
{
dialog->exec();
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QCloseEvent>
#include <QShowEvent>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
protected:
void closeEvent(QCloseEvent *e);
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
Dialog::Dialog(QWidget *parent)
: QDialog(parent), ui(new Ui::Dialog)
{
ui->setupUi(this);
QVBoxLayout *layout = new QVBoxLayout(this);
QLabel *label = new QLabel(this);
label->setText("this is a label");
layout->addWidget(label);
QPushButton *btnaccept= new QPushButton(this);
btnaccept->setText("accept");
connect(btnaccept, &QPushButton::clicked, this, [=](){accept();});
layout->addWidget(btnaccept);
QPushButton *btnclose= new QPushButton(this);
btnclose->setText("close");
connect(btnclose, &QPushButton::clicked, this, [=](){close();});
layout->addWidget(btnclose);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::closeEvent(QCloseEvent *e)
{
qDebug() << __FUNCTION__;
QDialog::closeEvent(e);
//e->ignore(); // if ignored close event, working well.
//accept();
}
demo code pack
Video presentation
I found that a method of closing QDialog will cause this situation: close button in title bar(top-right corner of the dialog), if closing it by reject(), accept(), close() everything is working correctly.
There is another question which is similar with mine, but I think the answer (resize the dialog manually) is not perfect, is there any another solution?

How to reuse the same window after clicking on other button?

I am trying to create an image viewer with slide show. When the user clicks on the play button, the viewer starts to show images. When the the user clicks on the stop button, the viewer stops to show images. After stopping, when the user clicks on the play button again, the viewer will continue to show the remaining images. My problem is that when the user clicks on the stop button and click on the play button again, I don't know how to reuse the same window created at the beginning to show the remaining images.
Button3 is the play button.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileSystemModel>
#include "showpic.h"
#include <QBasicTimer>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_3_clicked();
void tick();
void on_pushButton_4_clicked();
private:
Ui::MainWindow *ui;
QFileSystemModel *model;
QString filesPath;
ShowPic *showpic;
QStringList filenames;
QStringList::const_iterator m_imageIt;
QTimer m_timer;
};
#endif // MAINWINDOW_H
showpic.h
#ifndef SHOWPIC_H
#define SHOWPIC_H
#include <QWidget>
namespace Ui {
class ShowPic;
}
class ShowPic : public QWidget
{
Q_OBJECT
public:
explicit ShowPic(QWidget *parent = 0);
~ShowPic();
private:
Ui::ShowPic *ui;
public:
void addPixmap(const QPixmap &pixmap);
};
#endif // SHOWPIC_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
#include<QFileSystemModel>
#include<QStringList>
#include <QTreeView>
#include <QGraphicsScene>
#include <QTime>
#include <QDebug>
#include <iostream>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
filenames.append("C:\\test\\image.jpg");
filenames.append("C:\\test\\apple.jpg");
filenames.append("C:\\test\\orange.jpg");
filenames.append("C:\\test\\lemon.jpg");
filenames.append("C:\\test\\grape.jpg");
m_timer.setInterval(1000);
connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::tick(){
showpic->addPixmap(*m_imageIt);
m_imageIt ++;
if(m_imageIt == filenames.end()){
m_timer.stop();
m_imageIt = filenames.begin();
}
}
void MainWindow::on_pushButton_3_clicked() //click on the play button
{
if(!filenames.isEmpty()){ // initial click
showpic = new ShowPic();
m_timer.start();
showpic->setWindowState(Qt::WindowMaximized);
showpic->show();
} else if( ) { // click on the play button again,
m_timer.start(); //???
showpic->setWindowState(Qt::WindowMaximized); //???
showpic->show(); //???
}
}
void MainWindow::on_pushButton_4_clicked() // click on the stop button
{
m_timer.stop();
}
showpic.cpp
#include "showpic.h"
#include "ui_showpic.h"
ShowPic::ShowPic(QWidget *parent) :
QWidget(parent),
ui(new Ui::ShowPic)
{
ui->setupUi(this);
ui->graphicsView->setScene(new QGraphicsScene);
ui->horizontalLayout->addWidget(ui->graphicsView);
this->setLayout(ui->horizontalLayout);
}
ShowPic::~ShowPic()
{
delete ui;
}
void ShowPic::addPixmap(const QPixmap &pixmap){
ui->horizontalLayout->addWidget(ui->graphicsView);
this->setLayout(ui->horizontalLayout);
ui->graphicsView->setScene(new QGraphicsScene);
ui->graphicsView->scene()->addPixmap(pixmap);
ui->graphicsView->fitInView(ui->graphicsView->scene()->itemsBoundingRect() ,Qt::KeepAspectRatio);
}
Else part of on_pushButton_3_clicked won't run in any case because filenames is being filled when MainWindow created. In your code, you're creating new showpic in every click.
Firstly, set showpic to NULL in constructor of MainWindow;
showpic = NULL;
And change on_pushButton_3_clicked method like this;
void MainWindow::on_pushButton_3_clicked() //click on the play button
{
if(showpic == NULL){
showpic = new ShowPic();
}
if(!showpic->isVisible()){
showpic->setWindowState(Qt::WindowMaximized);
showpic->show();
}
m_timer.start();
}
Lastly, i don't have QT now, so my answer may contains typo/syntax error.
This works for me. I tested the scene clearing method, and it worked fine for me. But here I decided to just store the pointer to the QGraphicsPixmapItem as a member variable, and just set a new pixmap to it, instead of clearing the scene constantly. Seems more elegant like this to me.
#include <QtWidgets>
class SlideView : public QWidget
{
Q_OBJECT
public:
SlideView(QWidget *parent = nullptr) : QWidget(parent)
{
setLayout(new QHBoxLayout);
layout()->addWidget(&view);
view.setScene(new QGraphicsScene(this));
pixmap_item = new QGraphicsPixmapItem;
view.scene()->addItem(pixmap_item);
}
void setPixmap(const QPixmap &pixmap)
{
pixmap_item->setPixmap(pixmap);
view.fitInView(view.scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
}
private:
QGraphicsView view;
QGraphicsPixmapItem *pixmap_item = nullptr;
};
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr) : QWidget(parent)
{
slide_iterator = slides.begin();
setLayout(new QHBoxLayout);
QPushButton *play_button = new QPushButton("Play");
QPushButton *stop_button = new QPushButton("Stop");
layout()->addWidget(play_button);
layout()->addWidget(stop_button);
connect(play_button, &QPushButton::clicked, this, &MainWidget::play);
connect(stop_button, &QPushButton::clicked, this, &MainWidget::stop);
connect(&timer, &QTimer::timeout, this, &MainWidget::showNextSlide);
}
public slots:
void play() {timer.start(1000); view.showMaximized(); view.activateWindow();}
void stop() {timer.stop();}
void showNextSlide()
{
QPixmap pixmap(*slide_iterator);
view.setPixmap(pixmap);
slide_iterator++;
if(slide_iterator == slides.end())
slide_iterator = slides.begin();
}
private:
QTimer timer;
QStringList slides{"one.png", "two.png", "three.png"};
QStringList::const_iterator slide_iterator;
SlideView view;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget w;
w.show();
return a.exec();
}
#include "main.moc"

Qt3 vs Qt5 programming syntax

Hi I'm teaching myself Qt based on Qt 5.7.0 (MSVC 2013, 32 bit), Qt Creator 4.1.0 - community edition. I am using an book, "Programming with Qt, 2nd Edition" by Matthias Kalle Dalheimer which focuses on QT3. One of the exercises is to have a slider which uses the LCD number display. There are also two buttons (add, subtract) to change the slider and LCD display. I was not able to get the book code to work because there have been major syntax changes.
I was able to get my code to work using the Qt designer but I want to do it without that as well. How can I do that? I was thinking of using events but I couldn't figure out the syntax.
Here is the snippets from the book.
QObject::connect(decrement, SIGNAL(clicked()), myslider, SLOT(subtractStep()));
QObject::connect(increment, SIGNAL(clicked()), myslider, SLOT(addStep()));
These are the error messages from the console for my code below in main.cpp:
"QObject::connect: No such slot QSlider::SingleStep()in ..\ProgrammingQt\main.cpp:31
QObject::connect: No such signal QSlider::triggerAction(SliderSingleStepAdd) in ..\ProgrammingQt\main.cpp:32"
Here is my code without the ui. - main.cpp
#include <iostream>
#include <qapplication.h>
#include <qwidget.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qpushbutton.h>
#include <qstring.h>
using namespace std;
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QWidget *widget = new QWidget();
widget->setGeometry(400, 300, 170, 150);
QSlider *slider = new QSlider(Qt::Horizontal, widget);
slider->setGeometry(10, 10, 150,30);
QLCDNumber *lcd = new QLCDNumber(2, widget);
lcd->setGeometry(60, 50, 50, 50);
lcd->display(1);
QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
QPushButton *addBtn = new QPushButton("ADD ONE", widget);
addBtn->setGeometry(10, 110, 50, 30);
//QObject::connect(addBtn, SIGNAL(clicked(bool)), slider, SLOT(SliderSingleStepAdd()));
//QObject::connect(addBtn, SIGNAL(clicked(bool)), slider, SLOT(SingleStep()));
//QObject::connect(slider, SIGNAL(triggerAction(SliderSingleStepAdd)), lcd, SLOT(display(int)));
QPushButton *minusBtn = new QPushButton("MINUS ONE", widget);
minusBtn->setGeometry(100, 110, 60, 30);
// QObject::connect(minusBtn, SIGNAL(clicked(bool)), slider, SLOT (SliderSingleStepSub()));
QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
widget->setWindowTitle("LCD Number");
widget->show();
return app.exec();
}
Here is the code using the Qt Designer: 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_slider_valueChanged(int value)
{
ui->lcd->display(value);
}
void MainWindow::on_addBtn_clicked()
{
int incVal = ui->slider->value();
incVal++;
ui->slider->setValue(incVal);
ui->lcd->display(incVal);
}
void MainWindow::on_minusBtn_clicked()
{
int decVal = ui->slider->value();
decVal--;
ui->slider->setValue(decVal);
ui->lcd->display(decVal);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSlider>
#include <QLCDNumber>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_slider_valueChanged(int value);
void on_addBtn_clicked();
void on_minusBtn_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
The slots SliderSingleStepAdd, SingleStep or SliderSingleStepSub are not found because there are not defined in the object slider.
According to the documentation,
All classes that inherit from QObject or one of its subclasses (e.g.,
QWidget) can contain signals and slots.
So you need a class where you must implement your required signals and slots.
For example, your main should be something like this:
#include <iostream>
#include <qapplication.h>
#include <qwidget.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <myclass.h>
using namespace std;
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MyClass myClass;
QWidget *widget = new QWidget();
widget->setGeometry(400, 300, 170, 150);
QSlider *slider = new QSlider(Qt::Horizontal, widget);
slider->setGeometry(10, 10, 150,30);
QLCDNumber *lcd = new QLCDNumber(2, widget);
lcd->setGeometry(60, 50, 50, 50);
lcd->display(1);
QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
QPushButton *addBtn = new QPushButton("ADD ONE", widget);
addBtn->setGeometry(10, 110, 50, 30);
QObject::connect(addBtn, SIGNAL(clicked(bool)), &myClass, SLOT(SliderSingleStepAdd()));
QObject::connect(addBtn, SIGNAL(clicked(bool)), &myClass, SLOT(SingleStep()));
// QObject::connect(slider, SIGNAL(triggerAction(SliderSingleStepAdd)), lcd, SLOT(display(int)));
QPushButton *minusBtn = new QPushButton("MINUS ONE", widget);
minusBtn->setGeometry(100, 110, 60, 30);
QObject::connect(minusBtn, SIGNAL(clicked(bool)), &myClass, SLOT(SliderSingleStepSub()));
QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
widget->setWindowTitle("LCD Number");
widget->show();
return app.exec();
}
And you should have a class like the following one:
#ifndef MYCLASS_H
#define MYCLASS_H
#include <iostream>
#include <QObject>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(): QObject() {}
virtual ~MyClass() {}
public slots:
void SliderSingleStepAdd ()
{
std::cout << "SliderSingleStepAdd" << std::endl;
}
void SingleStep ()
{
std::cout << "SingleStep" << std::endl;
}
void SliderSingleStepSub ()
{
std::cout << "SliderSingleStepSub" << std::endl;
}
};
#endif // MYCLASS_H
In my opinion, all your objects (slider, lcd and buttons) should be in a class that inherits from QWidget so you can connect those objects. This should be also necessary in case of the following connect:
QObject::connect(slider, SIGNAL(triggerAction(SliderSingleStepAdd)), lcd, SLOT(display(int)));

how to use ui file for making a simple widget?

i have a simple window with a quit button in qt.The working code is shown below
#include <QApplication>
#include <QDialog>
#include <QPushButton>
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
};
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
setFixedSize(200, 120);
QPushButton *btquit = new QPushButton(tr("Quit"), this);
btquit->setGeometry(62, 40, 75, 30);
btquit->setFont(QFont("Times", 18, QFont::Bold));
connect(btquit, SIGNAL(clicked()), qApp, SLOT(quit()));
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
Now i want to code this program using qt designer.I created a widget named "mywindow" and a button inside that main widget named "btquit" in the ui file using qt designer.
How to rewrite the above code with the ui file.The name of ui file is mywindow.ui
#include <QApplication>
#include <QDialog>
#include <QPushButton>
#include "ui_mywindow1.h"
class MyWidget : public QWidget,private Ui::mywindow
{
public:
MyWidget(QWidget *parent = 0);
};
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
connect(btquit, SIGNAL(clicked()), qApp, SLOT(quit()));
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
I prefer to have the ui as private member in the widget's class. I assume that in the designer you have named the widget as mywindow (the objectName from the properties).
// MyWindow.h
#include <QWidget>
// Forward declaration of your ui widget
namespace Ui {
class mywindow;
}
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
~MyWidget();
private:
// private pointer to your ui
Ui::mywidget *ui;
};
And then in your .cpp you have to do the following:
#include "mywindow.h"
//1. Include the auto generated h file from uic
#include "ui_mywindow.h"
#include <QPushButton>
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent),
//2. initialize the ui
ui(new Ui::mywindow)
{
//3. Setup the ui
ui->setupUi(this);
// your code follows
setFixedSize(200, 120);
QPushButton *btquit = new QPushButton(tr("Quit"), this);
btquit->setGeometry(62, 40, 75, 30);
btquit->setFont(QFont("Times", 18, QFont::Bold));
connect(btquit, SIGNAL(clicked()), qApp, SLOT(quit()));
}
MyWidget::~Mywidget()
{
delete ui;
}

qt specific implementation

I have this snippet of the code:
#include <QApplication>
#include <QFont>
#include <QLCDNumber>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
#include <QWidget>
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
};
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *quit = new QPushButton(tr("Quit"));
quit->setFont(QFont("Times", 18, QFont::Bold));
QLCDNumber *lcd = new QLCDNumber(3);
lcd->setSegmentStyle(QLCDNumber::Flat);
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 999);
slider->setValue(0);
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)))
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
when I reach the max of the interval, I want to quit, how can I implement this with signals and slots, thanks in advance
Add one more slot-function to your MyWidget class, for example on_maximum_exit(int) like that:
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
public slots:
void on_maximum_exit(int );
};
Define new function:
void MyWidget::on_maximum_exit(int value)
{
if (value == slider->maximum())
close();
}
In MyWidget consctuctor, after connect(slider, SIGNAL(valueChanged(int)),... add:
/* ... */
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_maximum_exit(int)));
/* ... */
And of course use Qt docs!
Like I said in the other post this should work for you:
main.cpp
#include <QApplication>
#include "mywidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QObject>
include <QPushButton>
#include <QSlider>
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
~MyWidget(){};
public slots:
void getSliderValueAndQuit();
private:
QPushButton *quit;
QSlider *slider;
};
#endif // MYWIDGET_H
myWidget.cpp
#include "mywidget.h"
#include <QWidget>
#include <QObject>
#include <QApplication>
#include <QFont>
#include <QLCDNumber>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent)
{
quit = new QPushButton(tr("Quit"));
quit->setFont(QFont("Times", 18, QFont::Bold));
QLCDNumber *lcd = new QLCDNumber(3);
lcd->setSegmentStyle(QLCDNumber::Flat);
slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 999);
slider->setValue(0);
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
connect(slider, SIGNAL(valueChanged(int)),lcd, SLOT(display(int)));
connect(slider,SIGNAL(sliderReleased()), SLOT(getSliderValueAndQuit()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}
void MyWidget::getSliderValueAndQuit(){
if(slider->value() == slider->maximum())
close();
}

Resources