Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/41: Рейтинг темы: голосов - 41, средняя оценка - 4.93
 Аватар для alexey31415
60 / 60 / 7
Регистрация: 16.05.2010
Сообщений: 632

Создание контекстного меню

04.05.2014, 16:37. Показов 8086. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую.

У меня есть виджет дерева и я хочу, чтобы при клике ПКМ по корневому узлу появлялось одно контекстное меню, а при клике по дочерним узлам другое.

На рисунке показан лишь корневой узел(ProjectName), при клике по которому должно показываться m_RootItemContextMenu, а при клике его дочерних узлов меню m_SolutionItemContextMenu.

обработчик customContextMenuRequested
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void ProjectTree::CreateContextMenu(QPoint pos){
    m_SelectedItem = m_ProjectTree->itemAt(pos);
 
    if(m_SelectedItem == m_ProjectTree->headerItem()){
        CreateMenuForRootItem(pos);
    } else{
        CreateMenuForSolutionItem(pos);
    }
}
 
void ProjectTree::CreateMenuForRootItem(QPoint &pos){
    m_RootItemContextMenu = new QMenu(m_ProjectTree);
    m_RootItemContextMenu->addAction(m_SetProjNameAct);
 
    m_RootItemContextMenu->exec(m_ProjectTree->mapToGlobal(pos));
}
 
void ProjectTree::CreateMenuForSolutionItem(QPoint &pos){
    m_SolutionItemContextMenu = new QMenu(m_ProjectTree);
 
    m_SolutionItemContextMenu->addAction(m_AddNewSolAct);
    m_SolutionItemContextMenu->addAction(m_SetSolNameAct);
    m_SolutionItemContextMenu->addAction(m_RemoveSolAct);
 
    m_SolutionItemContextMenu->exec(m_ProjectTree->mapToGlobal(pos));
}


Заодно такой вопрос, есть какая-то возможность добавить верхнюю таблицу и кнопки справа в панель или иначе сделать рамку вокруг этих виджетов, чтобы визуально выделить их.
Миниатюры
Создание контекстного меню  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.05.2014, 16:37
Ответы с готовыми решениями:

Создание контекстного меню
Подскажите как можно реализовать контекстное меню с боковым изображением. К примеру, как указано на рисунке во вложении.

Создание дополнительного пункта контекстного меню
Собственно, сабж такой: в контекстное меню нужно добавить пункт "Размер файла". То есть я навожу на файл, кликаю правой кнопкой мыши и...

Создание контекстного меню для TableView (QT)
Всем доброго времени суток. На форме располагается таблица с заголовками(шапка) и записями. Для этой таблицы(TableView), нужно создать...

7
 Аватар для alexey31415
60 / 60 / 7
Регистрация: 16.05.2010
Сообщений: 632
04.05.2014, 17:07  [ТС]
Ещё такой вопрос: почему не показываются всплывающие подсказки при наведении на пункты меню, ведь я добавлял для каждого действия.

Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// пункты меню при клике по корневому узлу
    m_SetProjNameAct    = new QAction(tr("Change project name"), m_ProjectTree);
    m_SetProjNameAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
    m_SetProjNameAct->setStatusTip(tr("Только цифры и буквы!"));
    connect(m_SetProjNameAct, SIGNAL(triggered()),
            SLOT(SetProjectName()));
 
    // пункты меню при клике по узлам с именами решений
    m_AddNewSolAct  = new QAction(tr("Add solution"), m_ProjectTree);
    m_AddNewSolAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T));
    m_AddNewSolAct->setToolTip(tr("Создаёт решение с данными по умолчанию"));
    connect(m_AddNewSolAct, SIGNAL(triggered()),
            SLOT(AddNewSolution()));
 
    m_SetSolNameAct = new QAction(tr("Change solution name"), m_ProjectTree);
    m_SetSolNameAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
    m_SetSolNameAct->setToolTip(tr("Only characters or digits!"));
    connect(m_SetSolNameAct, SIGNAL(triggered()),
            SLOT(SetSolutionName()));
 
    m_RemoveSolAct  = new QAction(tr("Remove solution"), m_ProjectTree);
    m_RemoveSolAct->setShortcut((QKeySequence(Qt::CTRL + Qt::Key_U)));
    m_RemoveSolAct->setToolTip(tr("Безвозвратно удаляет решение!"));   // @TODO: добавить возможность отмены действий
    connect(m_RemoveSolAct, SIGNAL(triggered()),
            SLOT(RemoveSolution()));


