PDA

View Full Version : [C++ & QT]Sto imparando e vorrei qualche consiglio...


stefanoxjx
15-11-2016, 17:09
Ciao a tutti, sto imparando contemporaneamente a programmare in C++ e ad usare le Qt.
Ho letto un po' di libri ed ora sto cercando di cimentarmi sviluppando un programma che è già a buon punto, ma ovviamente mi sono lasciato dei dubbi alle spalle che se possibile vorrei chiarire con voi.

Punto 1: Il programma che sto sviluppando ha vari files .h e .cpp.
In questi files uso delle costanti che sono comuni a tutti e per non riscriverle tutte ogni volta su ogni file (altrimenti non vengono viste) ho creato un file header con nome costanti.h che vado ad includere su ogni file.
Volevo capire se questo è il modo più giusto per avere visibilità globale delle costanti o se ci sono altri modi.

Punto 2: Il programma ha una finestra principale e una finestra Opzioni.
Non sono riuscito a capire come potrei fare ad intercettare dalla finestra principale l'uscita dalla finestra "Opzioni" per richiamare un metodo che faccia degli aggiornamenti sulla finestra principale.
Mi spiego meglio, quando selezioni "Opzioni" mi si apre una nuova finestra con delle opzioni che io posso cambiare oppure no.
Vorrei che quando confermo le "Opzioni" con OK, mi si chiuda la finestra opzioni (come succede ora) ma la finestra principale sapendo di aver ripreso il controllo richiami un metodo per rileggere le impostazioni ed aggiornarsi.
Pensavo ad un segnale inerente al Focus ma su QMainWindow non trovo segnali simili.

Punto 3: Ho collegato un segnale ad uno slot con il seguente comando:

connect(&cmbTarget, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cmbTarget_currentIndexChanged(int)));

e il programma funziona senza problemi, però mi segnala questo:

QMetaObject::connectSlotsByName: No matching signal for on_cmbTarget_currentIndexChanged(int)


Ho fatto delle ricerche in merito e da quello che ho capito è perchè all'inizio avevo definito lo slot con nome diverso dal segnale.
Allora ho modificato il nome dello slot ed effettivamente il messaggio era inizialmente sparito.
Ora a volte c'è e altre no e non riesco a capire il perchè.

Punto 4: Avendo una serie di widget TextLine da completare tramite settings.value, esiste un metodo tipo foreach o simili per non maneggiarli uno ad uno?
Questo è il codice che ho scritto

ui->lineEditName1->setText(settings.value(sKeyName1).toString());
ui->lineEditName2->setText(settings.value(sKeyName2).toString());
ui->lineEditName3->setText(settings.value(sKeyName3).toString());
ui->lineEditName4->setText(settings.value(sKeyName4).toString());
ui->lineEditName5->setText(settings.value(sKeyName5).toString());
ui->lineEditName6->setText(settings.value(sKeyName6).toString());
ui->lineEditTel1->setText(settings.value(sKeyTel1).toString());
ui->lineEditTel2->setText(settings.value(sKeyTel2).toString());
ui->lineEditTel3->setText(settings.value(sKeyTel3).toString());
ui->lineEditTel4->setText(settings.value(sKeyTel4).toString());
ui->lineEditTel5->setText(settings.value(sKeyTel5).toString());
ui->lineEditTel6->setText(settings.value(sKeyTel6).toString());

ma magari con un foreach o simili me la cavo con 3 righe.

Spero che qualcuno mi possa aiutare a chiarirmi le idee.
Grazie.

Stefano

stefanoxjx
16-11-2016, 09:45
Le costanti sono variabili const.
Mi spieghi cosa intendi con:


se sono variabili const vanno dichiarate nell'header ma definite in un cpp che sara' compilato insieme al resto del programma.

Grazie.

Stefano

tomminno
16-11-2016, 16:38
Punto 1:
Dipende dal tipo della costanti che hai. Ad esempio se sono int puoi scrivere:

//Constants.h
#pragma once

class Constants
{
const int a = 5;
};


