我想知道当我右键单击表项时如何打开弹出菜单。在弹出菜单中,应该给出一些添加和删除等操作,这将创建一个新行或删除所选行。
我是Qt世界的新手,所以如果有人能够给我详细信息(如果可能的话还有代码),那么我将非常感激他/她。
谢谢。
我的目标:仅在QListWidget
区域内,只有点击某个项目时,才会打开包含删除的菜单。
修改:好的我用QListWidget
和菜单解决了问题。现在必须完成以下任务:
如果使用鼠标右键单击某个项目,然后单击“删除”,则该项目将被删除。
我的代码:
void ProvideContextMenu(const QPoint &); // MainWindow.h
// In MainWindow.cpp
ui->listFiles->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->listFiles, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(ProvideContextMenu(const QPoint &)));
void MainWindow::ProvideContextMenu(const QPoint &pos)
{
QPoint item = ui->listFiles->mapToGlobal(pos);
QMenu submenu;
submenu.addAction("ADD");
submenu.addAction("Delete");
QAction* rightClickItem = submenu.exec(item);
if (rightClickItem && rightClickItem->text().contains("Delete") )
{
ui->listFiles->takeItem(ui->listFiles->indexAt(pos).row());
}
}
Edit2 :好的,我解决了整个问题:D。我上传了我的代码,如果有人需要这样的东西可以帮助他/她。
答案 0 :(得分:19)
首先,您需要创建用于打开上下文菜单的插槽:
void showContextMenu(const QPoint&);
在您的类的构造函数中,使用QListWidget
,set context menu policy自定义并连接QListWidget::customContextMenuRequested(QPoint)
信号和showContextMenu()
插槽,如下所示:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
}
然后需要实现上下文菜单打开:
void MainWindow::showContextMenu(const QPoint &pos)
{
// Handle global position
QPoint globalPos = listWidget->mapToGlobal(pos);
// Create menu and insert some actions
QMenu myMenu;
myMenu.addAction("Insert", this, SLOT(addItem()));
myMenu.addAction("Erase", this, SLOT(eraseItem()));
// Show context menu at handling position
myMenu.exec(globalPos);
}
在此之后,我们需要实现添加和删除QListWidget
元素的插槽:
void MainWindow::eraseItem()
{
// If multiple selection is on, we need to erase all selected items
for (int i = 0; i < listWidget->selectedItems().size(); ++i) {
// Get curent item on selected row
QListWidgetItem *item = listWidget->takeItem(listWidget->currentRow());
// And remove it
delete item;
}
}
正如您所看到的,我们迭代所有选定的项目(对于设置多选模式使用setSelectionMode()
方法)并自行删除它,因为docs表示
从列表小部件中删除的项目将不会由Qt管理,并且将会 需要手动删除。
添加一些项目更容易,我的不同项目标题的静态变量解决方案如下:
void MainWindow::addItem()
{
static int i = 0;
listWidget->addItem(QString::number(++i));
}
为简化代码,请使用Qt5 sytax作为信号和插槽。它消除了创建中间插槽的需要。
我希望对你有所帮助。
答案 1 :(得分:0)
它比公认的答案简单得多。您不需要处理创建上下文菜单或光标位置或任何这些。使用 Qt::CustomContextMenu
而不是 Qt::ActionsContextMenu
,只需将您的操作直接添加到小部件:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui->setupUi(this);
// you can create the actions here, or in designer
auto actInsert = new QAction("Insert", this);
auto actDelete = new QAction("Delete", this);
// you can set up slot connections here or in designer
connect(actInsert, SIGNAL(triggered()), this, SLOT(addItem()));
connect(actDelete, SIGNAL(triggered()), this, SLOT(eraseItem()));
// and this will take care of everything else:
listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
listWidget->addActions({ actInsert, actDelete });
}
void MainWindow::addItem () {
...; // add an item
}
void MainWindow::eraseItem () {
...; // erase an item
}
除了 addActions
(我认为)之外的所有内容都可以在 Designer 中完成。
或者,如果您出于任何原因不想添加实际的槽函数,您也可以在连接时在 lambda 中执行所有操作:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui->setupUi(this);
// you can create the actions here, or in designer
auto actInsert = new QAction("Insert", this);
auto actDelete = new QAction("Delete", this);
connect(actInsert, &QAction::triggered, [=]() {
...; // add an item
});
connect(actDelete, &QAction::triggered, [=]() {
...; // erase an item
});
// and this will take care of everything else:
listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
listWidget->addActions({ actInsert, actDelete });
}
信号/槽选项更有条理和灵活,但 lambda 选项适用于高度专业化的简短代码位(或绑定到非槽函数)。
这适用于任何小部件上的上下文菜单。此外,同一个 QAction
可用于多个小部件。