Добавлено через 14 минут
также не срабатывают хоткеи для команд меню, возможно стоит вызывать для каждого действия что-то вроде SetEnable(true)?
0
 Аватар для RazrFalcon
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
04.05.2014, 17:32
1) Нужно виджету задать флаг:
C++ (Qt)
1
setContextMenuPolicy(Qt::CustomContextMenu);
2) QMenu не нужно создавать через new,. тем более каждый раз. Это же утечка памяти в чистом виде.
3) У QAction/QMenu нет тултипов, пусть есть и функция такая. Вы когда-либо видели что бы у меню был тултип?
4) Хоткеи обычно задают через setShortcut(tr("Ctrl+F"));
0
 Аватар для alexey31415
60 / 60 / 7
Регистрация: 16.05.2010
Сообщений: 632
04.05.2014, 17:43  [ТС]
Цитата Сообщение от RazrFalcon Посмотреть сообщение
setContextMenuPolicy(Qt::CustomContextMe nu);
задан.
Я решил проблему, класс хранит указатель на дочерний узел, в слоте идёт сравнение с этим узлом, если совпал, то показывается меню для родительского узла.

Цитата Сообщение от RazrFalcon Посмотреть сообщение
2) QMenu не нужно создавать через new,. тем более каждый раз. Это же утечка памяти в чистом виде.
Но если я буду добавлять в слоте каждый раз действие, то у меня будет постоянно увеличиваться кол-во пунктов меню.

Цитата Сообщение от RazrFalcon Посмотреть сообщение
4) Хоткеи обычно задают через setShortcut(tr("Ctrl+F"));
буду знать, хотя мне нравится подход .который я использую сейчас.
Но всё равно непонятно, почему не работают быстрые клавиши.
0
 Аватар для RazrFalcon
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
04.05.2014, 18:02
Цитата Сообщение от alexey31415 Посмотреть сообщение
Но если я буду добавлять в слоте каждый раз действие, то у меня будет постоянно увеличиваться кол-во пунктов меню.
QMenu создавайте прямо в слоте, но не через new.

Цитата Сообщение от alexey31415 Посмотреть сообщение
Но всё равно непонятно, почему не работают быстрые клавиши.
Хз, какой-то баг.
0
 Аватар для alexey31415
60 / 60 / 7
Регистрация: 16.05.2010
Сообщений: 632
04.05.2014, 18:10  [ТС]
Цитата Сообщение от RazrFalcon Посмотреть сообщение
QMenu создавайте прямо в слоте, но не через new.
Создаю в конструкторе, в слоте добавляю действия.

Можете помочь с этим. Как я представляю есть виджет Frame, к нему я добавляю разметку с таблицей и кнопками и потом указываю стиль фрейма.


Цитата Сообщение от alexey31415 Посмотреть сообщение
есть какая-то возможность добавить верхнюю таблицу и кнопки справа в панель или иначе сделать рамку вокруг этих виджетов, чтобы визуально выделить их.
Добавлено через 1 минуту
Цитата Сообщение от RazrFalcon Посмотреть сообщение
Хз, какой-то баг.
Мне кажется я просто где-то ошибся или не добавил что-то.
0
 Аватар для RazrFalcon
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
04.05.2014, 18:27
Цитата Сообщение от alexey31415 Посмотреть сообщение
есть какая-то возможность добавить верхнюю таблицу и кнопки справа в панель или иначе сделать рамку вокруг этих виджетов, чтобы визуально выделить их.
QGroupBox?
1
 Аватар для alexey31415
60 / 60 / 7
Регистрация: 16.05.2010
Сообщений: 632
04.05.2014, 19:43  [ТС]
Цитата Сообщение от RazrFalcon Посмотреть сообщение
QGroupBox?
Попробую.

Добавлено через 7 минут
По поводу хоткеев: возможно я передаю в качестве родительского виджета не тот, что надо?

.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class ProjectTree : public QWidget{
    Q_OBJECT
public:
    ProjectTree(QWidget* pwgt /*= 0*//*, QHBoxLayout* layout*/);
 
    QTreeWidget*        GetParentWidget();
 
private slots:
    bool                SetProjectName();
 
    bool                AddNewSolution();
    bool                SetSolutionName();
    bool                RemoveSolution();
 
    void                CreateContextMenu(QPoint pos);
    void                SetCurrentSolution(QTreeWidgetItem*, int);
 
private:
    QTreeWidget*        m_ProjectTree;
 
    QTreeWidgetItem*    m_RootItem;
    QTreeWidgetItem*    m_SelectedItem;
 
    QMenu*              m_RootItemContextMenu;
    QMenu*              m_SolutionItemContextMenu;
 
    QAction*            m_SetProjNameAct;
    QAction*            m_AddNewSolAct;
    QAction*            m_SetSolNameAct;
    QAction*            m_RemoveSolAct;
 
    int                 m_Width;
    int                 m_Height;
 
    void                CreateMenuForRootItem(QPoint& pos);
    void                CreateMenuForSolutionItem(QPoint& pos);
};
 
