2014-02-13 57 views
0

由於標題說我想創建類Note的對象並將其指針添加到類Traymenu的對象列表中。我錯過了我猜想的所有事情,請看看我如何在traymenus的newNote中調用Note的構造函數以及我在note.h中做了什麼。將類的實例傳遞給另一個構造函數,該構造函數將其對象添加到傳遞實例擁有的列表中

traymenu.h:

#ifndef TRAYMENU_H 
#define TRAYMENU_H 

#include <QSystemTrayIcon> 
#include <QIcon> 
#include <QPixmap> 
#include <QMenu> //in use for context menu 
#include <QList> 

#include "note.h" 

class Traymenu : public QSystemTrayIcon 
{ 
public: 
    Traymenu(); 
    ~Traymenu(); 
    void createMainContextMenu(); 
    void newNote(QWidget, Traymenu); 
    void exitProgram(); 

private: 
    QSystemTrayIcon mainIcon; 
    QMenu mainContextMenu; 
    QList<Note> notelist; //List that holds references to Note objects 
          //template argument 1 is invalid 

}; 
#endif // TRAYMENU_H 

traymenu.cpp:

#include "traymenu.h" 
#include <QDebug> 

Traymenu::Traymenu(){ 
    mainIcon.setIcon(QIcon(QPixmap("C:\\program.png"))); 
    mainIcon.setVisible(true); 
    mainIcon.show(); 

    createMainContextMenu(); 
} 

Traymenu::~Traymenu(){ 
} 

void Traymenu::newNote(){ 
    Note(Traymenu *this); //HOW TO PASS THE TRAYMENU INSTANC TO NOTE??? 
} 

void Traymenu::exitProgram(){ 
    delete this; //deletes traymenu object (icon disappears) 
} 

void Traymenu::createMainContextMenu(){ 
    QAction *actionNewNote = mainContextMenu.addAction("Neue Notiz"); 
    mainContextMenu.addSeparator(); 
    QAction *actionExitProgram = mainContextMenu.addAction("Programm beenden"); 

    actionNewNote->setIcon(QIcon("C:\\new.ico")); 
    actionNewNote->setIconVisibleInMenu(true); 

    //Qt5 new signal connection: http://qt-project.org/wiki/New_Signal_Slot_Syntax 
    QObject::connect(actionNewNote,&QAction::triggered,this,&Traymenu::newNote); 
    QObject::connect(actionExitProgram,&QAction::triggered,this,&Traymenu::exitProgram); 

    mainIcon.setContextMenu(&mainContextMenu); 
} 

note.h:

#ifndef NOTE_H 
#define NOTE_H 

#include <QWidget> 
#include "traymenu.h" 

namespace Ui{ 
class Note; 
} 

class Note : public QWidget 
{ 
public: 
    Note(QWidget *parent = 0, Traymenu *trayMenuIn); 
    ~Note(); 
    void appendNoteToNotelist(); 

private: 
    Q_OBJECT 
    Ui::Note *ui; 
    Traymenu *pTraymenu = &trayMenuIn; //trayMenuIn was not declared in this scope 
             //Why declare a formal parameter? 
}; 
#endif // NOTE_H 

note.cpp:

#include "note.h" 
#include "ui_note.h" 

Note::Note(QWidget *parent, Traymenu *trayMenuIn) : 
    QWidget(parent), 
    ui(new Ui::Note) 
{ 
    ui->setupUi(this); 
    Note::appendNoteToNotelist(); 
} 

Note::~Note() 
{ 
    delete ui; 
} 

void Note::appendNoteToNotelist(){ 
    pTraymenu.append(&ui); 
} 
+0

+1提供的源代碼,-1代碼與傾銷代碼有很多與問題本身無關的問題 –

回答

1

