QMenu und Extender-Widget...

Alles rund um die Programmierung mit Qt
Antworten
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

QMenu und Extender-Widget...

Beitrag von hilefoks »

Hi,

sorry für den komischen Titel. ;-)

Ich möchte in einem QMenu ein eigenes Widget einfügen das bei einem enterEvent(), also wenn die Maus über dem Widget steht, expandiert.

Also als Beispiel: Ich habe ein QWidget das aus zwei untereinander angeordneten QLabel besteht. Dieses Widget steckt im QMenu (mittels QWidgetAction).
Was ich nun möchte, aber nicht hinbekomme, ist: Das zweite, untere Label soll eingeblendet werden wenn die Maus über das Widget fährt und entsprechend wieder ausblenden, wenn die Maus das Widget verlässt.

Hat jemand eine Idee wie ich das am besten anstelle?

Danke.
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Beitrag von hilefoks »

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();
}
Antworten