【QT 5.9.3】no such slot错误解决办法

  • Post author:
  • Post category:其他


这种问题一般有下列几个地方出错:

1.在自己写的类中加入Q_OBJECT宏

2.槽函数没有写在”private/public slots:”里面

3.这种情况是我自己出的比较低级的错误,先上代码

MyDialog.h:

#pragma once

#include <QtWidgets/QDialog>
#include "ui_MyDialog.h"

class MyDialog : public QDialog
{
	Q_OBJECT

public:
	MyDialog(QWidget *parent = Q_NULLPTR);

private:
	Ui::MyDialogClass ui;
	QString _strDir;
private slots:
	void slotButtonClicked();
	void slotOpenFile();
};

MyDialog.cpp:

#include "MyDialog.h"
#include "qpushbutton.h"
#include "qevent.h"
#include "qdebug.h"
#include "qlayout.h"
#include "qfiledialog.h"
MyDialog::MyDialog(QWidget *parent)
	: QDialog(parent)
{
	ui.setupUi(this);

	QPushButton* button = new QPushButton("Another Button",this);
	connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked()));
	
}
void MyDialog::slotButtonClicked()
{
	QDialog* dlg = new QDialog();
	dlg->setWindowTitle("New Dialog");
	QHBoxLayout* hLayout = new QHBoxLayout(dlg);
	QPushButton* buttonOk = new QPushButton("OK");
	QPushButton* buttonExit = new QPushButton("EXIT");
	QPushButton* buttonOpenFile = new QPushButton("OPEN FILE");
	hLayout->addWidget(buttonOk);
	hLayout->addWidget(buttonExit);
	hLayout->addWidget(buttonOpenFile);
	//如果是通过exec来显示,可以通过accept或者reject的槽来关闭窗口
	//如果是show的话,可以通过close关闭窗口
	connect(buttonOk, SIGNAL(clicked()), dlg, SLOT(accept()));
	connect(buttonExit, SIGNAL(clicked()), dlg, SLOT(reject()));
	connect(buttonOpenFile, SIGNAL(clicked()), dlg,SLOT(slotOpenFile()));
	int ret=dlg->exec();
	if (ret == QDialog::Accepted)
	{
		qDebug() << "Accept";
	}
	else
	{
		qDebug() << "reject";
	}
}

void MyDialog::slotOpenFile()
{
	QFileDialog::getSaveFileName(NULL, "OPEN File", _strDir, "pic file(*.png *.jpg)");
}

问题出在slotButtonClicked函数里面的这句代码connect(buttonOpenFile, SIGNAL(clicked()), dlg,SLOT(slotOpenFile()));

点击按钮并没有事件产生,排除了前两种错误后,发现输出提示”no such slot QDialog::slotOpenFile()”,奇怪,这个函数我明明写在了MyDialog里面,程序为什么到QDialog里面去找它呢,原来我将dlg定义为了QDialog对象,也就是说这个新的对话框dlg是QDialog对象,那么此时进行信号和槽的连接,就要到QDialog里面去找,当然是找不到自己写的这个函数了。

解决方法很简单:要么自己再写一个类,要么将dlg声明为MyDialog对象即可

希望对各位读者有帮助!