QMainWindow crashes when using QComboBox [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a problem with my application in Qt, I use a QMainWindow and try to set up 2 QComboBox like I did for other widgets but the application crashes at the setupUi :
Voilà ma classe MainWindow, elle fonctionnait parfaitement et s'affichait jusqu'à ce que j'ajoute les 2 Combobox.
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
MainWindow(Map *inMap, int dim1, int dim2);
~MainWindow();
public slots:
void boutonClicked();
private:
Ui::MainWindow *_ui;
QPushButton *_bouton;
Canvas *_canvas;
QComboBox *_boxDim1;
QComboBox *_boxDim2;
};
Une fois les ComboBox ajoutées, le programme crashe à l'exécution du constructeur :
MainWindow::MainWindow(Map *inMap, int dim1, int dim2)
{
_ui->setupUi(this);
_boxDim1 = new QComboBox();
_boxDim2 = new QComboBox();
_canvas = new Canvas(inMap, dim1, dim2);
_bouton = new QPushButton("Test !");
_bouton->setToolTip("Bouton a push");
_bouton->setCursor(Qt::PointingHandCursor);
connect(_bouton, SIGNAL(clicked()), this, SLOT(boutonClicked()));
QWidget *q = new QWidget();
setCentralWidget(q);
QGridLayout *mainLayout = new QGridLayout();
mainLayout->addWidget(_canvas, 1, 0, 1, 1);
mainLayout->addWidget(_bouton, 2, 0, 1, 1);
q->setLayout(mainLayout);
}
Après débuggage dans ddd, le point exact du segfault correspond à :
_ui->setupUi(this);
Et à l'intérieur de cette fonction :
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objetName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow) /// Segfault ici.
Je dois avouer que je ne saisis pas d'où vient le problème puisque l'ajout et la création du QPushButton et du Canvas ont quant à eux parfaitement fonctionné.

Your _ui variable is not initialized, that's why it crashes. You need something like: _ui = new Ui::MainWindow(); ... also, it's good habit to have MainWindow take a QObject parameter as the parent in the second constructor. Or just use the first one and add the extra parameters you need.

Related

Visual studio compiles but no .exe is created

