QT:没有这样的插槽
问题是,每次从主窗口启动“设置”窗口时,我都会在 Qt Creator 中收到“No Such Slot”运行时错误。到目前为止,我发现 Qt 相当违反直觉,而且这种 slot 'n 信号概念似乎与简单地传递变量或函数调用有些牵强。基本上,我有一个带有设置选项的菜单,单击该选项时,会打开一个设置窗口,该窗口需要从用户那里获取双精度值并更新主窗口中的变量。
SettingsWindow.h
class SettingsWindow : public QWidget
{
Q_OBJECT
public:
SettingsWindow(QWidget *parent = 0);
signals:
void ValChanged(double newVal);
public slots:
void Accept();
private:
QLineEdit *le1;
};
设置窗口有一个接受按钮,它调用 Accept(),后者发出 ValChanged 信号,并将 newVal 设置为 le1 中的用户输入作为双精度值。
SettingsWindow.cpp
void SettingsWindow::Accept(){
emit ValChanged(le1->text().toDouble());
this->close();
}
该设置窗口由应用程序的主窗口调用: MainWindow
MainWindow.cpp
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
public slots:
void SetVal(double x);
private slots:
void NewWindow();
private:
double theVal;
};
该主窗口有一个菜单,可从中选择设置。这将创建一个新窗口,其中包含一个供用户输入数字的字段。
MainWindow.cpp
void MainWindow::NewWindow()
{
SettingsWindow *MySettings=new SettingsWindow(this);
QObject::connect(MySettings, SIGNAL(ValChanged(double)), this, SLOT(SetVal(double)));
MySettings->show();
MySettings->raise();
}
void MainWindow::SetVal(double x){
theVal = x;
}
我希望当设置窗口打开时,用户可以在字段中输入 val,然后发出 ValChanged 信号,将 theVal 设置为用户指定的值。大多数时候,我看到人们不包含 Q_OBJECT 宏的问题,但我两次都包含了它。关于为什么这不起作用的任何建议?
Problem is that I keep getting the 'No Such Slot' runtime error in Qt Creator every time I launch a 'settings' window from my main window. I've found Qt to be quite counter-intuitive so far and this slots 'n signals concept seems a bit of a stretch from simply passing vars or function calls. Basically, I have menu with a settings option, that when clicked, opens a settings window which needs to grab a double from the user and update a var in the main window.
SettingsWindow.h
class SettingsWindow : public QWidget
{
Q_OBJECT
public:
SettingsWindow(QWidget *parent = 0);
signals:
void ValChanged(double newVal);
public slots:
void Accept();
private:
QLineEdit *le1;
};
The settings window has an accept button which calls Accept() which emits the ValChanged signal with newVal set as the user input in le1 as a double.
SettingsWindow.cpp
void SettingsWindow::Accept(){
emit ValChanged(le1->text().toDouble());
this->close();
}
This settings window is called by the application's main window: MainWindow
MainWindow.cpp
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
public slots:
void SetVal(double x);
private slots:
void NewWindow();
private:
double theVal;
};
This main window has a menu which one would select settings from. This creates a new window with a field for one to enter a number.
MainWindow.cpp
void MainWindow::NewWindow()
{
SettingsWindow *MySettings=new SettingsWindow(this);
QObject::connect(MySettings, SIGNAL(ValChanged(double)), this, SLOT(SetVal(double)));
MySettings->show();
MySettings->raise();
}
void MainWindow::SetVal(double x){
theVal = x;
}
My hope is that when the settings window is opened, the user can enter a val into the field which then emits the ValChanged Signal which sets theVal to the value specified by the user. Most of the time I saw an issue with people not including Q_OBJECT macro, but I've included it both times. Any suggestions on why this doesn't work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对我来说,在我的槽函数上方添加一个
public Q_SLOTS:
是我所缺少的。 (我已经有了 Q_OBJECT 等)For me, adding a
public Q_SLOTS:
above my slot function was what I was missing. (I already had Q_OBJECT, etc.)您遇到的问题几乎肯定是由于未重新创建 moc 文件、连接调用中的拼写错误或相关插槽的声明中的拼写错误造成的。
您可能需要考虑到,这比从对话框获取输入所需的工作量要多得多。一种更简单的方法是将“接受”按钮单击信号连接到主窗口中的插槽,然后通过
getXXX()
方法直接从设置窗口的实例中获取所需的值。如果您最终有一个包含大量值的设置对话框,则不要通过 getter 获取每个值,而是让“接受”按钮信号返回一个结构,其中所有值都作为该结构的字段。
我应该提到的是,每次调用
NewWindow()
时都会创建一个SettingsWindow
的新实例。所有这些实例都将持续存在,直到 MainWindow 被销毁。The issue you are having is almost certainly due to a moc file not being recreated, a typo in your call to connect or a typo in the declaration of the slot in question.
You may want to consider that this is a lot more work than necessary for getting input from a dialog. A simpler method would be to connect the "Accept" button clicked signal to a slot in main window and then fetch the value you want directly from the instance of the settings window through a
getXXX()
method.If you eventually have a settings dialog with a lot of values, instead of fetching each value through getters, have the "Accept" button signal return a structure with all the values as fields of that structure.
I should mention that it looks like
NewWindow()
creates a new instance ofSettingsWindow
each time it is called. All of these instances will persist until theMainWindow
is destroyed.当我在命令行上手动重新创建 moc 文件时,我解决了问题。
我使用了 qt 命令提示符选项,因此所有路径都已设置:
我的代码没有任何问题,并且我的 makefile 没有任何我可以看到的 moc 命令。这适用于我尝试过的所有示例。我希望有人也可以尝试这个。我试验了近85个小时才找到原因。
对于 codeblocks 用户,请尝试重新创建精确的 moc 文件。
-o myheaderfile.cpp
选项是将 moc 输出保存到文件中。在文件上运行 moc 实际上会将所有内容都显示到控制台窗口上。
I solved my problem when I manually recreated my moc file on the command line.
I used qt command prompt option so all the paths had been set:
There was nothing wrong with my code, and my makefile didn't have any moc command I could see. This works for all my examples I have tried. I hope someone might try this too. I experimented for almost 85 hours before I could find the cause.
For codeblocks users, try recreating your moc files to be precise.
the
-o myheaderfile.cpp
option is to save the moc output to a file.Running moc on the file actually spews everything onto the console window.
我错误地尝试在没有
QSignalMapper
的情况下将参数传递到我的插槽,这是我从 这篇 SO 帖子。删除槽函数(.h 和 .cpp)的所有参数可以找到并调用回调。
是的,我是 Qt n00b。是时候用 QSignalMapper 重构了:)
HTH
I was incorrectly trying to pass a parameter to my slot without a
QSignalMapper
, which I learned from this SO post.Removing all parameters to the slot function (.h and .cpp) allowed the callback to be found and called.
Yes, I'm a Qt n00b. Time to refactor with QSignalMapper :)
HTH