gpt4 book ai didi

c++ - 编译代码中的 "Reparent"类

转载 作者:搜寻专家 更新时间:2023-10-31 01:14:51 24 4
gpt4 key购买 nike

以下案例:假设有一个二进制库,它定义了“Base”类及其许多子类(“Derivative1”、“Derivative2”等)。

我想在我自己的代码中扩展这些子类,但是因为我的扩展对所有子类都是相同的,因为它们只处理 Base 的一部分,所以将每个 Derivative 类都子类化并一遍又一遍地添加相同的代码会很乏味再次。

我的第一个想法是简单地编写一个可以为我完成工作的类模板,但是因为我正在处理的库是 Qt,所以 QObject 挫败了我。我的第二个想法是使用宏来生成每个类结构,但这也被 moc 阻挠了。

标题中的“reparent”是因为我想到了从Base派生并创建BaseExtended,然后以某种方式告诉编译器将每个Derivative reparent到这个扩展类。有没有办法例如在“BaseExtended”虚拟中声明“Base”,然后只写

class Derivative1Extended : public Derivative1, public BaseExtended {}

并让 BaseExtended 中的虚拟 Base 指向 Derivative1 中的 Base,从而基本上“挤压”我在 Base 和 Derivative1 之间的扩展?

(顺便说一下,我尽量让上面的内容尽可能通用,但我实际上在做的是尝试为每个 QWidget 衍生产品添加“focusIn”和“focusOut”信号,而不是一遍又一遍地编写相同的代码再次为我使用的每个 QWidget 子类)

编辑:作为引用,这是我当前的实现:

// qwidgetfs.h
class QLineEditFS : public QLineEdit
{
Q_OBJECT

private:
void focusInEvent(QFocusEvent *);
void focusOutEvent(QFocusEvent *);

public:
QLineEditFS(QWidget *parent = 0);
signals:
void focusReceived(QWidgetFS::InputType);
void focusLost();
};

// qwidgetfs.cpp
QLineEditFS::QLineEditFS(QWidget *parent /*= 0*/)
: QLineEdit(parent)
{}

void QLineEditFS::focusInEvent(QFocusEvent *e)
{
QLineEdit::focusInEvent(e);
emit focusReceived(QWidgetFS::InputText);
}

void QLineEditFS::focusOutEvent(QFocusEvent *e)
{
QLineEdit::focusOutEvent(e);
emit focusLost();
}

这对 QSpinBoxFS、QComboBoxFS、QCheckBoxFS 等重复...相反,我只想在一个公共(public)类 QWidgetFS 中定义这个逻辑,然后将它“注入(inject)”到从 QWidget 派生的其他类中

最佳答案

我不确定您是否真的能够在不修改 Qt 并重新编译它的情况下执行您的建议。

也许做你想做的,你可以使用安装在你想要处理焦点事件的对象上的事件过滤器?

小测试应用:

标题:

class FocusEventFilter : public QObject
{
Q_OBJECT
public:
FocusEventFilter(QObject* parent)
: QObject(parent)
{}

Q_SIGNALS:
void focusIn(QWidget* obj, QFocusEvent* e);
void focusOut(QWidget* obj, QFocusEvent* e);

protected:
bool eventFilter(QObject *obj, QEvent *e);
};

class testfocus : public QMainWindow
{
Q_OBJECT

public:
testfocus(QWidget *parent = 0, Qt::WFlags flags = 0);
~testfocus();

public Q_SLOTS:
void onFocusIn(QWidget*, QFocusEvent*);
void onFocusOut(QWidget*, QFocusEvent*);

private:
Ui::testfocusClass ui;
};

实现

#include <QFocusEvent>
#include "testfocus.h"

bool FocusEventFilter::eventFilter(QObject *obj, QEvent *e)
{
if (e->type() == QEvent::FocusIn) {
bool r = QObject::eventFilter(obj, e);
QFocusEvent *focus = static_cast<QFocusEvent*>(e);
QWidget* w = qobject_cast<QWidget*>(obj);
if (w) {
emit focusIn(w, focus);
}
return r;
}
else if (e->type() == QEvent::FocusOut) {
bool r = QObject::eventFilter(obj, e);
QFocusEvent *focus = static_cast<QFocusEvent*>(e);
QWidget* w = qobject_cast<QWidget*>(obj);
if (w) {
emit focusOut(w, focus);
}
return r;
}
else {
// standard event processing
return QObject::eventFilter(obj, e);
}
}


testfocus::testfocus(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);

FocusEventFilter* filter = new FocusEventFilter(this);

ui.lineEdit->installEventFilter(filter);
ui.lineEdit_2->installEventFilter(filter);

connect(filter, SIGNAL(focusIn(QWidget*, QFocusEvent*)), this, SLOT(onFocusIn(QWidget*, QFocusEvent*)));
connect(filter, SIGNAL(focusOut(QWidget*, QFocusEvent*)), this, SLOT(onFocusOut(QWidget*, QFocusEvent*)));
}

testfocus::~testfocus()
{

}

void testfocus::onFocusIn(QWidget* obj, QFocusEvent*)
{
obj->setStyleSheet("background-color:#aaaaff;");

}

void testfocus::onFocusOut(QWidget* obj, QFocusEvent*)
{
obj->setStyleSheet("background-color:#ffaaaa;");
}

当然,YMMV。每个对象总是可以有一个单独的过滤器。这种方法意味着你可以避免从一切派生。效率不高,但应该可以。

您可以在事件过滤器本身中做您想做的事,而不是使用信号/槽。

关于c++ - 编译代码中的 "Reparent"类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10832660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com