Slot with pointers as a parameters
-
Hello. I'm trying to refactor my code in project. I have 2 forms mainwindow and controls. So i decided to start refactoring from the addButtonPressed() function and basically move it from mainwindow to the controls. But here's the problem. Basically when i press the button, everything works but when i'm trying to add files to my PlaylistView (QTableView) nothing is showing, but files has been added, i checked that with QDebug(), and as far as i understand it's because in Controls class i don't have QMediaPlaylist mediaPlaylist and QStandardItemModel standardPlaylistModel. They are in MainWindow class as you can see. And as far as i understand if simply put them in Controls class private but in that case THEY ARE NOT THE SAME INSTANCES and that's why nothing is working. So now i'm trying to pass them as copies using pointers and everything is okay except one thing. I can't make a connect() because signatures are not matching. And so i'm wondering how do i connect a button to such slot? I guess i need to use lambdas? I tried but did not succeeded. Or maybe something with constructor? So what i'm doing wrong? And maybe there are simplier ways?
Sorry for the long read, i'm just trying to show you the whole picture, i hope i didn't confuse you
Here's the code(not full as i'm trying to keep it as short as possible for you and showing only important parts)
MainWindow.h
QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); int volume() const; ~MainWindow(); private: Ui::MainWindow *ui; std::unique_ptr<QMediaPlayer> mediaPlayer = std::make_unique<QMediaPlayer>(this); std::unique_ptr<QMediaPlaylist> mediaPlaylist = std::make_unique<QMediaPlaylist>(this); std::unique_ptr<QStandardItemModel> standardPlaylistModel = std::make_unique<QStandardItemModel>(this); }; #endif // MAINWINDOW_HControls.h
#ifndef CONTROLS_H #define CONTROLS_H #include "mainwindow.h" #include <QWidget> namespace Ui { class Controls; } class Controls : public QWidget { Q_OBJECT public: explicit Controls(QWidget *parent = nullptr); ~Controls(); public slots: void addButtonPressed(QMediaPlaylist *playlist, QStandardItemModel *model); private: Controls *controls; Ui::Controls *ui; }; #endif // CONTROLS_HControls.cpp
#include "controls.h" #include "mainwindow.h" #include "ui_controls.h" Controls::Controls(QWidget *parent) : QWidget(parent), ui(new Ui::Controls) { ui->setupUi(this); } Controls::~Controls() { delete ui; } void Controls::addButtonPressed(QMediaPlaylist *playlist, QStandardItemModel *model) { QStringList files = QFileDialog::getOpenFileNames(this, "Open music", QString(), "Audio files (*mp3 *flac" "*ogg *raw" "*wav *aiff" "*au *wma" "*aax *aa)"); for(QString &filepath : files ) { QList<QStandardItem *> items; items.append(new QStandardItem(QDir(filepath).dirName())); model->appendRow(items); playlist->addMedia(QUrl(filepath)); } } -
Hello. I'm trying to refactor my code in project. I have 2 forms mainwindow and controls. So i decided to start refactoring from the addButtonPressed() function and basically move it from mainwindow to the controls. But here's the problem. Basically when i press the button, everything works but when i'm trying to add files to my PlaylistView (QTableView) nothing is showing, but files has been added, i checked that with QDebug(), and as far as i understand it's because in Controls class i don't have QMediaPlaylist mediaPlaylist and QStandardItemModel standardPlaylistModel. They are in MainWindow class as you can see. And as far as i understand if simply put them in Controls class private but in that case THEY ARE NOT THE SAME INSTANCES and that's why nothing is working. So now i'm trying to pass them as copies using pointers and everything is okay except one thing. I can't make a connect() because signatures are not matching. And so i'm wondering how do i connect a button to such slot? I guess i need to use lambdas? I tried but did not succeeded. Or maybe something with constructor? So what i'm doing wrong? And maybe there are simplier ways?
Sorry for the long read, i'm just trying to show you the whole picture, i hope i didn't confuse you
Here's the code(not full as i'm trying to keep it as short as possible for you and showing only important parts)
MainWindow.h
QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); int volume() const; ~MainWindow(); private: Ui::MainWindow *ui; std::unique_ptr<QMediaPlayer> mediaPlayer = std::make_unique<QMediaPlayer>(this); std::unique_ptr<QMediaPlaylist> mediaPlaylist = std::make_unique<QMediaPlaylist>(this); std::unique_ptr<QStandardItemModel> standardPlaylistModel = std::make_unique<QStandardItemModel>(this); }; #endif // MAINWINDOW_HControls.h
#ifndef CONTROLS_H #define CONTROLS_H #include "mainwindow.h" #include <QWidget> namespace Ui { class Controls; } class Controls : public QWidget { Q_OBJECT public: explicit Controls(QWidget *parent = nullptr); ~Controls(); public slots: void addButtonPressed(QMediaPlaylist *playlist, QStandardItemModel *model); private: Controls *controls; Ui::Controls *ui; }; #endif // CONTROLS_HControls.cpp
#include "controls.h" #include "mainwindow.h" #include "ui_controls.h" Controls::Controls(QWidget *parent) : QWidget(parent), ui(new Ui::Controls) { ui->setupUi(this); } Controls::~Controls() { delete ui; } void Controls::addButtonPressed(QMediaPlaylist *playlist, QStandardItemModel *model) { QStringList files = QFileDialog::getOpenFileNames(this, "Open music", QString(), "Audio files (*mp3 *flac" "*ogg *raw" "*wav *aiff" "*au *wma" "*aax *aa)"); for(QString &filepath : files ) { QList<QStandardItem *> items; items.append(new QStandardItem(QDir(filepath).dirName())); model->appendRow(items); playlist->addMedia(QUrl(filepath)); } }@Nick-Shapper Only one of these two classes should know about QMediaPlaylist and QStandardItemModel, you should not pass them as parameter. Keep them in MainWindow and call a method in Controls on button press which returns a list of files to add. Then add these files inside MainWindow (so, connect a MainWindow slot to button and in this slot call that method in Controlls). This way you have a clean architecture and Controls does not have to know what actually happens with these files.
-
@Nick-Shapper Only one of these two classes should know about QMediaPlaylist and QStandardItemModel, you should not pass them as parameter. Keep them in MainWindow and call a method in Controls on button press which returns a list of files to add. Then add these files inside MainWindow (so, connect a MainWindow slot to button and in this slot call that method in Controlls). This way you have a clean architecture and Controls does not have to know what actually happens with these files.
@jsulm Thank you for reply. Ok, i got it. I'll try to do that
-
@Nick-Shapper Only one of these two classes should know about QMediaPlaylist and QStandardItemModel, you should not pass them as parameter. Keep them in MainWindow and call a method in Controls on button press which returns a list of files to add. Then add these files inside MainWindow (so, connect a MainWindow slot to button and in this slot call that method in Controlls). This way you have a clean architecture and Controls does not have to know what actually happens with these files.
@jsulm By the way, maybe you know some sources where i can learn that stuff?(books, maybe some docs, or even some tutorials come to mind?) It seems pretty complicated to me at the moment
-
@jsulm By the way, maybe you know some sources where i can learn that stuff?(books, maybe some docs, or even some tutorials come to mind?) It seems pretty complicated to me at the moment
@Nick-Shapper Search for "software design" and "software architecture". Is a quite broad topic.
-
@Nick-Shapper Search for "software design" and "software architecture". Is a quite broad topic.
@jsulm Ok, thank you