将参数传递给qt5c++中的槽
Passing arguments to a slot in qt5 c++
我正在c++ qt中创建一个ToDo列表应用程序。当一个加号按钮被按下时,它会添加一个包含QLabel和QToolButton的QHBoxLayout到我的gui中的垂直布局,所以我得到了带有'ToDos'的新框,以及在它们旁边删除它们的按钮。我已经在我的插槽内设置了各种小部件,当单击添加按钮时调用。但是,我需要将它们作为参数传递给插槽,当按下remove按钮时调用该插槽。我已经研究过了,所有我找到的是QSignalMapper。然而,我找不到任何足够接近我的案例来复制,我读过它只适用于某些参数,而不是我需要的三个(QHBoxLayout, QLineEdit和QToolButton)。当'add'按钮被按下时调用的插槽的一些代码如下:
//Creates a read only LineEdit which the user will add
QLineEdit *toDoBox = new QLineEdit(this);
toDoBox->setText(ui->lineEdit->text());
toDoBox->setReadOnly(true);
//Creates a new X button for removal of ToDo's
QToolButton *removeButton = new QToolButton;
removeButton->setText("X");
//Adds a horizontal layout with the ToDo and the remove button in it, to keep them together
QHBoxLayout *toDoLayout = new QHBoxLayout;
toDoLayout->addWidget(toDoBox);
toDoLayout->addWidget(removeButton);
//Removes a ToDo when the remove button is clicked
connect(removeButton, SIGNAL(clicked()), this, SLOT(on_removeButton_clicked()));
我的代码是托管在GitHub上,如果你想看到整个项目:https://github.com/DanWilkes02/ToDoList
谢谢你的耐心-我很难解释的事情是如此清楚在我的头脑!
如果我理解你的问题,你想要得到分配的对象,代表一个todo为了释放它们和更新你的视图。
你可以通过简单地包装你的QLineEdit, QToolButton和QHBoxLayout对象到一个类中,并在你的ToDoList类中使用一个容器(例如一个向量)来实现这一点。这样,每次你按下on_toolButton_clicked方法时,你都会把你的"todo object"推回去。
然后,你只需要使用一个带有索引的信号触发on_delete_todo插槽,从你的向量中删除一个"todo对象"并更新视图。
另外,看看这个Qt模型视图编程
下面是一个示例(在QT5下测试和工作):
您的Todo小部件
#ifndef TODOVIEW_H
#define TODOVIEW_H
#include <QString>
class QLineEdit;
class QToolButton;
class QHBoxLayout;
#include <QWidget>
class TodoView : public QWidget
{
Q_OBJECT
private:
QLineEdit* frame;
QToolButton* removeButton;
QHBoxLayout* toDoLayout;
int index;
public:
TodoView(const QString& what, int index, QWidget* parent);
~TodoView();
inline void setIndex(int i) { index = i; }
inline int getIndex(){ return index; }
private slots:
void emitIndex();
signals:
void selectedIndex(int);
};
#endif // TODOVIEW_H
#include "todoview.h"
#include <QLineEdit>
#include <QToolButton>
#include <QHBoxLayout>
TodoView::TodoView(const QString& what, int index, QWidget* parent) : QWidget(parent), index(index)
{
frame = new QLineEdit(this);
frame->setText(what);
frame->setReadOnly(true);
removeButton = new QToolButton(this);
removeButton->setText("X");
toDoLayout = new QHBoxLayout(this);
toDoLayout->addWidget(frame);
toDoLayout->addWidget(removeButton);
connect(removeButton, SIGNAL(clicked()), this, SLOT(emitIndex()));
}
TodoView::~TodoView() {}
void TodoView::emitIndex()
{
emit selectedIndex(getIndex());
}
你的主窗口
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vector>
class TodoView;
class QVBoxLayout;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void addTodo();
void delTodo(int);
private:
Ui::MainWindow* ui;
QVBoxLayout* vBoxLayout;
std::vector<TodoView*> todoView;
int max = -1;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "todoview.h"
#include <QVBoxLayout>
#include <QAction>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
vBoxLayout = new QVBoxLayout(centralWidget());
QAction* add = new QAction(ui->mainToolBar);
ui->mainToolBar->addAction(add);
connect(add, SIGNAL(triggered()), this, SLOT(addTodo()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::addTodo()
{
if(max > 9)
{
// Error msg.
}
else
{
TodoView* tdV = new TodoView("Yolo", max, centralWidget());
connect(tdV, SIGNAL(selectedIndex(int)), this, SLOT(delTodo(int)));
vBoxLayout->addWidget(tdV);
todoView.push_back(tdV);
++max;
}
}
void MainWindow::delTodo(int i)
{
// check if i < todoView.size().
delete todoView.at(i);
// update vector indexes !!!
--max;
}
我快速编辑了这段代码,我可能犯了几个错误,但你至少有一个解决方案的想法。
也可以为向量使用固定大小(更好的解决方案)。将TodoView已删除的对象设置为矢量中的nullptr,并在想要添加新的Todo视图组件时搜索nullptr:
在MainWindow构造函数中
todoView.reserve(10);
for(std::size_t i = 0; i < 10; ++i)
{
todoView[i] = nullptr;
}
addTodo槽
// Do not use push back.
// retrieve the max index.
// if < 10
for(std::size_t i = 0; i < todoView.size(); ++i)
{
if(todoView[i] == nullptr)
{
// allocate TodoView and affect it to the i° element
}
}
delTodo槽
delete todoView[i];
todoView[i] = nullptr;
使用一对向量也是可能的(一对int TodoView)。
我可以想到两种方法。
- 使用
QObject::sender()
. - 使用
QSignalMapper
QObject::sender()
这个静态方法返回发出信号的发送方对象的QObject *
。在这个例子中是QToolButton
,所以你可以使用这个引用来找到它的父节点(即QHBoxLayout
)和它的兄弟节点(即QLineEdit
)。
QSingalMapper
首先定义一个列表用于保存对所有行的引用,然后为每一行分配一个唯一的标识符(例如行号),然后根据官方文档的示例使用此标识符作为每个按钮的QSignalMapper
键。现在,如果用户单击一个按钮,在您的插槽中,您将获得相同的标识符,使用它并在行列表中查找整行。
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将成员函数指针作为参数传递给模板方法
- 如何在C++中将迭代器作为函数参数传递
- 将附加参数传递给使用 beast::bind_front_handler 调用的函数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 将参数传递为"const"的奇怪效果
- 如何在 c++ 中将函数作为参数传递?
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- 使用引用与指针将数组作为参数传递
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- 为什么我不能将引用作为 std::async 的函数参数传递
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 将__device__ lambda 作为参数传递给 __global__ 函数