mint mint - 3 months ago 33
C++ Question

C++ Qt setting up signal and slots for QMenu

I am trying to make a make a program that allows a user to right click a cell in a gridView and choose from a menu of actions.

I have the menu display, but am having trouble getting the signal and slot to work without getting errors. I am working in Qt 5.5 C++11, not very advanced with Qt or C++ yet so any help would be greatly appreciated

using namespace std;
QStandardItemModel* model;
QStandardItem *value;

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
model = new QStandardItemModel(9,9,this);

ui->tableView->setModel(model);
ui->tableView->setShowGrid(true);
ui->tableView->setWordWrap(true);
//to allow menu
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);

for(int row = 0; row < 9; row++){
ui->tableView->setRowHeight(row, 75);
for(int col = 0; col < 9; col++){
ui->tableView->setColumnWidth(col, 75);
QFont f("Consolas");

f.setPointSize(10);
value = new QStandardItem(QString("1 2 3\n4 5 6\n7 8 9"));


if ((row < 3 && col < 3) || (row > 5 && col < 3)
|| (row < 3 && col > 5) || (row > 5 && col > 5)
|| ((row > 2 && row < 6) && (col > 2 && col < 6))){
QBrush b(QColor("Moccasin"));
value->setBackground(b);
}

value->setFont(f);
value->setTextAlignment(Qt::AlignCenter);
model->setItem(row,col,value);
}
}

//connects model so functions run when a cell's text is changed
connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(on_cell_changed(QStandardItem*)));
//this sets up the menu
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(menuRequest(QPoint)));

}


this is the main window part of the program. It is (going to be) a sudoku solver, so the model represents the 9x9 grid and the for loop is populating the grid with choices for input (but that's not the thing I'm having trouble with). I need help with the menu part below (the above was just for context):

void MainWindow::menuRequest(QPoint pos)
{
QModelIndex index = ui->tableView->indexAt(pos);
std::cout << "MainWindow::menuRequest - at" << " QModelIndex row = " <<
index.row() << ", column = " << index.column() << std::endl;
QMenu menu(this);

QMenu setValues("Initialize Grid", this);
QAction *setValue1;
QAction *setValue2;
QAction *setValue3;
QAction *setValue4;
QAction *setValue5;
QAction *setValue6;
QAction *setValue7;
QAction *setValue8;
QAction *setValue9;
setValue1 = setValues.addAction("Set value to 1");
setValue2 = setValues.addAction("Set value to 2");
setValue3 = setValues.addAction("Set value to 3");
setValue4 = setValues.addAction("Set value to 4");
setValue5 = setValues.addAction("Set value to 5");
setValue6 = setValues.addAction("Set value to 6");
setValue7 = setValues.addAction("Set value to 7");
setValue8 = setValues.addAction("Set value to 8");
setValue9 = setValues.addAction("Set value to 9");

connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(on_menu_clicked(QAction*)));

menu.addMenu(&setValues);
QAction *action = menu.exec(
ui->tableView->viewport()->mapToGlobal(pos));

}

void MainWindow::on_menu_clicked(QAction*){
cout << "test menu click worked";
}


The connect statement in the MenuRequest function is throwing an error:

connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(on_menu_clicked(QAction*)));


C2664: 'QMetaObject::Connection QObject::connect(const QObject *, const char *, const char *, Qt::ConnectionType)const' : cannot convert argument 1 from 'QMenu' to 'const QObject *'

When it is supposed to go to the on_menu_click function it throws the above error

I know that means that menu isn't of the QObject type but I'm not sure how to fix this. Any help would be greatly appreciated

Answer

As stated in the comment your first argument in the connect() function needs to be a pointer. The documentation States the following:

connect(const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection)

http://doc.qt.io/qt-5/qobject.html#connect

Comments