Solved Riutilizzare funzioni per componenti grafici
-
@fermatqt said in Riutilizzare funzioni per componenti grafici:
non ho ben capito se e come devo ridefinire anche il distruttore della classe base!
l'hai commentato... e' il
AbstractQWidget::~AbstractQWidget() = default;
andrebbe nel file .cppcomunque
void tblRight(const QPoint &pos, QTableWidget* tbl)
rompeconnect(tbl, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(tblRight(QPoint)));
mantienilovoid tblRight(const QPoint &pos)
e usa, al suo interno,QTableWidget *tbl = qobject_cast<QTableWidget *>(sender());
-
@VRonin said in Riutilizzare funzioni per componenti grafici:
QTableWidget *tbl = qobject_cast<QTableWidget *>(sender());
si lo avevo commentato perchè mi dava un altro errore:
multiple definition of `AbstractQWidget::~AbstractQWidget()'questo il codice (comprensivo dell'altro tuo consiglio):
#ifndef ABSTRACTQWIDGET_H #define ABSTRACTQWIDGET_H #include <QWidget> #include <QMenu> #include <QTableWidget> class AbstractQWidget : public QWidget { public: AbstractQWidget(QWidget *parent = nullptr) : QWidget(parent) {} virtual ~AbstractQWidget() = 0; protected slots: void tblRight(const QPoint &pos) { QTableWidget *tbl = qobject_cast<QTableWidget *>(sender()); point = pos; QMenu *menu = new QMenu(this); QAction* actionList = menu->addAction(QString("Listini articolo")); QAction* dtlArt = menu->addAction(QString("Dettaglio articolo")); menu->popup(tbl->viewport()->mapToGlobal(pos)); connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo())); } protected: QPoint point; void menuDestro(QTableWidget *tbl) { if (tbl->rowCount() > 0) { connect(tbl, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(tblRight(QPoint))); } } }; AbstractQWidget::~AbstractQWidget() = default; #endif // ABSTRACTQWIDGET_H
-
@fermatqt said in Riutilizzare funzioni per componenti grafici:
si lo avevo commentato perchè mi dava un altro errore:
multiple definition of `AbstractQWidget::~AbstractQWidget()'@VRonin said in Riutilizzare funzioni per componenti grafici:
andrebbe nel file .cpp
devi spostare quella linea nel file AbstractQWidget.cpp
-
scusami, non sono ancora pratico di ereditarietà e c++!
adesso il file di intestazione è così:
#ifndef ABSTRACTQWIDGET_H #define ABSTRACTQWIDGET_H #include <QWidget> #include <QMenu> #include <QTableWidget> class AbstractQWidget : public QWidget { public: AbstractQWidget(QWidget *parent = nullptr) : QWidget(parent) {} virtual ~AbstractQWidget() = 0; protected slots: void tblRight(QPoint point) { QTableWidget *tbl = qobject_cast<QTableWidget *>(sender()); QMenu *menu = new QMenu(this); QAction* actionList = menu->addAction(QString("Listini articolo")); QAction* dtlArt = menu->addAction(QString("Dettaglio articolo")); menu->popup(tbl->viewport()->mapToGlobal(point)); connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo())); } protected: QPoint point; void menuDestro(QTableWidget *tbl) { if (tbl->rowCount() > 0) { connect(tbl, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(tblRight(QPoint))); } } }; #endif // ABSTRACTQWIDGET_H
a questo punto riesco a compilare ed avviare il programma.
però al momento in cui clicco col tasto destro sul mouse sulla QTableWidget:QObject::connect: No such slot Articoli::tblRight(QPoint) QObject::connect: (sender name: 'tblArticoli') QObject::connect: (receiver name: 'Articoli')
come se non vedesse lo slot!
-
strano... puoi vedere se con la nuova sintassi l'errore e' piu' comprensibile:
connect(tbl, &QTableWidget::customContextMenuRequested, this, &AbstractQWidget::tblRight);
anche
getListiniArticolo
manca in AbstractQWidget, chiaro se usi la nuova connect anche quiconnect(actionList, &QAction::triggered, this, &AbstractQWidget::getListiniArticolo);
Edit:
Mi sono accorto dell'errore piu' grave, manca
Q_OBJECT
, mea culpa!class AbstractQWidget : public QWidget { Q_OBJECT public: //il resto
questo dovrebbe risolvere il problema QObject::connect: No such slot Articoli::tblRight(QPoint), quello getListiniArticolo rimane
-
ciao!
ieri girovagando avevo già visto Q_OBJECT.
solo che se lo metto ottengo un'altra pletora di errori:
In functionAbstractQWidget::AbstractQWidget(QWidget*)': error: undefined reference to
vtable for AbstractQWidget'
In functionArticoli::qt_metacast(char const*)': error: undefined reference to
AbstractQWidget::qt_metacast(char const*)'
error: undefined reference to `AbstractQWidget::qt_metacall(QMetaObject::Call, int, void**)'
ecc....ho già provato a fare il clean e rebuild.
ma nulla da fare.
questo il codice:#ifndef ABSTRACTQWIDGET_H #define ABSTRACTQWIDGET_H #include <QWidget> #include <QMenu> #include <QTableWidget> class AbstractQWidget : public QWidget { Q_OBJECT public: AbstractQWidget(QWidget *parent = nullptr) : QWidget(parent) {} virtual ~AbstractQWidget() = 0; protected slots: void tblRight(QPoint point) { QTableWidget *tbl = qobject_cast<QTableWidget *>(sender()); QMenu *menu = new QMenu(this); QAction* actionList = menu->addAction(QString("Listini articolo")); QAction* dtlArt = menu->addAction(QString("Dettaglio articolo")); menu->popup(tbl->viewport()->mapToGlobal(point)); connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo())); } protected: QPoint point; void menuDestro(QTableWidget *tbl) { if (tbl->rowCount() > 0) { connect(tbl, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(tblRight(QPoint))); } } }; #endif // ABSTRACTQWIDGET_H
-
@fermatqt said in Riutilizzare funzioni per componenti grafici:
ho già provato a fare il clean e rebuild.
purtroppo qmake non e' molto intelligente, devi ri-eseguirlo manualmente se cambi il .pro file o se inserisci un
Q_OBJECT
. Ti basta andare su build->run qmake in Qt CreatorP.S.
questo:connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo()));
fallira' per le regioni elencate sopra -
allora, dopo il Run qmake lo compila e lo avvia.
come dicevi te, però, non lanciava getListiniArticolo.
allora l'ho levato dalla classe Articoli, e l'ho messo nella classe base:#ifndef ABSTRACTQWIDGET_H #define ABSTRACTQWIDGET_H #include <QWidget> #include <QMenu> #include <QTableWidget> #include "listiniarticolo.h" class AbstractQWidget : public QWidget { Q_OBJECT public: AbstractQWidget(QWidget *parent = nullptr) : QWidget(parent) {} virtual ~AbstractQWidget() = 0; protected slots: void tblRight(QPoint point) { QTableWidget *tbl = qobject_cast<QTableWidget *>(sender()); QMenu *menu = new QMenu(this); QAction* actionList = menu->addAction(QString("Listini articolo")); //QAction* dtlArt = menu->addAction(QString("Dettaglio articolo")); menu->popup(tbl->viewport()->mapToGlobal(point)); connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo(tbl))); } void getListiniArticolo(QTableWidget *tbl) { int selRow = tbl->row(tbl->itemAt(point)); QString selArt = tbl->item(selRow, 1)->text(); ListiniArticolo *la = new ListiniArticolo(selArt); la->show(); } protected: QPoint point; void menuDestro(QTableWidget *tbl) { if (tbl->rowCount() > 0) { connect(tbl, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(tblRight(QPoint))); } } }; #endif // ABSTRACTQWIDGET_H
ma ottengo sempre questo errore:
QObject::connect: No such slot Articoli::getListiniArticolo(tbl)
QObject::connect: (receiver name: 'Articoli')ho provato a fare il clean, rilanciare il qmake, ecc.
ma nulla, non lo vede. -
connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo(tbl)));
connect non funziona cosi'... http://doc.qt.io/qt-5/signalsandslots.html
fai cosi':
class AbstractQWidget : public QWidget { Q_OBJECT public: AbstractQWidget(QWidget *parent = nullptr) : QWidget(parent) {} virtual ~AbstractQWidget() = 0; protected slots: void tblRight(QPoint point) { QTableWidget *tbl = qobject_cast<QTableWidget *>(sender()); QMenu *menu = new QMenu(this); QAction* actionList = menu->addAction(QString("Listini articolo")); //QAction* dtlArt = menu->addAction(QString("Dettaglio articolo")); menu->popup(tbl->viewport()->mapToGlobal(point)); connect(actionList, &QAction::triggered, this, &AbstractQWidget::getListiniArticolo); } virtual void getListiniArticolo() = 0; protected: void getListiniArticoloTable(QTableWidget *tbl) { int selRow = tbl->row(tbl->itemAt(point)); QString selArt = tbl->item(selRow, 1)->text(); ListiniArticolo *la = new ListiniArticolo(selArt); la->show(); } protected: QPoint point; void menuDestro(QTableWidget *tbl) { if (tbl->rowCount() > 0) { connect(tbl, &QTableWidget::customContextMenuRequested, this, &AbstractQWidget::tblRight); } } }; #endif // ABSTRACTQWIDGET_H
poi in
Articoli
reimplementiprotected slots: virtual void getListiniArticolo() override {getListiniArticoloTable(ui->tblArticoli);}
-
ciao!
penso di aver capito meglio, ma come mi giro faccio casino :(allora:
#ifndef ABSTRACTQWIDGET_H #define ABSTRACTQWIDGET_H #include <QWidget> #include <QMenu> #include <QTableWidget> #include "listiniarticolo.h" class AbstractQWidget : public QWidget { Q_OBJECT public: AbstractQWidget(QWidget *parent = nullptr) : QWidget(parent) {} virtual ~AbstractQWidget() = 0; protected slots: void tblRight(QPoint point) { QTableWidget *tbl = qobject_cast<QTableWidget *>(sender()); QMenu *menu = new QMenu(this); QAction* actionList = menu->addAction(QString("Listini articolo")); //QAction* dtlArt = menu->addAction(QString("Dettaglio articolo")); menu->popup(tbl->viewport()->mapToGlobal(point)); //connect(actionList, SIGNAL(triggered()), this, SLOT(getListiniArticolo(tbl))); connect(actionList, &QAction::triggered, this, &AbstractQWidget::getListiniArticolo); } virtual void getListiniArticolo() = 0; protected: QPoint point; void menuDestro(QTableWidget *tbl) { if (tbl->rowCount() > 0) { //connect(tbl, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(tblRight(QPoint))); connect(tbl, &QTableWidget::customContextMenuRequested, this, &AbstractQWidget::tblRight); } } void getListiniArticoloTable(QTableWidget *tbl) { int selRow = tbl->row(tbl->itemAt(point)); QString selArt = tbl->item(selRow, 1)->text(); ListiniArticolo *la = new ListiniArticolo(selArt); la->show(); } }; #endif // ABSTRACTQWIDGET_H
e fino a qui ok.
poi dentro articoli articoli.h:namespace Ui { class Articoli; } class Articoli : public AbstractQWidget { Q_OBJECT public: explicit Articoli(AbstractQWidget *parent = 0); virtual ~Articoli(); protected slots: virtual void getListiniArticolo() override { getListiniArticoloTable(ui->tblArticoli); } private slots: void on_btnCollezione_clicked(); void on_btnGiorni_clicked(); void txtSearch(QString search); //void getListiniArticolo(); void toUpper(const QString &text); private: Ui::Articoli *ui; Database *db; QStringList header; LoadingDialog pd; };
ma ottengo un errore:
error: invalid use of incomplete type ‘class Ui::Articoli’ getListiniArticoloTable(ui->tblArticoli);
forward declaration of ‘class Ui::Articoli’ class Articoli;ho provato a dare un'occhiata su google, ma non ne sono uscito.
credo di aver capito il problema, ma non so come risolverlo.
ho anche provato a cambiare il modificatore di accesso di Ui::Articoli *ui; -
non e' un vero problema solo un piccolo accorgimento tecnico. Invece di lasciare
protected slots: virtual void getListiniArticolo() override { getListiniArticoloTable(ui->tblArticoli); }
nel file .h, trasformalo in dichiarazione+implementazione, cioe'
Nel file .h:
protected slots: virtual void getListiniArticolo() override;
Nel file .cpp
void Articoli::getListiniArticolo(){ getListiniArticoloTable(ui->tblArticoli); }
Il problema e' dovuto al fatto che nel file .h
ui
non e' completamente definito -
perfetto, adesso funziona tutto.
mi alleno un pò su tutti gli altri metodi che devo "condividere", così capisco un pò meglio...grazie mille per l'aiuto!!