I am trying to make a telemetry software for a college project. I am new to C++ as I am more used to Python. I followed a few tutorials and asked help from GPT3 to make it.
// Importation des librairies
#include "telemetry.h"
#include <QApplication>
#include <QMainWindow>
#include <QTabWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QStandardItemModel>
#include <QTableView>
// Structure pour stocker les données de télémétrie
struct TelemetryData {
double time;
double distance;
double speed;
double acceleration;
double acceleratorPressure;
double brakePressure;
double gpsPositionX;
double gpsPositionY;
};
//----------------------------------------------------------------------------- Main ------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// ---------- Création des différents affichages, boutons et onglets --------
QApplication app(argc, argv);
// Créer la fenêtre principale de l'application
QMainWindow window;
window.setWindowTitle("Télémétrie");
// Créer le layout principal de la fenêtre
QWidget* centralWidget = new QWidget(&window);
QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget);
window.setCentralWidget(centralWidget);
// Créer le widget QTabWidget et l'ajouter à l'interface utilisateur
QTabWidget* tabWidget = new QTabWidget(centralWidget);
mainLayout->addWidget(tabWidget);
// Créer le premier onglet affichant le graphique de pression d'accélérateur et de frein
QWidget* firstTab = new QWidget();
QVBoxLayout* firstTabLayout = new QVBoxLayout(firstTab);
// Créer le graphe de pression d'accélérateur et de frein
QCustomPlot* pressureGraph = new QCustomPlot(firstTab);
pressureGraph->addGraph();
pressureGraph->addGraph();
pressureGraph->graph(0)->setPen(QPen(Qt::green));
pressureGraph->graph(1)->setPen(QPen(Qt::red));
pressureGraph->xAxis->setLabel("Temps (ms)");
pressureGraph->yAxis->setLabel("Pression (bars)");
pressureGraph->yAxis->setRange(0, 1);
firstTabLayout->addWidget(pressureGraph);
// Créer les boutons de contrôle du graphe de pression d'accélérateur et de frein
QPushButton* pauseButton = new QPushButton("Mettre en pause", firstTab);
QPushButton* nextButton = new QPushButton("Milliseconde suivante", firstTab);
QPushButton* previousButton = new QPushButton("Milliseconde précédente", firstTab);
QPushButton* forwardButton = new QPushButton("Avancer x3", firstTab);
QPushButton* backwardButton = new QPushButton("Reculer x3", firstTab);
firstTabLayout->addWidget(pauseButton);
firstTabLayout->addWidget(nextButton);
firstTabLayout->addWidget(previousButton);
firstTabLayout->addWidget(forwardButton);
firstTabLayout->addWidget(backwardButton);
// Ajouter l'onglet au widget QTabWidget
tabWidget->addTab(firstTab, "Graphique de pression d'accélérateur et de frein");
// Créer le deuxième onglet affichant un tableau de données de télémétrie
QWidget* secondTab = new QWidget();
QVBoxLayout* secondTabLayout = new QVBoxLayout(secondTab);
// Créer le modèle de données et le tableau
QStandardItemModel* model = new QStandardItemModel(0, 9, secondTab);
model->setHeaderData(0, Qt::Horizontal, "Temps (ms)");
model->setHeaderData(1, Qt::Horizontal, "Distance (m)");
model->setHeaderData(2, Qt::Horizontal, "Vitesse (m/s)");
model->setHeaderData(3, Qt::Horizontal, "Accélération (m/s^2)");
model->setHeaderData(4, Qt::Horizontal, "Pression d'accélérateur (bars)");
model->setHeaderData(5, Qt::Horizontal, "Pression de frein (bars)");
model->setHeaderData(6, Qt::Horizontal, "Position GPS X (m)");
model->setHeaderData(7, Qt::Horizontal, "Position GPS Y (m)");
//Créer l'onglet secondaire
QTableView* tableView = new QTableView(secondTab);
tableView->setModel(model);
secondTabLayout->addWidget(tableView);
// Ajouter l'onglet au widget QTabWidget
tabWidget->addTab(secondTab, "Données de télémétrie");
// Créer le bouton permettant de changer d'onglet
QPushButton* switchTabButton = new QPushButton("Changer d'onglet", centralWidget);
mainLayout->addWidget(switchTabButton);
// Connecter le signal clicked() du bouton à un slot qui changera l'onglet sélectionné dans le widget QTabWidget
QObject::connect(switchTabButton, &QPushButton::clicked, [&tabWidget]() {
int currentIndex = tabWidget->currentIndex();
int newIndex = (currentIndex + 1) % tabWidget->count();
tabWidget->setCurrentIndex(newIndex);
});
// --------------------- Ouverture du Fichier -------------------
// Ouvrir le fichier de données de télémétrie en lecture
QFile file("telemetry.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
// Afficher une erreur si le fichier ne peut pas être ouvert
QMessageBox::critical(nullptr, "Erreur", "Impossible d'ouvrir le fichier de données de télémétrie");
return -1;
}
// Collecter les données de télémétrie depuis le fichier
QTextStream in(&file);
QVector<TelemetryData> data;
while (!in.atEnd()) {
QString line = in.readLine();
QStringList fields = line.split("\t");
if (fields.size() != 8) {
// Afficher une erreur si le nombre de champs est incorrect
QMessageBox::critical(nullptr, "Erreur", "Format de données de télémétrie incorrect");
return -1;
}
TelemetryData datum;
datum.time = fields[0].toDouble();
datum.distance = fields[1].toDouble();
datum.speed = fields[2].toDouble();
datum.acceleration = fields[3].toDouble();
datum.acceleratorPressure = fields[4].toDouble();
datum.brakePressure = fields[5].toDouble();
datum.gpsPositionX = fields[6].toDouble();
datum.gpsPositionY = fields[7].toDouble();
data.append(datum);
}
file.close();
// -------------- Affinage des affichages --------------
// Créer un objet gnuplot pour dessiner la gauge de vitesse
Gnuplot gp;
gp << "set terminal qt size 350,200 font ',14'\n";
gp << "set style data line\n";
gp << "set xrange [-1:1]\n";
gp << "set yrange [-1:1]\n";
gp << "set border 0\n";
gp << "set tics out\n";
gp << "set nokey\n";
gp << "unset colorbox\n";
gp << "set object 1 circle at 0,0 size 1.1 fc rgb 'white'\n";
gp << "set object 2 circle at 0,0 size 1 fc rgb 'black'\n";
gp << "set object 3 circle at 0,0 size 0.9 fc rgb 'red'\n";
gp << "set object 4 circle at 0,0 size 0.1 fc rgb 'black'\n";
gp << "set object 5 circle at 0,0 size 0.07 fc rgb 'white'\n";
// Créer une image du circuit vu d'en haut
QImage circuitImage("circuit.png");
QLabel* circuitLabel = new QLabel(centralWidget);
circuitLabel->setPixmap(QPixmap::fromImage(circuitImage));
circuitLabel->setScaledContents(true);
circuitLabel->setFixedSize(500, 500);
mainLayout->addWidget(circuitLabel);
// Dessiner un cercle rouge à la position de la voiture sur l'image du circuit
QGraphicsScene* circuitScene = new QGraphicsScene(circuitLabel);
QGraphicsEllipseItem* car = new QGraphicsEllipseItem(0, 0, 10, 10);
car->setBrush(QBrush(Qt::red));
circuitScene->addItem(car);
QGraphicsView* circuitView = new QGraphicsView(circuitScene, circuitLabel);
circuitView->setRenderHint(QPainter::Antialiasing);
circuitView->setRenderHint(QPainter::SmoothPixmapTransform);
circuitView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
circuitView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
circuitView->setFixedSize(500, 500);
// Créer une jauge de vitesse
QLabel* speedGauge = new QLabel(centralWidget);
speedGauge->setFixedSize(350, 200);
speedGauge->setPixmap(QPixmap::fromImage(gp.plot(QString(""), "", "", "", false).scaled(350, 200)));
mainLayout->addWidget(speedGauge);
// Afficher la fenêtre principale
mainWindow.show();
// ---------------- Fonction Temps réel ---------------
// Initialiser l'index de la donnée de télémétrie actuellement affichée
int dataIndex = 0;
// Initialiser un booléen indiquant si la lecture en temps réel est en pause
bool paused = false;
// Boucle principale de mise à jour de l'affichage en temps réel
while (true) {
// Mettre à jour le graphique de pression d'accélérateur et de frein
pressureGraph->graph(0)->addData(data[dataIndex].time, data[dataIndex].acceleratorPressure);
pressureGraph->graph(1)->addData(data[dataIndex].time, data[dataIndex].brakePressure);
pressureGraph->xAxis->setRange(data[dataIndex].time, 8, Qt::AlignRight);
pressureGraph->replot();
// Mettre à jour la jauge de vitesse
double speedRatio = data[dataIndex].speed / 140.0; // 140 km/h est la vitesse maximale
gp << "set object 4 circle at " << QString::number(speedRatio * std::sin(M_PI / 4)).toStdString()
<< "," << QString::number(-speedRatio * std::cos(M_PI / 4)).toStdString()
<< " size 0.1 fc rgb 'black'\n";
speedGauge->setPixmap(QPixmap::fromImage(gp.plot(QString(""), "", "", "", false).scaled(350, 200)));
// Mettre à jour la position de la voiture sur l'image du circuit
car->setPos(250 + data[dataIndex].gpsPositionX * 3, 250 - data[dataIndex].gpsPositionY * 3); // 250, 250 est le centre de l'image
// Mettre à jour l'affichage du tableau de données de télémétrie
for (int i = 0; i < model->rowCount(); ++i) {
model->setData(model->index(i, 0), data[i].time);
model->setData(model->index(i, 1), data[i].distance);
model->setData(model->index(i, 2), data[i].speed);
model->setData(model->index(i, 3), data[i].acceleration);
model->setData(model->index(i, 4), data[i].acceleratorPressure);
model->setData(model->index(i, 5), data[i].brakePressure);
model->setData(model->index(i, 6), data[i].gpsPositionX);
model->setData(model->index(i, 7), data[i].gpsPositionY);
}
tableView->scrollTo(model->index(dataIndex, 0));
// Attendre 1 milliseconde avant de mettre à jour à nouveau l'affichage
QThread::msleep(1);
// Si la lecture en temps réel n'est pas en pause, passer à la donnée de télémétrie suivante
if (!paused) {
++dataIndex;
}
if (dataIndex >= data.size()) {
dataIndex = 0;
}
}
There is no error and when I build the solution, it works fine, saying the operation was succesful, however when I try to debug it, no .exe is found.
Here is what I get when I build the solution :
Build started...
1>------ Build started: Project: Telemetrie_PITA, Configuration: Debug x64 ------
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
I checked the project files and it is true, there is no .exe in sight.
To verify whether the error would come from my project or my installation, I ran a simple HelloWorld project which worked perfectly fine.
Menu -> Build -> Build Solution perform.
.exe file is default located in C:\Users\DESKTOP NAME\source\repos\PROJECT NANE\PROJECT NAME\bin\Debug path.
.exe can also be forcibly deleted Anti-Virus Program.