我列出了每個問題,然後列出了您的錯誤的說明片段。

  • QObject不可複製。你無法在任何地方傳遞他們的實例。你不能將它們的實例存儲在容器中。 QWidgets也是QObject。您只能通過指針或引用傳遞QObject。要將QObject存儲在容器中,必須將QSharedPointer存儲到在堆上創建的實例。

    void newNote(QWidget, Traymenu); 
    
  • 調用delete this的方法中應極其謹慎進行;除特殊情況外,這只是錯誤的。如果你不熟悉C++,經驗法則是:它總是錯誤的。如果你想刪除一個的對象實例,你肯定是在堆上,你可以撥打deleteLater。一旦控制返回到事件循環,它將執行刪除操作。

  • 退出應用程序的典型方法是致電qApp->quit()

    QObject::connect(actionExitProgram,&QAction::triggered,this,&Traymenu::exitProgram); 
    
  • 具有默認值的參數必須在沒有默認值的參數之後。

    Note(QWidget *parent = 0, Traymenu *trayMenuIn); 
    
  • 當您在函數/方法調用中傳遞參數時,不需要再次提供類型。

    Note(Traymenu *this); 
    
  • 當抱着的QObject其一生沒有得到很好的控制引用,你應該使用QPointer避免懸空指針引用。 QPointer在其他地方刪除對象時會將自身重置爲零,從而爲您提供乾淨的崩潰(與未定義且可能非常具有誤導性的行爲相反)。

    Traymenu *pTraymenu 
    
  • 類成員的初始化應該在初始化列表來完成。下面您的代碼無關的形式參數:

    Traymenu *pTraymenu = &trayMenuIn; 
    

所有這些修正後,和其他一些人,代碼看起來像下面。你可以將它編譯爲一個獨立的單一文件 - 它可以工作,儘管你從不顯示註釋,所以它們仍然是不可見的。

#include <QApplication> 
#include <QSystemTrayIcon> 
#include <QIcon> 
#include <QPixmap> 
#include <QMenu> 
#include <QList> 
#include <QPointer> 

// Note.h 

namespace Ui{ 
class Note { 
public: 
    void setupUi(QWidget *) {} // dummy for sscce.org 
}; 
} 

class TrayMenu; 
class Note : public QWidget 
{ 
    Q_OBJECT 
public: 
    Note(TrayMenu *trayMenu, QWidget *parent = 0); 
    ~Note(); 
private: 
    QScopedPointer<Ui::Note> m_ui; 
    QPointer<TrayMenu> m_traymenu; 
}; 

// TrayMenu.h 

class Note; 
class TrayMenu : public QSystemTrayIcon 
{ 
public: 
    TrayMenu(); 
    ~TrayMenu(); 
    void createMainContextMenu(); 
    void newNote(); 
private: 
    QSystemTrayIcon mainIcon; 
    QMenu mainContextMenu; 
    QList<QSharedPointer<Note> > noteList; 
}; 

// TrayMenu.cpp 

TrayMenu::TrayMenu(){ 
    mainIcon.setIcon(QIcon(QPixmap("C:\\program.png"))); 
    mainIcon.setVisible(true); 
    mainIcon.show(); 

    createMainContextMenu(); 
} 

TrayMenu::~TrayMenu() {} 

void TrayMenu::newNote() { 
    QSharedPointer<Note> note(new Note(this)); 
    noteList << note; 
} 

void TrayMenu::createMainContextMenu(){ 
    QAction *actionNewNote = mainContextMenu.addAction("Neue Notiz"); 
    mainContextMenu.addSeparator(); 
    QAction *actionExitProgram = mainContextMenu.addAction("Programm beenden"); 

    actionNewNote->setIcon(QIcon("C:\\new.ico")); 
    actionNewNote->setIconVisibleInMenu(true); 

    QObject::connect(actionNewNote, &QAction::triggered, this, &TrayMenu::newNote); 
    QObject::connect(actionExitProgram, &QAction::triggered, qApp, &QCoreApplication::quit); 

    mainIcon.setContextMenu(&mainContextMenu); 
} 

// Note.cpp 

Note::Note(TrayMenu *trayMenu, QWidget *parent) : 
    QWidget(parent), 
    m_ui(new Ui::Note), 
    m_traymenu(trayMenu) 
{ 
    m_ui->setupUi(this); 
} 

Note::~Note() {} 

// main.cpp 

int main(int argc, char ** argv) { 
    QApplication app(argc, argv); 
    TrayMenu menu; 
    return app.exec(); 
} 

#include "main.moc" 
+0

謝謝您的詳細回答:) – user2366975

相關問題