opening new window from a window QT? - c++

I have two classes both define under QDialog class.
Both classes individually are working properly and opening their respective window but what i want is that from one window there is an action in the menubar ,which on clicking open the other window.
codes for the classes defined are
class 1
class Box : public QDialog
{
Q_OBJECT
public:
Box(QWidget *parent=0);
private slots:
void refresh();
signals:
void itemChanged(QStandardItem *);
private:
void create_frame();
void create_menu();
QGroupBox *tablegroup;
QDialogButtonBox *buttonbox;
QAction *help;
QAction *exit;
QAction *idseacrh;
QAction *idsearch;
QMenu *file;
QMenu *search;
QMenuBar *menubar;
QTableView *table;
};
CLASS 2
class Box1 : public QDialog
{
Q_OBJECT
public:
Box1(QWidget *parent=0);
private:
QLineEdit *text;
QLabel *searchh;
QDialogButtonBox *buttonboxx;
QTableView *tablee;
QGroupBox *tableegroup;
QGroupBox *searchgroup;
};
The action will be there in Box which will open Box1.
_I HAVE IMAGE ALSO FOR BOTH THE _ window which i have created and tried to upload but it says i need 10 reputations to do this,so i wasnt able to do it.

I don't get it. If i understood the question, you just need to connect QAction from your QMenuBar to function which will correspond for creating new window with Box1 widget. Here you are simple example of how to do it:
void Box::newDialog()
{
QVBoxLayout* lay = new QVBoxLayout;
Box1* temp = new Box1(this);
lay->addWidget(temp);
QDialog dialog(this);
dialog.setModal(true);
dialog.setLayout(lay);
dialog.setWindowTitle("Box1");
dialog.exec();
}
And
connect(Box1Action, SIGNAL(triggered()), this, SLOT(newDialog()));
or simpler:
myMenu->addAction(tr("Create Box1 Window"), this, SLOT(newDialog()));

Related

Menu with QGraphicsView and QGraphicsProxyWidget in C++

I would like to put a window adapted to the size of my screen which would contain a menu. My menu is a QWidget that contains QPushButton :
class Menu : public QWidget
{
Q_OBJECT
private :
QPushButton* _menu1;
QPushButton* _menu2;
public:
Menu();
~Menu();
};
For that I use a QGraphicsView with a QGraphicsScene and my menu being a QWidget, I use a QGraphicsProxyWidget to integrate it to my scene :
myView.h :
class myView : public QGraphicsView
{
private :
QGraphicsScene* _scene;
Menu* _menu;
QGraphicsProxyWidget* _proxy;
public:
HomeView();
~HomeView();
};
and in myView.cpp :
_scene = new QGraphicsScene();
_menu = new Menu();
_proxy = new QGraphicsProxyWidget();
_proxy->setWidget(_menu);
this->setScene(_scene);
_scene->addItem(_proxy);
this->showFullScreen();
And when I hover over my menu, the effects showing that I am hovering over the menu are very slow, for example when I hover from _menu1 to _menu2 there is a few seconds delay. Is it because I am using a QGraphicsProxyWidget? Is there another way to do it with a QGraphicsView?
I use Qt5 and C++.
Thank you in advance.

C++ Qt inherit from custom widget

