当类A和类B需要操作同一个输入框时,需要采用共享实例的设计模式。以下是具体实现方案:
// MainWindow.h
#include
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr);
private:
QTextEdit* m_sharedEditor; // 被共享的编辑器
ClassA* m_classA;
ClassB* m_classB;
};
// MainWindow.cpp
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
{
m_sharedEditor = new QTextEdit(this); // 父对象为MainWindow
m_classA = new ClassA(m_sharedEditor, this);
m_classB = new ClassB(m_sharedEditor, this);
// 布局设置...
}
// ClassA.h
#include
class ClassA : public QWidget {
Q_OBJECT
public:
explicit ClassA(QTextEdit* sharedEditor, QWidget* parent = nullptr);
private:
QTextEdit* m_editor; // 指向共享实例的指针
QPushButton* m_btn;
};
// ClassA.cpp
ClassA::ClassA(QTextEdit* sharedEditor, QWidget* parent)
: QWidget(parent),
m_editor(sharedEditor) // 保存共享指针
{
m_btn = new QPushButton("修改文本A", this);
connect(m_btn, &QPushButton::clicked, [this]() {
m_editor->append("来自A的修改"); // 操作共享编辑器
});
}
// ClassB.h (结构类似ClassA)
class ClassB : public QWidget {
Q_OBJECT
public:
explicit ClassB(QTextEdit* sharedEditor, QWidget* parent = nullptr);
private:
QTextEdit* m_editor; // 同一实例
QLineEdit* m_input;
};
// ClassB.cpp
ClassB::ClassB(QTextEdit* sharedEditor, QWidget* parent)
: QWidget(parent),
m_editor(sharedEditor)
{
m_input = new QLineEdit(this);
QPushButton* btn = new QPushButton("提交到编辑器", this);
connect(btn, &QPushButton::clicked, [this]() {
m_editor->setText(m_input->text()); // 修改共享内容
});
}
// 使用QMutex保护共享资源(如果涉及多线程)
class ThreadSafeEditor {
public:
void appendText(const QString& text) {
QMutexLocker locker(&m_mutex);
m_editor->append(text);
}
private:
QTextEdit* m_editor;
QMutex m_mutex;
};
// 当需要跨类同步状态时
// 在MainWindow中连接信号
connect(m_classA, &ClassA::textUpdated,
m_sharedEditor, &QTextEdit::append);
connect(m_classB, &ClassB::textUpdated,
m_sharedEditor, &QTextEdit::append);
// 使用QPointer防止野指针
class ClassA {
private:
QPointer<QTextEdit> m_editor; // 自动置空当对象被销毁时
};
// 使用前检查有效性
if(!m_editor.isNull()) {
m_editor->setText("安全操作");
}
// TextMediator.h
class TextMediator : public QObject {
Q_OBJECT
public:
void registerEditor(QTextEdit* editor) {
m_editor = editor;
}
void submitText(const QString& text, QObject* sender) {
if(m_editor) {
m_editor->append(QString("[%1] %2")
.arg(sender->metaObject()->className())
.arg(text));
}
}
private:
QTextEdit* m_editor = nullptr;
};
// 在ClassA/B中通过中介者操作
m_mediator->submitText(text, this);
// TextSubject.h
class TextSubject : public QObject {
Q_OBJECT
public:
void attach(QTextEdit* editor) {
m_editors.append(editor);
}
void notifyAll(const QString& text) {
for(auto editor : m_editors) {
editor->setText(text);
}
}
private:
QList<QTextEdit*> m_editors;
};
// 使用队列化操作(Qt::QueuedConnection)
connect(sender, &Sender::textChange,
m_editor, &QTextEdit::setText,
Qt::QueuedConnection);
// 当某个类需要获取焦点时
void ClassA::highlightEditor() {
if(m_editor) {
m_editor->setFocus();
m_editor->selectAll();
}
}
// 添加Undo/Redo支持
class EditHistory {
public:
void pushState(const QString& text) {
m_history.push(text);
}
QString undo() {
if(!m_history.isEmpty()) {
return m_history.pop();
}
return "";
}
private:
QStack<QString> m_history;
};
class ITextEditor {
public:
virtual void appendText(const QString&) = 0;
virtual QString content() const = 0;
};
TEST_F(SharedEditorTest, testConcurrentAccess) {
editor->setText("");
classA->append("A");
classB->append("B");
EXPECT_EQ(editor->toPlainText(), "A\nB");
}
通过这种设计,类A和类B可以安全、高效地协同操作同一个输入框,同时保持代码的可维护性和扩展性。