- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
以下案例:假设有一个二进制库,它定义了“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/
以下案例:假设有一个二进制库,它定义了“Base”类及其许多子类(“Derivative1”、“Derivative2”等)。 我想在我自己的代码中扩展这些子类,但是因为我的扩展对所有子类都是相同的,
我有一个下面列出的小应用程序,它只是在其中制作了一个 x 窗口和一个小窗口。我稍后计划制作一个实验性 IDE,其中所有的工具栏和菜单都是子窗口,并且可以选择任何想要管理它们的窗口管理器。 我想做的是启
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题?通过 editing this post 添加详细信息并澄清问题. 1年前关闭。 Improve this
我是一名优秀的程序员,十分优秀!