As the title says I want to create an object of class Note and add its pointer to a list of the object of class Traymenu. I am missing the whole thing I guess, please take a look on how I call the Note's constructor in traymenus's newNote and what I am doing in 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);
}
I list each problem followed by an illustrative snippet of your mistake.
QObjects are not copyable. You can't pass their instances anywhere. You can't store their instances in most containers. std::list
is a notable example. QWidgets are QObjects, too. You can only pass QObjects by pointer, or by reference. To store QObjects in containers, you must store a smart pointer, eg std::unique_ptr
or std::shared_ptr
or QSharedPointer
to an instance created on the heap.
void newNote(QWidget, Traymenu);
Calling delete this
inside a method should be done with utmost care; except for special circumstances it's just wrong. If you're new to C++, the rule of thumb is: it's always wrong. If you want to delete an object instance that you're sure is on the heap , you can call deleteLater
. It will perform the deletion once the control returns to the event loop.
The typical way of exiting an application is by calling QCoreApplication::quit()
.
QObject::connect(actionExitProgram,&QAction::triggered,this,&Traymenu::exitProgram);
Parameters with default values must come after parameters without default values.
Note(QWidget *parent = 0, Traymenu *trayMenuIn);
When you pass a parameter in a function/method call, you don't need to provide the types again.
Note(Traymenu *this);
When holding references to QObjects whose lifetime is not well controlled, you should use QPointer
to avoid dangling pointer references. A QPointer
resets itself to zero when the object is deleted elsewhere, thus giving you a clean crash (as opposed to undefined and possibly very misleading behavior).
Traymenu *pTraymenu
Initialization of class members should be done in default member initializers, and/or an initialization list. Your code below has nothing to do with formal parameters:
Traymenu *pTraymenu = &trayMenuIn;
After all those fixes, and some others, the code looks like below. You could compile it as a self-contained, single file - it works, although you never show the notes, so they remain invisible.
// 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;
};
// TrayMenu.cpp
template <int N> auto decode64(const char (&arg)[N], int rows) {
auto const raw = QByteArray::fromBase64(QByteArray::fromRawData(arg, N-1));
QImage img((const quint8 *)raw.data(), rows, rows, raw.size()/rows, QImage::Format_MonoLSB);
img = std::move(img).convertToFormat(QImage::Format_Indexed8);
img.setColor(1, qRgba(0, 0, 0, 0)); // make transparent
return img;
}
// convert baseline_language_black_18dp.png -flatten -negate -monochrome mono:-|base64 -b80
static const char language_d64[] =
"/////w//////D/////8P/z/A/w//DwD+D/8BAPwP/wEA+A9/IEbgDz8cjuEPPxyPww8fHg+HDw+PHw8P"
"DwAAAA8PAAAADw8AAAAPx8c/Pg7Hzz8+DsfHHz4Ox4c/Pg7Hxz8/DsfHPz4ODwAAAA4PAAAADw8AAAAP"
"H48fjw8fHg+HDz8cj4MPPxiH4Q9/IMbgD/8AAPAP/wMA/A//DwD/D/8/4P8P/////w//////D/////8P";
static const auto language_icon = decode64(language_d64, 36);
// convert baseline_note_add_black_18dp.png -flatten -negate -monochrome mono:-|base64 -b80
static const char note_add_d64[] =
"/////w//////D/////8PfwDA/w8/AMD/Dz8AAP8PPwAY/w8/ADD8Dz8AePwPPwDw8A8/APjhDz8A8OMP"
"PwDwxw8/AJDCDz8AAMAPPwAAwA8/AATADz8AD8APPwAGwA8/AA/ADz8ABsAPP/D/wA8/8P/ADz/w/8AP"
"PwAOwA8/AAfADz8ADsAPPwAGwA8/AAbADz8AAMAPPwAAwA8/AADAD38AAOAP/////w//////D/////8P";
static const auto note_add_icon = decode64(note_add_d64, 36);
TrayMenu::TrayMenu() {
m_mainIcon.setIcon(QPixmap::fromImage(language_icon));
m_mainIcon.setVisible(true);
m_mainIcon.show();
createMainContextMenu();
}
void TrayMenu::newNote() {
m_notes.emplace_back(this);
m_notes.back().show();
}
void TrayMenu::createMainContextMenu() {
auto *actionNewNote = m_mainContextMenu.addAction("Neue Notiz");
m_mainContextMenu.addSeparator();
auto *actionExitProgram = m_mainContextMenu.addAction("Programm beenden");
actionNewNote->setIcon(QPixmap::fromImage(note_add_icon));
actionNewNote->setIconVisibleInMenu(true);
QObject::connect(actionNewNote, &QAction::triggered, this, &TrayMenu::newNote);
QObject::connect(actionExitProgram, &QAction::triggered, QCoreApplication::quit);
m_mainIcon.setContextMenu(&m_mainContextMenu);
}
// Note.cpp
Note::Note(TrayMenu *trayMenu, QWidget *parent) :
QWidget(parent),
m_traymenu(trayMenu)
{
m_ui.setupUi(this);
}
// main.cpp
int main(int argc, char ** argv) {
QApplication app(argc, argv);
TrayMenu menu;
return app.exec();
}
#include "main.moc"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.