我无法使用插槽/信号从VC ++转移到Qt风格的编程。我想创建一个带有图像的按钮,当单击该按钮时,将其更改为另一个图像,并在释放后更改回原始图像。我创建了一个名为ClickableQLabel
的类,它继承自QLabel,但它告诉我某些函数是重新定义的。具体来说,是那些emit
。
MainProgram.cpp
#include "MainProgram.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
CodeVault w;
w.show();
return a.exec();
}
MainProgram.h
#ifndef MAINPROGRAM_H
#define MAINPROGRAM_H
#include <QMainWindow>
#include "clickableqlabel.h"
namespace Ui {
class MainProgram;
}
class MainProgram : public QMainWindow
{
Q_OBJECT
public:
explicit MainProgram(QWidget *parent = 0);
~MainProgram();
private:
Ui::MainProgram *ui;
};
#endif // MAINPROGRAM_H
clickableqlabel.h
#ifndef CLICKABLEQLABEL_H
#define CLICKABLEQLABEL_H
#include <QLabel>
#include <QMouseEvent>
using namespace Qt;
class ClickableQLabel : public QLabel {
Q_OBJECT
QPixmap pushed;
QPixmap unpushed;
public:
ClickableQLabel(QWidget *parent = 0);
void mousePressEvent(QMouseEvent *eve );
void mouseReleaseEvent(QMouseEvent *eve );
void setPushed(QPixmap &p);
void setUnpushed(QPixmap &p);
signals:
void leftButtonPressed(ClickableQLabel* sender);
void leftButtonReleased(ClickableQLabel* sender);
};
#endif // CLICKABLEQLABEL_H
clickableqlabel.cpp
#include "clickableqlabel.h"
ClickableQLabel::ClickableQLabel(QWidget *parent) : QLabel(parent){
// set up qlabel
}
void ClickableQLabel::setPushed(QPixmap &p){
pushed = p;
}
void ClickableQLabel::setUnpushed(QPixmap &p){
unpushed = p;
}
void ClickableQLabel::leftButtonPressed(ClickableQLabel* sender){
if(!pushed.isNull())
sender->setPixmap(pushed.scaledToWidth(sender->width()));
}
void ClickableQLabel::leftButtonReleased(ClickableQLabel* sender){
if(!unpushed.isNull())
sender->setPixmap(unpushed.scaledToWidth(sender->width()));
}
void ClickableQLabel::mousePressEvent(QMouseEvent *eve ){
if(eve->button() == Qt::LeftButton){
emit leftButtonPressed(this);
}
}
void ClickableQLabel::mouseReleaseEvent(QMouseEvent *eve ){
if(eve->button() == Qt::LeftButton){
emit leftButtonReleased(this);
}
}
我收到的是以下3个错误:
moc_clickableqlabel.obj:-1: error: LNK2005: "public: void __cdecl ClickableQLabel::leftButtonPressed(class ClickableQLabel *)" (?leftButtonPressed@ClickableQLabel@@QEAAXPEAV1@@Z) already defined in clickableqlabel.obj
moc_clickableqlabel.obj:-1: error: LNK2005: "public: void __cdecl ClickableQLabel::leftButtonReleased(class ClickableQLabel *)" (?leftButtonReleased@ClickableQLabel@@QEAAXPEAV1@@Z) already defined in clickableqlabel.obj
debug\CodeVault.exe:-1: error: LNK1169: one or more multiply defined symbols found
导致错误的两个函数是clickableqlabel.h文件中的两个信号。我该如何设置connect
功能以及在哪里?
答案 0 :(得分:3)
您不应该为信号提供实施方案。您只需在类标题中声明信号。 Qt moc提供了一个实现,负责在信号发出时调用信号的插槽connect
,参见this。因为你提供了一个实现,而Qt moc提供了另一个实现,你最终会得到两个不同的实现,并且链接器会抱怨。
因此,为了在发出信号时执行某些代码,您可以将其放在连接到该信号的某个插槽中,或者您可以在发出信号之前手动执行它。 。
另外需要注意的是,您的信号有一个名为sender
的参数。通常没有必要这样做,QObject::sender()
提供类似的功能。
我应该如何设置连接功能以及在哪里?
例如,当您在ClickableQLabel
窗口中实例化MainProgram
时(可以在ClickableQLabel
表单文件中使用.ui
执行此操作),您可以{{1它的信号传递到connect
的插槽,就像这样。
mainprogram.h
MainProgram
然后在构造函数#ifndef MAINPROGRAM_H
#define MAINPROGRAM_H
#include <QMainWindow>
#include "clickableqlabel.h"
namespace Ui {
class MainProgram;
}
class MainProgram : public QMainWindow
{
Q_OBJECT
public:
explicit MainProgram(QWidget *parent = 0);
~MainProgram();
public slots:
void labelPressed();
void labelReleased();
private:
Ui::MainProgram *ui;
};
#endif // MAINPROGRAM_H
中,connect
向ClickableQLabel
的广告位发出信号,如下所示:
MainProgram
其中connect(clickableLabel, SIGNAL(leftButtonPressed()), this, SLOT(labelPressed()));
是您的clickableLabel
对象。
答案 1 :(得分:2)
您不应该明确定义信号&#34;功能&#34; - 简单地发出它们(就像在mousePressEvent()
和mouseReleaseEvent()
函数中一样)。
如果您想要执行某些操作(例如setPixmap),您可以在连接到这些信号的插槽函数中执行此操作,也可以直接在mousePressEvent
和mouseReleaseEvent
函数中执行此操作。 / p>
不相关,但您可能还需要执行qRegisterMetaType<ClickableQLabel>()
之类的操作,以便将该数据类型与信号/插槽机制一起使用。
答案 2 :(得分:0)
您无需子类化QLabel
来实现此目的:在onLabelButtonClicked
类中添加MainWindow
广告位(方法),该广告连接到QPushButton
{ {1}}信号,并根据需要调用setText / setIcon。
如果你想重新使用这个可点击的元素,你当然可以把它封装在一个类中,但是在定义新的widget时,Qt只需要子类化和处理raw-events;如果您只是编写标准功能(单击,调整外观),那么主窗口/对话框类中的插槽通常就足够了。