#endif  /*PROJECTTREE_H*/


.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
ProjectTree::ProjectTree(QWidget *pwgt = 0/*, QHBoxLayout *layout*/) :
    QWidget(pwgt),
    m_Width(120),
    m_Height(800)
{
    m_ProjectTree   = new QTreeWidget(pwgt);
    m_ProjectTree->setHeaderLabel(tr("Project tree"));
    m_ProjectTree->setColumnCount(1);
 
    // корневой узел дерева, содержит имя проекта
    m_RootItem      = new QTreeWidgetItem(m_ProjectTree);
    m_RootItem->setText(0, SolutionManager::GetInstance()->GetProjectName());
 
    // используется собственное контекстное меню
    m_ProjectTree->setContextMenuPolicy(Qt::CustomContextMenu);
 
    m_RootItemContextMenu = new QMenu(this);
 
    connect(m_ProjectTree, SIGNAL(customContextMenuRequested(QPoint)),
            SLOT(CreateContextMenu(QPoint)));
 
    connect(m_ProjectTree, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
            SLOT(SetCurrentSolution(QTreeWidgetItem*, int)));
 
    m_ProjectTree->setMaximumSize(m_Width, m_Height);
    m_SolutionItemContextMenu = new QMenu(m_ProjectTree);
 
    QKeySequence shortcut = QKeySequence(Qt::CTRL + Qt::Key_R);
 
    // пункты меню при клике по корневому узлу
    m_SetProjNameAct    = new QAction(tr("Change project name"), m_ProjectTree);
    m_SetProjNameAct->setShortcut(shortcut);
    connect(m_SetProjNameAct, SIGNAL(triggered()),
            SLOT(SetProjectName()));
 
    // пункты меню при клике по узлам с именами решений
    m_AddNewSolAct  = new QAction(tr("Add solution"), m_ProjectTree);
    shortcut        = QKeySequence(Qt::CTRL + Qt::Key_T);
    m_AddNewSolAct->setShortcut(shortcut);
    connect(m_AddNewSolAct, SIGNAL(triggered()),
            SLOT(AddNewSolution()));
 
    m_SetSolNameAct = new QAction(tr("Change solution name"), m_ProjectTree);
    shortcut        = QKeySequence(Qt::CTRL + Qt::Key_Y);
    m_SetSolNameAct->setShortcut(shortcut);
    connect(m_SetSolNameAct, SIGNAL(triggered()),
            SLOT(SetSolutionName()));
 
    m_RemoveSolAct  = new QAction(tr("Remove solution"), m_ProjectTree);
    shortcut        = QKeySequence(Qt::CTRL + Qt::Key_U);
    m_RemoveSolAct->setShortcut(shortcut);
    connect(m_RemoveSolAct, SIGNAL(triggered()),
            SLOT(RemoveSolution()));
}


Добавлено через 1 час 5 минут
Контекстное меню появляется при клике по дереву в любой его области, а можно сделать так, чтобы меню появлялось лишь при клике по одному из его узлов?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.05.2014, 19:43
Помогаю со студенческими работами здесь

Создание контекстного меню для элементов дерева
Доброго времени суток. Мне нужно сделать виджет дерева, в котором по клику ПКМ по верхнему узлу появлялось контекстное меню, а при клике...

Создание контекстного меню для собственного виджета
Здравствуйте. Помогите советом. Имеется графический интерфейс программы (ниже на картиночке). Мне необходимо осуществить реализацию выбора...

Открытие контекстного меню
у меня есть контекстное меню void CameraView::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; ...

Вызов контекстного меню по правому клику
Добрый день, нашел простую статейку как это сделать- http://www.setnode.com/blog/right-click-context-menus-with-qt/ Но данный прием не...

Кастомизация стандартного контекстного меню QTextEdit
Столкнулся с необходимостью использования модифицированного контекстного меню для QTextEdit. Создал свой класс, в котором переопределил...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru