I have a vector of labels, declared in the MainWindow class:
QVector<QPointer<QLabel>> labels;
And a function:
void MainWindow::testFunc()
{
for(int i = 0; i < 5; ++i) {
labels.push_back(QPointer<QLabel>(new QLabel(this)));
labels.back()->setGeometry(QRect(50 * i, 0, 50, 50));
labels.back()->setText("test");
}
}
I call this function in the class constuctor and everything is fine:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
testFunc();
}
Then I added a button and a connecting:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::testFunc);
}
And after clicking the labels aren't shown. I checked via debugger and in the both ways the labels are created and constructors for them are executed. Also I tried simple pointers, QTimer::singleShot() and QPointer<QLabel> without QVector - the result is the same.
Why the second way does't work? Why I can add a QLabel only in the constuctor?
QMainWindow alwayd should have a centralWidget that contains other chilrens. when using forms, centralWidget is automaticly created. you may manage labels in a horizontal layout and then add them to the centralWidget:
QPointer<QHBoxLayout> hBoxLayout (new QHBoxLayout);
for(int i = 0; i < 5; ++i) {
labels.push_back(QPointer<QLabel>(new QLabel));
labels.back()->setGeometry(QRect(50 * i, 0, 50, 50));
labels.back()->setText("test");
hBoxLayout->addWidget(labels.back().data());
}
ui->centralwidget->setLayout(hBoxLayout);
Related
Hey I want to create a 8x8 field of pushButtons. When using this Code
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVector>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
QGridLayout* layout = new QGridLayout();
ui->centralwidget->setLayout(layout);
QVector<QVector<QPushButton*>> buttons2DVector(8);
for (int i=0;i<8;i++){
buttons2DVector[i].resize(8);
for(int j=0;j<8;j++){
QPushButton *b = new QPushButton("button");
layout->addWidget(b,i,j);
buttons2DVector[i][j] = b;
}
}
the error is:
unknown type Name "QGridLayout"
unknown type Name "ui"
the Code was given to me but I dont know how to use it properly. As you can probably see I am a beginner in QT and C++ but it would be nice if someone could help me.
Assuming you added the following to your MainWindow class declaration:
QVector<QVector<QPushButton*>> buttons2DVector(8);
void createGrid();
You could create the grid programmatically as follows:
#include "mainwindow.h"
#include <QVector>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
createGrid();
}
void MainWindow::createGrid() {
QFrame *frame = new QFrame(this);
QGridLayout *layout = new QGridLayout(frame);
for (int i=0;i<8;i++){
buttons2DVector[i].resize(8);
for(int j=0;j<8;j++){
QPushButton *b = new QPushButton("button", layout);
layout->addWidget(b,i,j);
buttons2DVector[i][j] = b;
}
}
setCentralWidget(frame);
}
I want to pass three strings (cellTitle,cellPoem,cellGroup) from mainwindows to another dialog. I know when i initiate the second form the values become zeros. I read somewhere it's possible with slots but i don't know how.
mainwindows.h
public:
QString cellTitle,cellPoem,cellGroup;
mainwindows.cpp
void MainWindow::on_tableView_pressed(const QModelIndex &index)
{
cellText = ui->tableView->model()->data(index).toString();
QSqlQuery * qry2 = new QSqlQuery(mydb);
qry2->prepare("select * from Poems where Title='"+cellText+"'");
qry2->exec();
while(qry2->next()){
cellTitle = qry2->value(1).toString();
cellPoem = qry2->value(2).toString();
cellGroup = qry2->value(3).toString();
ui->textEdit->setText(qry2->value(2).toString());
}
}
void MainWindow::on_btnUpdate_clicked()
{
frmUpdate frmupdate;
frmupdate.setModal(true);
frmupdate.exec();
}
frmupdate.cpp
#include "frmupdate.h"
#include "ui_frmupdate.h"
#include <mainwindow.h>
frmUpdate::frmUpdate(QWidget *parent) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
MainWindow mainwindow;
ui->lineEdit->setText(mainwindow.cellTitle);
ui->lineEdit_2->setText(mainwindow.cellGroup);
ui->textEdit->setText(mainwindow.cellPoem);
}
frmUpdate::~frmUpdate()
{
delete ui;
}
void frmUpdate::on_btnUpdate_clicked()
{
}
void frmUpdate::on_pushButton_2_clicked()
{
this->close();
}
frmUpdate::frmUpdate(QWidget *parent) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
MainWindow mainwindow;
You here have created a new, temporary MainWindow instance only with default constructor being called. Of course, this new instance is then created with empty default texts:
ui->lineEdit->setText(mainwindow.cellTitle);
ui->lineEdit_2->setText(mainwindow.cellGroup);
ui->textEdit->setText(mainwindow.cellPoem);
}
Easiest now would be passing the original main window as parameter:
frmUpdate::frmUpdate(QWidget* parent, MainWindow* mainWindow) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
ui->lineEdit->setText(mainwindow->cellTitle);
ui->lineEdit_2->setText(mainwindow->cellGroup);
ui->textEdit->setText(mainwindow->cellPoem);
}
If the parent is the main window, you can simply cast:
frmUpdate::frmUpdate(QWidget* parent) :
QDialog(parent),
ui(new Ui::frmUpdate)
{
ui->setupUi(this);
MainWindow* mainWindow = qobject_cast<MainWindow*>(parent);
if(mainWindow)
{
ui->lineEdit->setText(mainwindow->cellTitle);
ui->lineEdit_2->setText(mainwindow->cellGroup);
ui->textEdit->setText(mainwindow->cellPoem);
}
else
{
// appropriate error handling
}
}
You might search the main window from parent as well:
for(;;)
{
MainWindow* mainWindow = qobject_cast<MainWindow*>(parent);
if(mainWindow)
{
ui->lineEdit->setText(mainwindow->cellTitle);
ui->lineEdit_2->setText(mainwindow->cellGroup);
ui->textEdit->setText(mainwindow->cellPoem);
break;
}
parent = parent->parent();
if(!parent)
{
// appropriate error handling
break;
}
}
All above assuming that MainWindow inherits from QObject...
I have done some coding for L00 (name of my first QLineEdit).
I want to do the same for other 99 widgets (up to L99). I don't wanna copy paste it 100 hundred times.
void MainWindow::on_L00_returnPressed(){
QString c = ui->L00->text();
char d = QString(c).at(0).toLatin1();
if(d>=65&&d<=90||d>=97&&d<=122)
{
square[0]=d;
ui->MessageBox->setText("Alphabet succesfully entered");
ui->L00->setReadOnly(true);
ui->L00->setStyleSheet("QLineEdit { background: rgb(0, 255, 255);}");
}
else
{
ui->MessageBox->setText("Enter Alphabets Only");
ui->L00->setText("");
}
}
If you add all these widget through Qt Designer the objects will have the same name of the variable, so we can get them through findChild, then apply connect the signal ReturnPressed to a lambda function and not having to create a slot for each QLineEdit.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
int n = 100;
for(int i=0; i<n; i++){
QString name = QString("L%1").arg(i, 2, 10, QChar('0'));
QLineEdit* w = findChild<QLineEdit *>(name);
connect(w, &QLineEdit::returnPressed, [=](){
QString c = w->text();
char d = QString(c).at(0).toLatin1();
if((d>=65&& d<=90)||(d>=97&&d<=122))
{
square[i]=d;
ui->MessageBox->setText("Alphabet succesfully entered");
w->setReadOnly(true);
w->setStyleSheet("QLineEdit { background: rgb(0, 255, 255);}");
}
else
{
ui->MessageBox->setText("Enter Alphabets Only");
w->clear();
}
});
}
}
Note: I have considered that square[i] corresponds to the QLineEdit L-i.
Another solution is to connect all to the same slot and obtain the object through the function sender().
*.h
private slots:
void onReturnPressed();
*.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
for(QLineEdit* w: findChildren<QLineEdit *>()){
connect(w, &QLineEdit::returnPressed, this, &MainWindow::onReturnPressed);
}
}
void MainWindow::onReturnPressed()
{
QLineEdit* w =qobject_cast<QLineEdit *>(sender());
int i = w->objectName().remove(0, 1).toInt();
QString c = w->text();
char d = QString(c).at(0).toLatin1();
if((d>=65&& d<=90)||(d>=97&&d<=122))
{
square[i]=d;
ui->MessageBox->setText("Alphabet succesfully entered");
w->setReadOnly(true);
w->setStyleSheet("QLineEdit { background: rgb(0, 255, 255);}");
}
else
{
ui->MessageBox->setText("Enter Alphabets Only");
w->clear();
}
}
For old version:
*.h
private slots:
void onReturnPressed();
.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
int n = 100;
for(int i=0; i<n; i++){
QString name = QString("L%1").arg(i, 2, 10, QChar('0'));
QLineEdit* w = findChild<QLineEdit *>(name);
if(w)
connect(w, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
}
}
void MainWindow::onReturnPressed()
{
QLineEdit* w =qobject_cast<QLineEdit *>(sender());
int i = w->objectName().remove(0, 1).toInt();
QString c = w->text();
char d = QString(c).at(0).toLatin1();
if((d>=65&& d<=90)||(d>=97&&d<=122))
{
square[i]=d;
ui->MessageBox->setText("Alphabet succesfully entered");
w->setReadOnly(true);
w->setStyleSheet("QLineEdit { background: rgb(0, 255, 255);}");
}
else
{
ui->MessageBox->setText("Enter Alphabets Only");
w->clear();
}
}
You can use the QObject::findChildren to do so. It must be called from the parent widget (your MainWindow). You can from it connect the QLineEdit individually, or change all values at once.
Example:
for (auto lineEdit : this->findChildren<QLineEdit*>()) {
// connect lineEdit or change values
}
Problem starts with:
I have done some coding for L00 (name of my first QLineEdit) … 99 widgets (up to L99).
This means that you designed your application incorrectly.
I'm almost sure that you should use QTableView or QTableWidget with QAbstractTableModel or QStandartItemModel.
Also setStyleSheet should be applied on QApplication or at least on top level widget. This is how stylesheet is supposed to be used.
I have a QStackedWidget with a custom widget in it.
//mainwindow.h
private:
CentralWidget m_centralWidget;
//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->stackedWidget->addWidget(&m_centralWidget);
}
Now i want to create a QSplitter, fill the Splitter with content and add this Splitter to the StackedWidget.
CentralWidget::CentralWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::CentralWidget)
{
ui->setupUi(this);
connect(ui->pbAddSplit, SIGNAL(pressed()), this, SLOT(addSplit()));
}
void CentralWidget::addSplit()
{
QWidget* parent = parentWidget();
QStackedWidget* stackedWidget = qobject_cast<QStackedWidget*>(parent);
if(!stackedWidget) {
return;
}
QSplitter* splitter = new QSplitter(Qt::Vertical);
splitter->addWidget(new QLabel("Banana"));
splitter->addWidget(this);
int nIndex = stackedWidget->addWidget(splitter);
stackedWidget->setCurrentIndex(nIndex);
}
The result should be a QLabel("Banana") as one Widget of the splitter and the CentralWidget as the other splitter-widget.
But i just get the QLabel("Banana") - SplitterHandle and the CentralWidget got lost somehow...
splitter->addWidget(this) is obviously wrong...
Replacing it with splitter->addWidget(new QLabel("Cherry")) will result in a correct SplitterWidget...
The problem seems to be the parenting, but i cant figure it out.
Any suggestions would be most welcome!
If I create my QDialog and show it modal with exec() everything works fine, but I need this no modal!
With show() the Dialog is empty!
ProgramLoading *programLoading = new ProgramLoading();
programLoading->show();
// some code
programLoading->done(0);
Constructor
ProgramLoading::ProgramLoading(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
setWindowFlags( Qt::CustomizeWindowHint ); // remove window border
}
Don't think something with Dialog code is wrong because it works with exec()!
Any hints? Thank you!
PS: I'm using QT plugin for VisualStudio 2008
mw (Default with Window Decoration):
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
sd = new SplashDialog();
sd->show();
QTimer::singleShot(10000,this,SLOT(closeSplashDialog()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::closeSplashDialog()
{
sd->close();
delete sd;
}
splash (UI having Label and Button):
SplashDialog::SplashDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SplashDialog)
{
ui->setupUi(this);
setWindowFlags( Qt::CustomizeWindowHint );
}
SplashDialog::~SplashDialog()
{
delete ui;
}
Splash Dialog opens and is being closed 10 seconds later as intended