C++ Qt inherit from custom widget - c++

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!");
}

Related

Qt incorrectly lays widgets on top of each other

In Qt 4.8.5 32-bit and VS2010, I'm trying to create a Window as shown in this screenshot from QtDesigner:
When I run the application, the widgets get laid down on top of each other :
In the Console, I see this :
Does anybody have any idea why this is happening?
Here is my code :
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(){
ui = new Ui::AView();
ui->setupUi(this);
}
~MainWindow();
...
private:
Ui::AView* ui;
}
From the screenshot of QtDesigner, I see that your UI is for a QWidget, but you are applying it to a QMainWindow. This causes the problem, as the handling of main window is different to other widgets.
I don't know of a way to change the base class for a UI file. Maybe the best way is to create a new file, select the mainwindow template, and copy/paste the content from the old file.
Another option would be to have a QWidget, set it up with the UI, and add it as the main window's central widget:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(){
ui = new Ui::AView();
QWidget *wgt = new QWidget;
ui->setupUi(wgt);
this->setCentralWidget(wgt);
}
~MainWindow();
...
private:
Ui::AView* ui;
}
Try this:
class MainWindow : public QMainWindow, public Ui::AView
{
Q_OBJECT
public:
MainWindow(){
setupUi(this);
}
~MainWindow();
}

Creating a class that implements tabs and can be used as a "central widget" in QMainWindow

I want the central widget of my mainWindow class to be a QTabWidget. My plan is to create widgets that I want to put in the tabs as separate classes and add them to QTabWidget class and add the QtabWidget class itself as a central Widget to the mainWindow class.
To do this, how must I declare my tabWidget class ?
Should it be :
class centralTab : public QMainWindow
{
}
or
class centralTab : public QDialog
{
}
Also, in the ctor, What should be used as the parent ?
Just create QMainWindow subclass:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
//...
};
In constructor use addTab() method::
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QTabWidget *tabWidget = new QTabWidget(this);
//some settings
tabWidget->addTab(new QLabel("example1"), "General1");
tabWidget->addTab(new QLabel("example2"), "General2");
setCentralWidget(tabWidget);
}
Why QMainWindow? Because only QMainWindow has setCentralWidget() method;
You can add different widgets and set also icon to every tab, QLabel is just example.

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)));
}

opening new window from a window QT?

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()));

Create Widget in QMainWindow and load to ScrollArea

I tried to create a Mainwindow with an slot, which creates a Widget and loads it to the ScrollArea in the Mainwindow. This doesn't work, so I tired to create the Widget in the constructor of the mainwindow and I always get errors and don't know why.. so what's the right declaration of the Widget?
#include <QtGui>
class Mainwindow : public QMainWindow
{
Q_OBJECT
public:
Mainwindow(QMainWindow *parent = 0);
public slots:
private:
QScrollArea *List,*Sublist,*Overall,*Settings;
QLabel *label_title;
QPushButton *bn_exit,*bn_list,*bn_overall,*bn_settings;
};
//! ------------------------------------- Mainlist -------------------------------------
class Sublist : public QWidget{
Q_OBJECT
private:
QLabel *title;
public:
Sublist(QWidget *parent = 0);
};
and .cpp
Mainwindow::Mainwindow(QMainWindow *parent) : QMainWindow(parent) {
this->resize(1024,576);
//this->setWindowFlags(Qt::Popup);
QPalette palette;
palette.setColor(QPalette::Background, QColor(16,16,16));
this->setPalette(palette);
Sublist SecondList;
//! [Set ScrollAreas]
List = new QScrollArea(this);
List->setGeometry(0,60,200,456);
List->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
Sublist = new QScrollArea(this);
Sublist->setGeometry(200,60,824,456);
Sublist->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
//Sublist->setWidget(SecondList)
}
//! ---------------------------------------- MainList------------------------------------------------------
Sublist::Sublist(QWidget *parent){
resize(1200,1200);
title = new QLabel("Title",this);
title->setGeometry(1120,1120,40,90);
}
I have played around with your code a bit, noticed a few things:
In class Mainwindow you define your QScrollArea variables:
QScrollArea *List,*Sublist,*Overall,*Settings;
You define a variable named Sublist of type QScrollArea, but you also have a class of the same name:
class Sublist : public QWidget
Probably would be a good idea to change the variable names for your scroll areas:
QScrollArea *list, *subList, *overall, *settings;
Next, in the constructor for class Sublist you pass a pointer to the parent class but never assign it to your base class. You also have a QLabel widget that never is placed anywhere. What seems to be needed is a layout for your custom widget.
The Sublist class could be something like this:
//.h
class Sublist : public QWidget
{
Q_OBJECT
public:
Sublist(QWidget *parent = 0);
private:
QLabel *title;
QVBoxLayout *layout;
};
//.cpp
Sublist::Sublist(QWidget *parent) : QWidget(parent) {
resize(1200,1200);
title = new QLabel("Title");
title->setGeometry(1120,1120,40,90);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(title);
setLayout(layout);
}
The Mainwindow class something like this:
//.h
class Mainwindow : public QMainWindow
{
Q_OBJECT
public:
Mainwindow(QMainWindow *parent = 0);
private:
Sublist *secondList;
QScrollArea *list, *subList, *overall, *settings;
QLabel *label_title;
QPushButton *bn_exit,*bn_list,*bn_overall,*bn_settings;
};
//.cpp
Mainwindow::Mainwindow(QMainWindow *parent) : QMainWindow(parent)
{
this->resize(1024,576);
QPalette palette;
palette.setColor(QPalette::Background, QColor(16,16,16));
palette.setColor(QPalette::Foreground, QColor(255,255,255));//set text to white
this->setPalette(palette);
secondList = new Sublist(this);
//! [Set ScrollAreas]
list = new QScrollArea(this);
list->setGeometry(0,60,200,456);
list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
subList = new QScrollArea(this);
subList->setGeometry(200,60,824,456);
subList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
subList->setWidget(secondList);
}
Im still not 100% sure this is what you where trying to achieve with this code, but I hope that I have helped you to resolve some of the issues in your current implementation.