Hi,
ich hab nach vielen, vielen Versuchen endlich eine mögliche Lösung gefunden. Allerdings bin ich mir bei einigen Sachen nicht ganz sicher...
Mein zentrales Problem war lange das ich ein QMenu das sichtbar ist, in der Größe ändern wollte. Nun habe ich eine Lösung gefunden (in menu.cpp):
Code: Alles auswählen
void Menu::onSizeChanged()
{
QActionEvent e(QEvent::ActionChanged, 0,0);
QApplication::sendEvent(this, &e);
emit sizeChanged();
}
Das funktioniert so, allerdings bin ich mir nicht sicher ob ich
QActionEvent so verwenden darf.
Ansonsten ist dies mein Code. Vielleicht mag einmal jemand darüberschauen und e.v. Verbesserungsvorschläge machen. Insbesondere nervt noch ein recht auffälliges flackern des Menüs, das ich aber nicht weg bekomme.
Code: Alles auswählen
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMenu>
class QLineEdit;
class QLabel;
class QTimer;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
Q_SIGNALS:
void sizeChanged();
protected:
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
private:
void slotShowExtender(bool);
QLabel *m_label;
QLineEdit *m_editline;
};
#endif
Code: Alles auswählen
#include "widget.h"
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QTimeLine>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
m_label = new QLabel("Foo Label");
m_editline = new QLineEdit();
m_editline->setVisible(false);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(m_label);
layout->addWidget(m_editline);
setLayout(layout);
}
void Widget::enterEvent(QEvent *)
{
slotShowExtender(true);
}
void Widget::leaveEvent(QEvent *)
{
slotShowExtender(false);
}
void Widget::slotShowExtender(bool b)
{
if(m_editline->isVisible() != b) {
m_editline->setVisible(b);
adjustSize();
resize(sizeHint());
emit sizeChanged();
}
}
Code: Alles auswählen
#ifndef SYSTEMTRAY_H
#define SYSTEMTRAY_H
#include <QSystemTrayIcon>
#include <QPoint>
class Menu;
class SystemTray : public QSystemTrayIcon
{
Q_OBJECT
public:
SystemTray();
private slots:
void slotAdjustPosition();
void slotOnActivated(QSystemTrayIcon::ActivationReason reason);
private:
Menu *m_menu;
QPoint m_menu_pos;
};
#endif
Code: Alles auswählen
#include "systemtray.h"
#include "menu.h"
#include <QApplication>
#include <QDesktopWidget>
SystemTray::SystemTray() : QSystemTrayIcon()
{
m_menu = new Menu;
setContextMenu(m_menu);
connect(m_menu, SIGNAL(sizeChanged()), this, SLOT(slotAdjustPosition()));
connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotOnActivated(QSystemTrayIcon::ActivationReason)));
}
void SystemTray::slotAdjustPosition()
{
m_menu->move( m_menu_pos.x(), m_menu_pos.y() - m_menu->height() );
}
void SystemTray::slotOnActivated(ActivationReason reason)
{
if(reason == QSystemTrayIcon::Context) {
m_menu_pos = QCursor::pos();
m_menu->popup(m_menu_pos);
slotAdjustPosition();
}
}
Code: Alles auswählen
#ifndef MENU_H
#define MENU_H
#include <QMenu>
class Menu : public QMenu
{
Q_OBJECT
public:
Menu();
Q_SIGNALS:
void sizeChanged();
private slots:
void onSizeChanged();
};
#endif
Code: Alles auswählen
#include "menu.h"
#include "widget.h"
#include <QWidgetAction>
#include <QActionEvent>
#include <QApplication>
Menu::Menu() : QMenu()
{
{
QWidgetAction *widgetAction = new QWidgetAction(this);
Widget *widget = new Widget();
widgetAction->setDefaultWidget(widget);
addAction(widgetAction);
connect(widget, SIGNAL(sizeChanged()), this, SLOT(onSizeChanged()));
}
{
QWidgetAction *widgetAction = new QWidgetAction(this);
Widget *widget = new Widget();
widgetAction->setDefaultWidget(widget);
addAction(widgetAction);
connect(widget, SIGNAL(sizeChanged()), this, SLOT(onSizeChanged()));
}
addSeparator();
addAction(new QAction("Some action", this));
addAction(new QAction("Some other action", this));
}
void Menu::onSizeChanged()
{
QActionEvent e(QEvent::ActionChanged, 0,0);
QApplication::sendEvent(this, &e);
emit sizeChanged();
}