Russian Qt Forum
Ноябрь 17, 2024, 23:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как реализовать контекстное меню для виджетов?  (Прочитано 21315 раз)
smirnoff
Гость
« : Январь 28, 2011, 17:21 »

Добрый день.

Помогите разобраться. Хочу понять как создать контекстное меню для любого из виджетов. Например для QLineEdit.
Имеем:

Код:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    QLineEdit ln(&w);

    w.show();

    return a.exec();
}

Вопрос: как создать свое контекстное меню для ln?

Для самого виджета Widget создать меню не проблема (подглядел в examples):

Код:
void Widget::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(QPixmap("C:\\Qt\\pro\\popupmenu-build-desktop\\debug\\ico.png"), "ShowMessage", this, SLOT(msg()));
    menu.addAction("About Qt", qApp, SLOT(aboutQt()));
    menu.addSeparator();
    menu.addAction("Exit", qApp, SLOT(qApp->exit()));
    menu.exec(event->globalPos());
}

А как для других виджетов?

Спасибо за советы, комментарии, ссылки...
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Январь 28, 2011, 17:28 »

QMenu * QLineEdit::createStandardContextMenu ()
Записан

Qt 5.11/4.8.7 (X11/Win)
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #2 : Январь 28, 2011, 17:52 »

Цитировать
как создать контекстное меню для любого из виджетов.
Переопределить mousePressEvent
Код:
#include <QtGui/QApplication>
#include <QLineEdit>
#include <QMenu>
#include <QMouseEvent>

class myLineEdit : public QLineEdit
{
public:
myLineEdit(QWidget *p = 0)
:QLineEdit(p) {}
virtual void mousePressEvent ( QMouseEvent *event )
{
if( event->button() == Qt::RightButton)
{
QMenu menu(this);
menu.addAction("ShowMessage");
menu.addAction("About Qt");
menu.addSeparator();
menu.addAction("Exit");
menu.exec(event->globalPos());
}
else
QLineEdit::mousePressEvent(event);
}

};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;

QLineEdit *ln = new myLineEdit(&w);

w.show();

return a.exec();

}
Записан
smirnoff
Гость
« Ответ #3 : Январь 28, 2011, 18:05 »

QMenu * QLineEdit::createStandardContextMenu ()

Вот это не понял как применить. Хотелось бы пример.

Цитировать
как создать контекстное меню для любого из виджетов.
Переопределить mousePressEvent
Код:
#include <QtGui/QApplication>
#include <QLineEdit>
#include <QMenu>
#include <QMouseEvent>

class myLineEdit : public QLineEdit
{
public:
myLineEdit(QWidget *p = 0)
:QLineEdit(p) {}
virtual void mousePressEvent ( QMouseEvent *event )
{
if( event->button() == Qt::RightButton)
{
QMenu menu(this);
menu.addAction("ShowMessage");
menu.addAction("About Qt");
menu.addSeparator();
menu.addAction("Exit");
menu.exec(event->globalPos());
}
else
QLineEdit::mousePressEvent(event);
}

};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;

QLineEdit *ln = new myLineEdit(&w);

w.show();

return a.exec();

}

Это работает. Спасибо.

Как я понял мы описываем свой класс, который является наследником QLineEdit, в котором определяем функцию, реагирующую на события мыши, где выделяем нажатие на правую кнопку (Qt::RightButton).

Огромное спасибо.
Записан
Fat-Zer
Гость
« Ответ #4 : Январь 28, 2011, 18:24 »

Цитировать
как создать контекстное меню для любого из виджетов.
Переопределить mousePressEvent

Из пушки по воробьям...
всё намного проще:
Код
C++ (Qt)
#include <QApplication>
#include <QLineEdit>
#include <QAction>
 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineEdit le;
le.show();
le.addAction(new QAction(QObject::tr("qwe"),&le));
le.addAction(new QAction(QObject::tr("asd"),&le));
le.setContextMenuPolicy(Qt::ActionsContextMenu);
 
return a.exec();
}
 
Записан
smirnoff
Гость
« Ответ #5 : Январь 28, 2011, 18:40 »

Цитировать
как создать контекстное меню для любого из виджетов.
Переопределить mousePressEvent

Из пушки по воробьям...
всё намного проще:
Код
C++ (Qt)
#include <QApplication>
#include <QLineEdit>
#include <QAction>
 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineEdit le;
le.show();
le.addAction(new QAction(QObject::tr("qwe"),&le));
le.addAction(new QAction(QObject::tr("asd"),&le));
le.setContextMenuPolicy(Qt::ActionsContextMenu);
 
return a.exec();
}
 