I'm working on a project with Qt and C++.
Now my Question is:
Is inheritance possible in UI classes?
For example: This is the Widget I want to inherit from
//windowA.h
namespace Ui {
class WindowA;
}
class WindowA : public QWidget
{
Q_OBJECT
public:
explicit WindowA(QWidget *parent = nullptr);
~AddWindow();
QPushButton *button;
};
//windowA.cpp
WindowA::WindowA(QWidget *parent) :
QWidget(parent)
{
button = new QPushButton();
button->setText("Save");
connect(button, SIGNAL (clicked()), this, SLOT (//slot));
QGridLayout *layout = new QGridLayout();
layout->addWidget(button, 0, 0);
this->setLayout(layout);
}
This is the widget that inherits from WindowA
//windowB.h
namespace Ui {
class WindowB;
}
class WindowB : public WindowA
{
Q_OBJECT
public:
explicit WindowB(QWidget *parent = nullptr);
~WindowB();
};
How would I implement a QPushButton, so that it's possible to set different text in both classes?
I can add a QPushButton but the text set in WindowA would also be set in WindowB. The problem is to set a different text for the button in WindowB than it is set for the button in WindowA
If I understand your question correctly, all you need to do is change what text you set on the button in your constructor:
WindowB::WindowB(QWidget *parent) :
WindowA(parent)
{
button->setText("Something else!");
}

How to detect that the close button of QWidget is pressed?

I create a new QWidget object and I want to know when the close button is pressed.
I have tried the following code:
pWindow = new QWidget();
connect(pWindow , SIGNAL(triggered()), this, SLOT(processCloseButtonWindowsClicked()));
but it give an error:
no signal triggered of pWindow
How to achieve this?
Cause
QWidget does not have a triggered signal.
Solution
I would suggest you to:
Subclass QWidget and reimplement QWidget::closeEvent
Check QEvent::spontaneous to differentiate between a click of the close button and the call to QWidget::close
According to your app's logic either call QWidget::closeEvent(event); to close the widget, or QEvent::ignore to leave it open
Example
I have prepared an example for you of how to implement the proposed solution:
#include <QMainWindow>
#include <QCloseEvent>
#include <QPushButton>
class FooWidget : public QWidget
{
Q_OBJECT
public:
explicit FooWidget(QWidget *parent = nullptr) :
QWidget(parent) {
auto *button = new QPushButton(tr("Close"), this);
connect(button, &QPushButton::clicked, this, &FooWidget::close);
resize(300, 200);
setWindowTitle("Foo");
}
protected:
void closeEvent(QCloseEvent *event) override {
if (event->spontaneous()) {
qDebug("The close button was clicked");
// do event->ignore();
// or QWidget::closeEvent(event);
} else {
QWidget::closeEvent(event);
}
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
FooWidget *pWindow;
public:
explicit MainWindow(QWidget *parent = nullptr) :
QMainWindow(parent),
pWindow(new FooWidget()) {
pWindow->show();
}
};
void QWidget::closeEvent(QCloseEvent *event) will be the possible way I would go with.
You can read the documentation here.
Before, check if Qt has a class for what you want to do. Maybe you want to use QDialog instead of QWidget for what you want to achieve.
The following code: suppose you want to delete the widget when the X is clicked and you just want to know when to do something.
Try connecting the signal from the base class QObject of your widget when it is Destroyed:
-Your Widget
-attribute setted to destroy your widget after X(closebotton is clicked) or the close() handler is triggered
-connect the destroyed() signal to whatever slot you want to do something before it is destroyed
pWindow = new QWidget();
pWindow->setAttribute(Qt::WA_DeleteOnClose,true);
connect(pWindow , SIGNAL(destroyed()), this,SLOT(processCloseButtonWindowsClicked()));
for more info:
https://doc.qt.io/qt-5/qwidget.html#close
https://doc.qt.io/qt-5/qobject.html#destroyed

Qt, OpenGL Widget, no such slot

I wanted to create a simple application where there's triangle generated using OpenGL and three push buttons changing that triangle color. The triangle is generated but unfortunately buttons don't work and I get errors saying:
QObject::connect: No such slot MainWindow::redSlot(OGL) in
..\buttonwidget\mainwindow.cpp:17 QObject::connect: No such slot
MainWindow::greenSlot(OGL) in ..\buttonwidget\mainwindow.cpp:20
QObject::connect: No such slot MainWindow::blueSlot(OGL) in
..\buttonwidget\mainwindow.cpp:23
I have slots definitions:
void MainWindow::redSlot(Widget* w)
{
w->setColor(red);
}
void MainWindow::greenSlot(Widget* w)
{
w->setColor(green);
}
void MainWindow::blueSlot(Widget* w)
{
w->setColor(blue);
}
They are changing variable declared in class Widget that changes color of a generated triangle. Here's class Widget:
class Widget : public QGLWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
QSize minimumSizeHint() const;
QSize sizeHint() const;
enum color c;
void setColor(enum color color1);
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
};
And then I connect slots to buttons in class MainWindow constructor:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
layout = new QVBoxLayout();
QWidget *w = new QWidget();
setCentralWidget(w);
w->setLayout(layout);
Widget *OGL = new Widget();
//OGL->c=green; - it was a test whether changing value of enum type variable c works
//it works, changing it changes the color of a generated triangle
redButton = new QPushButton(tr("Red"));
connect(redButton, SIGNAL(clicked()), this, SLOT(redSlot(OGL)));
greenButton = new QPushButton(tr("Green"));
connect(greenButton, SIGNAL(clicked()), this, SLOT(greenSlot(OGL)));
blueButton = new QPushButton(tr("Blue"));
connect(blueButton, SIGNAL(clicked()), this, SLOT(blueSlot(OGL)));
layout->addWidget(OGL);
layout->addWidget(redButton);
layout->addWidget(greenButton);
layout->addWidget(blueButton);
}
Here's slot declaration in header:
class MainWindow : public QMainWindow
{
Q_OBJECT
QVBoxLayout *layout;
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QPushButton *redButton;
QPushButton *greenButton;
QPushButton *blueButton;
public slots:
void redSlot(Widget*);
void greenSlot(Widget*);
void blueSlot(Widget*);
};
How should I make them work?
Connects in QT are string-based, that means:
connect(redButton, SIGNAL(clicked()), this, SLOT(redSlot(OGL)));
will not work, since you havent defined a slot "redSlot(OGL)", instead you would have to use
...SLOT(redSlot(Widget*)));
Moreover, it is possible to define a SLOT with less parameter but not with more, therefore your slot/connect has to look like
void redSlot();
connect(redButton, SIGNAL(clicked()), this, SLOT(redSlot()));
if you need a pointer to the "Widget" you have to retrieve it from somewhere else.
Example: Define slot in "Widget"-class and change connect to:
connect(redButton, SIGNAL(clicked()), OGL, SLOT(redSlot()));