Se però hai anche stringhe devi usare un file .cpp per l'inizializzazione

Punto 2:
Se non ho capito male dovresti ridefinire il closeEvent della tua finestra e aggiungere un signal alla classe in modo da poterlo intercettare dalla finestra di tuo interesse.
Esempio:

//file dialog.h:
void closeEvent(QCloseEvent *event);
signals:
void dialogClosed();

//file dialog.cpp
Dialog::closeEvent(QCloseEvent *event)
{
emit dialogClosed();
event->accept();
}


Punto 3:
Sei sicuro di aver identificato correttamente signal e slot nella definizione delle classi? Dall'errore sembra che tu non abbia definito on_cmbTarget_currentIndexChanged come slot.
Comunque usa la sintassi C++11 e non avrai più errore anche se non hai definito uno slot, altrimenti otterrai un errore in fase di compilazione se stai sbagliando la definizione:

connect(&cmbTarget, &cmbTargetClassType::currentIndexChanged,
this, &thisClassType::on_cmbTarget_currentIndexChanged);

La sintassi C++11 funziona con tutti i metodi non solo con gli slot.

Punto 4:
se assegni un nome sequenziale ad ogni controllo, lo puoi fare facilmente in un ciclo for partendo dal controllo parent che contiene i controlli cercati:

for (int i = 1; i <= maxLineEdit; i++)
QLineEdit *lineEdit= parentWidget->findChild<QLineEdit *>("lineEditName"+QString::number(i));

stefanoxjx
16-11-2016, 20:59
Ciao e grazie della risposta.
Allora, andando per passi:

Punto 1:
Queste sono le costanti che ho messo nell'header:

#ifndef COSTANTI_H
#define COSTANTI_H

#include <QString>

const QString sKeyComPort="ComPort";
const QString sKeyBaud="Baud";
const QString sKeyDiffTime="DiffTime";
const QString sKeyName1="Name1";
const QString sKeyName2="Name2";
const QString sKeyName3="Name3";
const QString sKeyName4="Name4";
const QString sKeyName5="Name5";
const QString sKeyName6="Name6";
const QString sKeyTel1="Tel1";
const QString sKeyTel2="Tel2";
const QString sKeyTel3="Tel3";
const QString sKeyTel4="Tel4";
const QString sKeyTel5="Tel5";
const QString sKeyTel6="Tel6";
const QString sKeyLastName="LastName";

#endif // COSTANTI_H


Punto 2:
Su consiglio di un utente di un altro forum, ho sostituito la chiamata della finestra opzioni da .show() a .exec() e così ho risolto il problema.
Essendo novellino di Qt non ci avevo proprio pensato.

Punto 3:
Ieri sera mi sono messo a cercare una soluzione ed ho scoperto che quando si crea un dialogo tramite il designer, nel file MOC vengono creati già di default tutti gli eventi possibili dei vari widget che iniziano con on_ e questo crea dei conflitti se vengono definiti manualmente altri eventi uguali con lo stesso nome.
Mi è quindi bastato rinominare il mio evento togliendo l'on_ iniziale e il problema si è risolto.

Punto 4:
Tra i vari libri che ho letto mi sembrava di aver visto anche la possibilità di passare in rassegna i widget tramite un ciclo for, però non ricordavo dove.
Domani se ho un po' di tempo mi metto a fare qualche esperimento :)

Grazie.

Stefano

stefanoxjx
18-11-2016, 18:47
questo non linka se includi constanti.h da più di un file sorgente.

Eppure sembra funzionare.
Quindi, lasciando perdere che comunque sembra funzionare quale sarebbe la soluzione migliore da utilizzare?

Grazie.

Stefano

stefanoxjx
09-12-2016, 18:37
Scusate il ritardo nella risposta, ma sono stato preso da altro.
Vi ringrazio per le risposte esaustive che ho già fatto fruttare :)
Grazie ancora.

Stefano

71106
09-12-2016, 18:48
dichiarazioni nel file .h e definizioni nel file .cpp Vale per le funzioni, ma per le variabili bisogna anche usare extern.