Attempting to add QLayout "" to convertidorNumericoDialogo "" which already has a layout [duplicate]

This question already has answers here:
QWidget::setLayout: Attempting to set QLayout "" on Widget "", which already has a layout
(2 answers)
Closed 1 year ago.
what's up friends, I got the issue of the title, programm working with 3 QLineEdit where 1st it's to introduce a decimal number, 2nd a hex, and the 3rd a binary.
I got signals that works while I introduce a decimal number then it puts the hex value in the 2nd QLineEdit(it's converted by signal) , and to the same way for the binary value.
until here, before was working(but not now), after I put a code to introduce a binary or hex, then it becomes to decimal , and the other val...
I need your help, maybe I'm not seeing something .... it's literally the first time I used QGidLayout, etc etc.
my code is next:
code of convertidorNumerico.cpp
#include "convertidornumerico.h"
convertidorNumerico::convertidorNumerico(QObject *parent) : QObject(parent)
{
}
void convertidorNumerico::setDec(const QString &cadena)
{
bool ok;
int num = cadena.toInt(&ok);
if ( ok )
{
emit hexChanged(QString::number(num, 16));
emit binChanged(QString::number(num, 2));
}
else
{
emit hexChanged("");
emit binChanged("");
}
}
void convertidorNumerico::setHex(const QString &cadena)
{
bool ok;
int num = cadena.toInt(&ok, 16);
if ( ok )
{
emit decChanged(QString::number(num));
emit binChanged(QString::number(num, 2));
}
else
{
emit decChanged("");
emit binChanged("");
}
}
void convertidorNumerico::setBin(const QString &cadena)
{
bool ok;
int num = cadena.toInt(&ok);
if ( ok )
{
emit decChanged(QString::number(num));
emit hexChanged(QString::number(num, 16));
}
else
{
emit decChanged("");
emit hexChanged("");
}
}
code of convertidorNumerico.h
#ifndef CONVERTIDORNUMERICO_H
#define CONVERTIDORNUMERICO_H
#include <QObject>
class convertidorNumerico : public QObject
{
Q_OBJECT
public:
explicit convertidorNumerico( QObject *parent = nullptr );
signals:
void decChanged(const QString &);
void hexChanged(const QString &);
void binChanged(const QString &);
public slots:
void setDec(const QString &);
void setHex(const QString &);
void setBin(const QString &);
};
#endif // CONVERTIDORNUMERICO_H
code of convertidorNumericoDialogo.cpp
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QIntValidator>
#include <QRegularExpression>
#include <QRegularExpressionValidator>
#include "convertidornumericodialogo.h"
#include "convertidornumerico.h"
/*convertidorNumericoDialogo::convertidorNumericoDialogo(QObject *parent) : QObject(parent)
{
}*/
convertidorNumericoDialogo::convertidorNumericoDialogo()
{
QVBoxLayout *mainLayout = new QVBoxLayout ( this );
QGridLayout *editLayout = new QGridLayout ( this );
QHBoxLayout *btnLayout = new QHBoxLayout ( this );
QLabel *decLabel = new QLabel("decimal");
QLabel *hexLabel = new QLabel("Hexadecimal");
QLabel *binLabel = new QLabel("Binario");
decEdit = new QLineEdit;
hexEdit = new QLineEdit;
binEdit = new QLineEdit;
editLayout->addWidget(decLabel, 0, 0);
editLayout->addWidget( decEdit, 0, 1 );
editLayout->addWidget( hexLabel, 1, 0 );
editLayout->addWidget( hexEdit, 1, 1 );
editLayout->addWidget(binLabel, 2, 0);
editLayout->addWidget(binEdit, 2, 1);
QPushButton *btnSalir = new QPushButton("SALIR");
btnLayout->addStretch();
btnLayout->addWidget(btnSalir);
mainLayout->addLayout(editLayout);
mainLayout->addStretch();
mainLayout->addLayout(btnLayout);
btnSalir->setDefault(true);
connect(btnSalir, SIGNAL(released()), this, SLOT(accept()));
// VALORES DE UN BYTE : 0 - 255
QIntValidator *decVal = new QIntValidator(0, 255, decEdit);
decEdit->setValidator(decVal);
// EXP REG PARA VALIDAR HEXADECIMALES DE HASTA 2 DIGITOS....
QRegularExpressionValidator *hexVal = new QRegularExpressionValidator(
QRegularExpression("^[0-9A-Fa-f]{1,2}"), hexEdit);
hexEdit->setValidator(hexVal);
// EXP REG PARA VALIDAR BINARIOS DE HASTA 8 BYTES....
QRegularExpressionValidator *binVal = new QRegularExpressionValidator(
QRegularExpression("[0-1]{1,8}"), binEdit);
binEdit->setValidator(binVal);
convertidorNumerico *convertidor = new convertidorNumerico;
connect(decEdit, SIGNAL(textChanged(QString)), convertidor, SLOT(setDec(QString)));
connect(convertidor, SIGNAL(hexChanged(QString)), hexEdit, SLOT(setText(QString)));
connect(convertidor, SIGNAL(binChanged(QString)), binEdit, SLOT(setText(QString)));
// tarea: => CONECTAR las señales de hexa y binario, para que ingresando esos datos, se devuelva la info en la app.
connect(hexEdit, SIGNAL(textChanged(QString)), convertidor, SLOT(setHex(QString)));
connect(binEdit, SIGNAL(textChanged(QString)), convertidor, SLOT(setBin(QString)));
connect(convertidor, SIGNAL(decChanged(QString)), decEdit, SLOT(setText(QString)));
}
code of convertidorNumericoDialogo.h
#ifndef CONVERTIDORNUMERICODIALOGO_H
#define CONVERTIDORNUMERICODIALOGO_H
#include <QDialog>
class QLineEdit;
class convertidorNumericoDialogo : public QDialog
{
Q_OBJECT
public:
//explicit convertidorNumericoDialogo(QObject *parent = nullptr);
explicit convertidorNumericoDialogo();
private:
QLineEdit *decEdit;
QLineEdit *hexEdit;
QLineEdit *binEdit;
};
#endif // CONVERTIDORNUMERICODIALOGO_H
any solution? I did everything and I didn't make it working...
You are setting multiple layouts, change this:
QVBoxLayout *mainLayout = new QVBoxLayout ( this );
QGridLayout *editLayout = new QGridLayout ( this );
QHBoxLayout *btnLayout = new QHBoxLayout ( this );
to
QVBoxLayout *mainLayout = new QVBoxLayout ( this );
QGridLayout *editLayout = new QGridLayout;
QHBoxLayout *btnLayout = new QHBoxLayout;
See https://doc.qt.io/qt-5/qlayout.html#QLayout

QStackedWidget how to use it exactly?

I tried to use QStackedWidget before, but I didn't understand exactly how to. The code below makes me understand how to change the current window from the main window to another window, already called in the mainwindow, and this is working good. I changed the current index to all the other windows, and every time the window is not the same, which is good.
My question is:
From another window how can I switch to another window (different than the current)? Do I Have to define this QStackedWidget in all the other windows, so that I can use it the same way as I am using it here?
I would love that after clicking on a button on a window(the other windows) the window switch to another one, How can I do it?
For example, in this code I have the FenetrePrincipale that allow me to change the windows using the setCurrentIndex , setting the setCurrentIndex to 3 for example make the first window that appear is MAFENETRE3.
I would like that from for example, from MAFENTRE3 use a button that allow me to switch to another window .
( actually after having problems with QStackedWidget I just implement my code normally and instead of switching to another window, I just open window on the bottom of the window calling which is not looking good!
PS HERE THE CODE OF TEST :
fenetrprincipale.h
#ifndef FENETRE_PRINCIPALE
#define FENETRE_PRINCIPALE
#include <QApplication>
#include <QtWidgets>
#include "MaFenetre.h"
#include "MaFenetre2.h"
#include "MaFenetre3.h"
#include "MaFenetre4.h"
class FenetrePrincipale : public QMainWindow
{
Q_OBJECT
public:
FenetrePrincipale();
~FenetrePrincipale();
public slots:
void slotDisplayFen(int fenIndex);
private:
QStackedWidget *stack;
MaFenetre *fen1;
MaFenetre2 *fen2;
MaFenetre3 *fen3;
MaFenetre4 *fen4;
};
#endif
fenetreprincipale.cpp
#include "FenetrePrincipale.h"
FenetrePrincipale::FenetrePrincipale() : QMainWindow()
{
stack = new QStackedWidget(this);
fen1 = new MaFenetre();
fen2 = new MaFenetre2 ();
fen3 = new MaFenetre3();
fen4 = new MaFenetre4();
stack->addWidget(fen1);
stack->addWidget(fen2);
stack->addWidget(fen3);
stack->addWidget(fen4);
this->setCentralWidget(stack);
stack->setCurrentIndex(0); // on affiche la première fenêtre à l'ouverture du programme
setWindowTitle("Test STACKEDLAYOUT");
resize(500,600);
connect(fen1, SIGNAL(askDisplayFen(int)), this, SLOT(slotDisplayFen(int)));
connect(fen2, SIGNAL(askDisplayFen(int)), this, SLOT(slotDisplayFen(int)));
connect(fen3, SIGNAL(askDisplayFen(int)), this, SLOT(slotDisplayFen(int)));
connect(fen4, SIGNAL(askDisplayFen(int)), this, SLOT(slotDisplayFen(int)));
}
FenetrePrincipale::~FenetrePrincipale()
{
}
void FenetrePrincipale::slotDisplayFen(int fenIndex)
{
if ((fenIndex < 0) || (fenIndex > 3)) {return;}
stack->setCurrentIndex(fenIndex);
}
Here is the code of Mafenetre
MaFenetre.h
#ifndef DEF_MAFENETRE
#define DEF_MAFENETRE
#include <QtWidgets>
class MaFenetre : public QWidget // On hérite de QWidget (IMPORTANT)
{
public:
MaFenetre();
private:
QPushButton *m_bouton;
};
#endif
MaFenetre.cpp
#include "MaFenetre.h"
MaFenetre::MaFenetre() : QWidget()
{
setFixedSize(300, 150);
m_bouton = new QPushButton("Quitter", this);
m_bouton->setFont(QFont("Comic Sans MS", 14));
m_bouton->move(110, 50);
// Connexion du clic du bouton à la fermeture de l'application
QObject::connect(m_bouton, SIGNAL(clicked()), qApp, SLOT(quit()));
}
I have shared with a below sample code i hope it would be help for you.
#include "test1.h"
#include "ui_test1.h"
#include<QDebug>
test1::test1(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::test1)
{
ui->setupUi(this);
stack = new QStackedWidget(this);
tes = new test2();
stack->addWidget(ui->pushButton);
stack->addWidget(tes);
this->setCentralWidget(stack);
stack->setCurrentIndex(0);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(slotDisplayFen()));
}
test1::~test1()
{
delete ui;
}
void test1::slotDisplayFen()
{
qDebug()<<"test";
stack->setCurrentIndex(1);
}
The answer is just to define a custom signal on the desired window to switch , and that signal will be sent to the main window so it will display the right switch for you

Qt qwidget appearing and disappearing instantly

I was writing a chat program with Qt 5.9. I finished the client-side program and started improving it. The first thing I did was making a new Qwidget (a secondary window) that would appear when pressing the connect button on my main window. Everything went fine, but when I tested and pressed the connect button on my main window, my secondary window appeared and disappeared instantly. How can I make my secondary window stay (not disappear) for the time the user presses the button (which is on the secondary window)? Here is the code of both my windows : main window.h (fenClient.h):
#ifndef FENCLIENT_H
#define FENCLIENT_H
#include <QtWidgets>
#include <QtNetwork>
#include <ui_fenclient.h>
#include <fenconnexion.h>
class FenClient : public QWidget, private Ui::FenClient
{
Q_OBJECT
public:
FenClient();
~FenClient();
private slots:
void on_boutonConnexion_clicked();
void on_boutonEnvoyer_clicked();
void on_message_returnPressed();
void donneesRecues();
void connecte();
void deconnecte();
void erreurSocket(QAbstractSocket::SocketError erreur);
private:
QTcpSocket *socket;
quint16 tailleMessage;
};
#endif // FENCLIENT_H
#include <fenclient.h>
main window.cpp (fenClient.cpp) This is where the secondary window is created.
FenClient::FenClient()
{
setupUi(this);
socket = new QTcpSocket;
connect(socket,SIGNAL(readyRead()),this,SLOT(donneesRecues()));
connect(socket,SIGNAL(connected()),this,SLOT(connecte()));
connect(socket,SIGNAL(disconnected()),this,SLOT(deconnecte()));
connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(erreurSocket(QAbstractSocket::SocketError)));
tailleMessage = 0;
}
void FenClient::on_boutonConnexion_clicked()
{
listeMessages->append(tr("<em>Tentative de connexion en cours...</em>"));
boutonConnexion->setEnabled(false);
fenConnexion *fenetreCo = new fenConnexion; //this is where my secondary window is created
fenetreCo->show();
fenetreCo->activateWindow();
fenetreCo->setParent(this);
fenetreCo->echangerPseudo(pseudo->text());
socket->abort();
socket->connectToHost(serveurIP->text(),serveurPort->value());
}
void FenClient::on_boutonEnvoyer_clicked()
{
if (message->text().isEmpty())
{
QMessageBox::information(this,"Veuillez écrire quelque chose","Pour éviter le spam, j'ai decidé d'empecher l'envoi de message vide. Veuillez écrire quelque chose...");
}
else if(pseudo->text() == "")
{
QMessageBox::information(this,"Veuillez spécifier votre nom","Pour éviter l'anonimité, j'ai décidé d'obligé l'usage d'un pseudo.");
}
else
{
QByteArray paquet;
QDataStream out(&paquet, QIODevice::WriteOnly);
QString messageAEnvoyer = tr("<strong>") + pseudo->text() + tr("</strong> : ") + message->text();
out<<(quint16) 0;
out<< messageAEnvoyer ;
out.device()->seek(0);
out << (quint16) (paquet.size() - sizeof(quint16));
socket->write(paquet);
message->clear();
message->setFocus();
}
}
void FenClient::on_message_returnPressed()
{
on_boutonEnvoyer_clicked();
}
void FenClient::donneesRecues()
{
QDataStream in(socket);
if (tailleMessage==0)
{
if(socket->bytesAvailable() < (int)sizeof(quint16))
{return;}
in >> tailleMessage;
}
if (socket->bytesAvailable() < tailleMessage)
{return;}
QString messageRecu;
in >> messageRecu;
listeMessages->append(messageRecu);
tailleMessage = 0;
}
void FenClient::connecte()
{
listeMessages->append(tr("<em>Connexion réussie</em>"));
boutonConnexion->setEnabled(true);
message->setEnabled(true);
}
void FenClient::deconnecte()
{
listeMessages->append(tr("<em>Déconnecté!</em>"));
message->setEnabled(false);
}
void FenClient::erreurSocket(QAbstractSocket::SocketError erreur)
{
switch(erreur)
{
case QAbstractSocket::HostNotFoundError:
listeMessages->append(tr("<em>ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port.</em>"));
break;
case QAbstractSocket::ConnectionRefusedError:
listeMessages->append(tr("<em>ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port.</em>"));
break;
case QAbstractSocket::RemoteHostClosedError:
listeMessages->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>"));
break;
default:
listeMessages->append(tr("<em>ERREUR : ") + socket->errorString() + tr("</em>"));
}
boutonConnexion->setEnabled(true);
}
FenClient::~FenClient()
{}
secondary window.h (fenconnexion.h)
#ifndef FENCONNEXION_H
#define FENCONNEXION_H
#include <ui_fenconnexion.h>
#include <QtWidgets>
class fenConnexion : public QWidget, private Ui::Form
{
Q_OBJECT
public:
fenConnexion();
QString pseudoUtilisateur;
void echangerPseudo(QString pseudoAEchanger);
private slots :
void checkPseudo();
private:
QString pseudo;
};
#endif // FENCONNEXION_H
secondary window.cpp (fenconnexion.cpp)
#include <fenconnexion.h>
fenConnexion::fenConnexion()
{ setupUi(this);
connect(boutonInserer,SIGNAL(clicked(bool)),this,SLOT(checkPseudo()));
}
void fenConnexion::checkPseudo()
{
pseudo=pseudoInsere->text();
if (pseudo.isEmpty())
{
QMessageBox::information(this,"Probleme","Veuillez entre un pseudo conetenant au moins un caractere.");
}
else
{
pseudoUtilisateur=pseudo;
pseudoInsere->clear();
pseudo.clear();
this->close();
}
}
void fenConnexion::echangerPseudo(QString pseudoAEchanger)
{
pseudoAEchanger.clear();
pseudoAEchanger = pseudoUtilisateur;
}
I feel like I've made a very simple error, but as I haven't used Qt in over 6 months, I don't seem to find it.
You need to make sure you've set up the window properly before trying to show it.
fenConnexion *fenetreCo = new fenConnexion;
fenetreCo->show();
fenetreCo->activateWindow();
fenetreCo->setParent(this);
Set the parent of the window before invoking show on it. That makes the window this' child, which means that it's this' responsibility to manage its life-cycle.

How to know if a horizontal scrollerbar is shown in a QPlainTextEdit inherited class?

How can i know that whether the scrollbar is displayed in a QPlainTextEdit ?
I tried QScrollBar::isHidden() , but always return true.
Appreciate any of your help !
You should try using the isVisible() method on your edit's verticalScrollBar().
This works as expected here:
#include <QtGui>
class Win: public QWidget
{
Q_OBJECT
public:
Win(QWidget *parent=0): QWidget(parent)
{
edit = new QPlainTextEdit;
QPushButton *b1 = new QPushButton("click");
QVBoxLayout *vl = new QVBoxLayout;
vl->addWidget(edit);
vl->addWidget(b1);
setLayout(vl);
connect(b1, SIGNAL(clicked()), this, SLOT(clicked()));
}
public slots:
void clicked()
{
qDebug() << edit->verticalScrollBar()->isVisible();
}
private:
QPlainTextEdit *edit;
};