QT: simple text from QLineEdit to QLabel of different class

I'm trying to write a very basic program. The main window contains a label. Pressing the "Add New" button opens a QDialog with a QLineEdit. Changing the text, press "Add" and I would like the QLabel in the main window to be updated with the text from QLineEdit. I can get the signals through but the label is not updating. I understand that connect only works on instances of classes, not classes themselves. The problem seems to be the one class is not aware of the instance of the main window.
What I've tried to do is once the Add button is pressed, a signal is emitted. Once that signal is emitted, the slot in the mainWindow class receives a string to use in QLabel::setText().
I've read countless examples and documentation but the examples seem to be too different from the simple task I'm lost in. Any help is appreciated.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
#include <QLabel>
class QLineEdit;
class QPushButton;
class QLabel;
class addDlg : public QDialog{
Q_OBJECT
public:
addDlg(QWidget *parent = 0);
signals:
void textChanged(const QString &text);
private slots:
void sendText(QWidget *parent);
private:
QPushButton *addButton;
QLineEdit *inputText;
};
class mainWindow : public QWidget{
Q_OBJECT
public:
mainWindow();
QLabel *textLabel;
public slots:
void recvText(const QString &text);
private slots:
void addDlgShow();
private:
QPushButton *addWindow;
addDlg *dialog;
};
#endif // MAINWINDOW_H
MainWindow.cpp
addDlg::addDlg(QWidget *parent)
: QDialog(parent){
inputText = new QLineEdit(tr("enter here"));
addButton = new QPushButton(tr("Accept"));
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->addWidget(inputText);
vLayout->addWidget(addButton);
setLayout(vLayout);
setWindowTitle(tr("Add new text"));
connect(addButton, SIGNAL(clicked()),
this, SLOT(sendText()));
}
void addDlg::sendText(){
QString text = inputText->text();
emit textChanged(text);
// This connect is where I believe the problem lies.
connect(this, SIGNAL(textChanged(QString)),
mainPtr, SLOT(recvText(QString)));
//mainPtr is uninitialized as I can't seem to point it to the manWindow instance
//I can do mainWindow* mainPtr = new mainWindow but that just creates a new instance.
//How do I pass on the first mainWindow main instance "mainPtr" to this class addDlg?
}
mainWindow::mainWindow()
: QWidget(0){
textLabel = new QLabel(tr("Empty"));
addWindow = new QPushButton(tr("Add New"));
dialog = new addDlg();
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->addWidget(textLabel);
vLayout->addWidget(addWindow);
setLayout(vLayout);
setWindowTitle(tr("Test 4"));
connect(addWindow, SIGNAL(clicked()),
this, SLOT(addDlgShow()));
}
void mainWindow::addDlgShow(){ dialog->show(); }
void mainWindow::recvText(const QString &text){
QString input = text;
textLabel->clear();
textLabel->setText(input);
textLabel->update();
}
One solution is to put your connect code in mainWindow::mainWindow where you have pointers to both the mainwindow and your newly created dialog. The snippet might change to this:
mainWindow::mainWindow() : QWidget(0) {
// ... existing code ..
// add this
connect(dialog, SIGNAL(textChanged(QString)),
this, SLOT(recvText(QString)));
}