Отлично. Минимализм сейчас в моде. :-) А как привязать пункт меню "qwe" и другие к слоту? Есть пример?

 
Записан
Etud
Гость
« Ответ #6 : Январь 28, 2011, 19:16 »

Цитировать
Отлично. Минимализм сейчас в моде.
Может ты хотел сказать оптимализм ?!!

Цитировать
А как привязать пункт меню "qwe" и другие к слоту? Есть пример?

Еще проще.

Создай объект action, сделай connect()  и пользуйся слотами.
Записан
smirnoff
Гость
« Ответ #7 : Январь 28, 2011, 19:41 »

Сделал так, все заработало:

Код:
#include <QtGui>
#include "widget.h"


void Widget::sw()
{
    QMessageBox::information(0, "Information", "Information message text");
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    QLineEdit le(&w);
    QAction *mAct, *sAct;

    mAct = new QAction("qwe", &le);
    sAct = new QAction("asd", &le);

    le.addAction(mAct);
    le.addAction(sAct);
    le.setContextMenuPolicy(Qt::ActionsContextMenu);

    le.connect(mAct, SIGNAL(triggered()), &w, SLOT(sw()));

    w.show();

    return a.exec();
}

Все ли верно? Или есть у кого-нибудь замечания по поводу моего кода?
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #8 : Январь 28, 2011, 21:57 »

>> Для самого виджета Widget создать меню не проблема
>> ...
>> А как для других виджетов?
аналогично, ведь они тоже виджеты

>>Все ли верно?
скомпилль, запусти, узнаешь
Записан

Юра.
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #9 : Январь 29, 2011, 11:08 »

Из пушки по воробьям...
всё намного проще:
не знал про такой метод.... А как "простым" методом сепаратор вставить?

Цитировать
Цитировать
QMenu * QLineEdit::createStandardContextMenu ()
Вот это не понял как применить. Хотелось бы пример.

У QLineEdit есть стандартное контекстное меню (Copy, Paste, Cut, ....). Если нужно дополнить это сандартное меню своими пунктами, то в "пушке", в  mousePressEvent содаем стандартное меню и добавляем свои пункты

Код:
...
if( event->button() == Qt::RightButton)
{
QMenu *menu = createStandardContextMenu();
menu.addAction("ShowMessage");
menu.addAction("About Qt");
menu.addSeparator();
menu.addAction("Exit");
menu.exec(event->globalPos());
}....
возможно и без переопределения mousePressEvent можно добавить к стандартному меню свои пункты.
Записан
Fat-Zer
Гость
« Ответ #10 : Январь 29, 2011, 13:57 »

Из пушки по воробьям...
всё намного проще:
не знал про такой метод.... А как "простым" методом сепаратор вставить?
сепаратор - тот же QAction
Код
C++ (Qt)
QAction* sep = new QAction(le);
sep->setSeparator(1);
le->addAction(sep);
 
конечно приятно было бы в одну строчку записать... но я не нашёл как...

есть ещё два способа показывать меню... здесь всё расписывать не буду, посмотрите справку про Qt::ContextMenuPolicy и всё сразу станет ясно Подмигивающий
ЗЫ: А если наследовать, то лучше перехватывать contextMenuEvent.

Записан
Krow
Гость
« Ответ #11 : Март 27, 2011, 07:26 »

а теперь вопрос. а что если конткстное меню динамическое.
допустим:
О программе:
сепаратор
список действий(открываем раскрывающийся список)->
             послать на ярмарку,
             позвать с ярмарки
             и т.д.

сепаратор
выход

список сдействий берется из бд. (он может быть динамическим, потому как список "куда послать может меняться")
как в таком случае QAction'ы завязать?
Записан
fuCtor
Гость
« Ответ #12 : Март 27, 2011, 20:11 »

Код
C++ (Qt)
   QAction *mAct, *sAct;
 
   mAct = new QAction("qwe", &le);
   sAct = new QAction("asd", &le);
 
   le.addAction(mAct);
   le.addAction(sAct);
   le.setContextMenuPolicy(Qt::ActionsContextMenu);
 
   le.connect(mAct, SIGNAL(triggered()), &w, SLOT(sw()));

Можно еще проще:
Код
C++ (Qt)
 le.addAction("qwe", &w, SLOT(sw()));
 le.addAction("asd");
 le.setContextMenuPolicy(Qt::ActionsContextMenu);
 

А динамическое меню можно реализовать путем перехвата сигнала нажатия на меню, запроса из базы нужных элементов. Построения нового меню и добавления его к нажатому итему с последующим разворачиванием программно. Связывания так же при создании выполняются. При скрытии меню, элементы можно уничтожить.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.234 секунд. Запросов: 23.