正如标题所说,我想创建一个类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 :(得分:2)
我列出了每个问题,然后是错误的说明性摘要。
QObjects不可复制。你无法在任何地方传递他们的实例。您无法将其实例存储在大多数容器中。 std::list
是一个值得注意的例子。 QWidgets也是QObjects。您只能通过指针或引用传递QObject。要将QObject存储在容器中,必须存储智能指针,例如<{1}}或std::unique_ptr
或std::shared_ptr
到堆上创建的实例。
QSharedPointer
在方法中调用void newNote(QWidget, Traymenu);
应该非常谨慎;除了特殊情况,这是错的。如果你是C ++的新手,经验法则是:它总是错的。如果要删除您确定在堆上的对象实例,可以调用delete this
。一旦控件返回到事件循环,它将执行删除。
退出应用程序的典型方法是调用deleteLater
。
QCoreApplication::quit()
带有默认值的参数必须位于没有默认值的参数之后。
QObject::connect(actionExitProgram,&QAction::triggered,this,&Traymenu::exitProgram);
在函数/方法调用中传递参数时,不需要再次提供类型。
Note(QWidget *parent = 0, Traymenu *trayMenuIn);
当保持对生命周期控制不佳的QObject的引用时,应使用Note(Traymenu *this);
来避免悬空指针引用。当对象在其他地方被删除时,QPointer
将自身重置为零,从而为您提供干净的崩溃(与未定义且可能非常误导的行为相反)。
QPointer
类成员的初始化应该在默认成员初始值设定项和/或初始化列表中完成。您的代码与正式参数无关:
Traymenu *pTraymenu
在完成所有这些修复以及其他一些修复后,代码如下所示。你可以将它编译为一个独立的单个文件 - 它可以工作,虽然你从不显示笔记,所以它们仍然是不可见的。
Traymenu *pTraymenu = &trayMenuIn;
// https://github.com/KubaO/stackoverflown/tree/master/questions/note-tray-21753641
#include <QtWidgets>
#include <list>
// 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 = {});
private:
Ui::Note m_ui;
QPointer<TrayMenu> m_traymenu;
};
// TrayMenu.h
class Note;
class TrayMenu : public QObject {
Q_OBJECT
public:
TrayMenu();
void createMainContextMenu();
void newNote();
private:
QSystemTrayIcon m_mainIcon;
QMenu m_mainContextMenu;
std::list<Note> m_notes;
};