将 QAction 连接到插槽
connect QAction to slot
我正在尝试理解为什么 QObject::connect 有时可以,有时却不能。
我很乐意提供任何帮助,我已经做了很多 google/Documentation 阅读/并寻找问题的可能重复项,重复项没有解决我的问题
我有 2 个非常相似的 Qt 项目代码,几个小时后我试图弄清楚为什么它不起作用。
工作测试项目:
toolbar.h
#ifndef TOOLBAR_H
#define TOOLBAR_H
#include <QMainWindow>
#include <QApplication>
class Toolbar : public QMainWindow
{
Q_OBJECT
public:
Toolbar(QWidget *parent = 0);
public slots:
void dosmt();
signals:
void test();
void test2();
private:
static bool button1;
};
#endif // TOOLBAR_H
toolbar.cpp
#include "toolbar.h"
#include <QToolBar>
#include <QIcon>
#include <QAction>
#include <QLabel>
#include <iostream>
bool Toolbar::button1=false;
Toolbar::Toolbar(QWidget *parent): QMainWindow(parent)
{
QString path="../res/login_photo.png";
QPixmap newpix(path);
QPixmap openpix("../res/global.png");
QPixmap quitpix("new.png");
QToolBar *toolbar = addToolBar("main toolbar");
QAction *hallo=toolbar->addAction(QIcon(newpix), "1");
toolbar->addAction(QIcon(openpix), "Open File");
toolbar->addSeparator();
QAction *quit = toolbar->addAction(QIcon(quitpix),
"Quit Application");
connect(hallo,SIGNAL(triggered()),this,SLOT(dosmt()));
connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
}
void Toolbar::dosmt()
{
button1=!button1;
if(button1){
emit test();
}else{
emit test2();
}
}
现在我想改进布局,以便我可以放入我可能需要的所有元素,所以我创建了一个新项目,如果我评论了不工作的连接信号槽线,它就可以工作。工具栏基本上只是重命名为 mainwindow
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QApplication>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void dosmt();
void h1();
signals:
void s1();
};
mainwindow.cpp
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QToolBar>
#include <QApplication>
#include <QObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QPixmap newpix("../res/login_photo.png");
QPixmap openpix("../res/global.png");
QPixmap quitpix("new.png");
QToolBar *toolbar = new QToolBar;
QAction* hallo=toolbar->addAction(QIcon(newpix), "Page1");
toolbar->addAction(QIcon(openpix), "Open File");
QAction *quit = toolbar->addAction(QIcon(quitpix),"Quit Application");
下面是我的问题错误消息
connect(hallo,SIGNAL(triggered()),this,SLOT(h1()));
没问题时:
connect(this,SIGNAL(s1()),this,SLOT(h1()));
休息:
QVBoxLayout * mvbox = new QVBoxLayout;
mvbox->addWidget(toolbar);
setCentralWidget(new QWidget);
centralWidget()->setLayout(mvbox);
}
void MainWindow::dosmt()
{
qDebug("happ");
}
void MainWindow::h1()
{
qDebug("happ");
}
MainWindow::~MainWindow()
{
}
错误(Fehler)消息:
/cpp/qt/GUItest1/mainwindow.cpp:19:
Fehler: no matching function for call to 'MainWindow::connect(QAction*&, const char*, MainWindow* const, const char*)'
connect(hallo,SIGNAL(triggered()),this,SLOT(h1()));
followed by a bunch of not helping stuff i just took the ones that look remotly usefull
Qt/5.4/gcc_64/include/QtCore/qobject.h:213: Fehler:
no type named'Object' in 'struct QtPrivate::FunctionPointer<const char*>'
^
/Qt/5.4/gcc_64/include/QtCore/qobject.h:254: Fehler: invalid use of incomplete type 'struct QtPrivate::QEnableIf<false, QMetaObject::Connection>'
/Qt/5.4/gcc_64/include/QtCore/qglobal.h:1056: Fehler: declaration of 'struct QtPrivate::QEnableIf<false, QMetaObject::Connection>'
template <bool B, typename T = void> struct QEnableIf;
^
/Qt/5.4/gcc_64/include/QtCore/qobject.h:293:
Fehler: no type named 'Object' in 'struct QtPrivate::FunctionPointer<const char*>'
通过尝试,我发现问题出在信号 QAction 中,因为来自 Mainwindow 的信号可以连接到来自 mainwindow 的插槽
项目一和项目二的唯一区别似乎是工具栏的添加方式
addToolBar
对比
QToolBar *toolbar = new QToolBar; and
mvbox->addWidget(toolbar);
您忘记在 mainwindow.cpp 中包含 QAction header。
#include <QAction>
它应该可以正确编译您的程序。
为什么不使用 SLOTS
?
toolbar = addToolBar("main toolbar");
toolbar->addAction("Open", this, SLOT(open_file()) );
toolbar->addAction("New", this, SLOT(new_file());
toolbar->addAction("Quit", this, SLOT(quit_application());
同时在 header
:
[...]
public slots:
void open_file();
void new_file();
void quit_application();
[...]
SLOTS 是 QT 最佳实践,你应该使用它们。
我正在尝试理解为什么 QObject::connect 有时可以,有时却不能。
我很乐意提供任何帮助,我已经做了很多 google/Documentation 阅读/并寻找问题的可能重复项,重复项没有解决我的问题
我有 2 个非常相似的 Qt 项目代码,几个小时后我试图弄清楚为什么它不起作用。
工作测试项目:
toolbar.h
#ifndef TOOLBAR_H
#define TOOLBAR_H
#include <QMainWindow>
#include <QApplication>
class Toolbar : public QMainWindow
{
Q_OBJECT
public:
Toolbar(QWidget *parent = 0);
public slots:
void dosmt();
signals:
void test();
void test2();
private:
static bool button1;
};
#endif // TOOLBAR_H
toolbar.cpp
#include "toolbar.h"
#include <QToolBar>
#include <QIcon>
#include <QAction>
#include <QLabel>
#include <iostream>
bool Toolbar::button1=false;
Toolbar::Toolbar(QWidget *parent): QMainWindow(parent)
{
QString path="../res/login_photo.png";
QPixmap newpix(path);
QPixmap openpix("../res/global.png");
QPixmap quitpix("new.png");
QToolBar *toolbar = addToolBar("main toolbar");
QAction *hallo=toolbar->addAction(QIcon(newpix), "1");
toolbar->addAction(QIcon(openpix), "Open File");
toolbar->addSeparator();
QAction *quit = toolbar->addAction(QIcon(quitpix),
"Quit Application");
connect(hallo,SIGNAL(triggered()),this,SLOT(dosmt()));
connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
}
void Toolbar::dosmt()
{
button1=!button1;
if(button1){
emit test();
}else{
emit test2();
}
}
现在我想改进布局,以便我可以放入我可能需要的所有元素,所以我创建了一个新项目,如果我评论了不工作的连接信号槽线,它就可以工作。工具栏基本上只是重命名为 mainwindow
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QApplication>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void dosmt();
void h1();
signals:
void s1();
};
mainwindow.cpp
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QToolBar>
#include <QApplication>
#include <QObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QPixmap newpix("../res/login_photo.png");
QPixmap openpix("../res/global.png");
QPixmap quitpix("new.png");
QToolBar *toolbar = new QToolBar;
QAction* hallo=toolbar->addAction(QIcon(newpix), "Page1");
toolbar->addAction(QIcon(openpix), "Open File");
QAction *quit = toolbar->addAction(QIcon(quitpix),"Quit Application");
下面是我的问题错误消息
connect(hallo,SIGNAL(triggered()),this,SLOT(h1()));
没问题时:
connect(this,SIGNAL(s1()),this,SLOT(h1()));
休息:
QVBoxLayout * mvbox = new QVBoxLayout;
mvbox->addWidget(toolbar);
setCentralWidget(new QWidget);
centralWidget()->setLayout(mvbox);
}
void MainWindow::dosmt()
{
qDebug("happ");
}
void MainWindow::h1()
{
qDebug("happ");
}
MainWindow::~MainWindow()
{
}
错误(Fehler)消息:
/cpp/qt/GUItest1/mainwindow.cpp:19:
Fehler: no matching function for call to 'MainWindow::connect(QAction*&, const char*, MainWindow* const, const char*)'
connect(hallo,SIGNAL(triggered()),this,SLOT(h1()));
followed by a bunch of not helping stuff i just took the ones that look remotly usefull
Qt/5.4/gcc_64/include/QtCore/qobject.h:213: Fehler:
no type named'Object' in 'struct QtPrivate::FunctionPointer<const char*>'
^
/Qt/5.4/gcc_64/include/QtCore/qobject.h:254: Fehler: invalid use of incomplete type 'struct QtPrivate::QEnableIf<false, QMetaObject::Connection>'
/Qt/5.4/gcc_64/include/QtCore/qglobal.h:1056: Fehler: declaration of 'struct QtPrivate::QEnableIf<false, QMetaObject::Connection>'
template <bool B, typename T = void> struct QEnableIf;
^
/Qt/5.4/gcc_64/include/QtCore/qobject.h:293:
Fehler: no type named 'Object' in 'struct QtPrivate::FunctionPointer<const char*>'
通过尝试,我发现问题出在信号 QAction 中,因为来自 Mainwindow 的信号可以连接到来自 mainwindow 的插槽
项目一和项目二的唯一区别似乎是工具栏的添加方式
addToolBar
对比
QToolBar *toolbar = new QToolBar; and
mvbox->addWidget(toolbar);
您忘记在 mainwindow.cpp 中包含 QAction header。
#include <QAction>
它应该可以正确编译您的程序。
为什么不使用 SLOTS
?
toolbar = addToolBar("main toolbar");
toolbar->addAction("Open", this, SLOT(open_file()) );
toolbar->addAction("New", this, SLOT(new_file());
toolbar->addAction("Quit", this, SLOT(quit_application());
同时在 header
:
[...]
public slots:
void open_file();
void new_file();
void quit_application();
[...]
SLOTS 是 QT 最佳实践,你应该使用它们。