从库(DLL)函数访问ui指针
Access ui pointer from a library (DLL) function
嗨,我想从一个非成员函数更新ui。除了将"this"指针作为我的非成员传递之外,任何帮助都是来自库的回调。
以下是我的代码:
主窗口.cpp
static void callback(QString result)
{
ui->textBrowser->append(result);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
int a=1,b=2;
QLibrary myLib("myaddlib");
myLib.load();
add = (myadd)myLib.resolve("add_function");
add(callback, a, b);
}
因此,我所需要的就是能够从非成员回调中将数据附加到UI中。请帮帮我。
编辑:我不允许修改我的回调
基于注释的EDIT:callback
将在另一个线程中调用,因此从那里调用小部件方法会产生错误'cannot send events to objects owned by a different thread'
根据您的评论
"我尝试创建全局指针Ui::MainWindow*myui并分配构造函数中的myui到ui,但它会引发以下错误:"无法将事件发送到其他线程拥有的对象"。"
问题是,您的callback
在错误的线程中被调用。这里有一个解决方案:
-
创建指向实际主窗口实例的全局指针,我们称之为
MainWindow *mainWinInstance;
。还要注意的是,主窗口实例的使用寿命将比回调所针对的库/线程长,或者如果即使在主窗口被破坏后callback
也有被调用的风险,则使用QPointer
。 -
将以下插槽方法添加到
MainWindow
:MainWindow::appendText(const QString &text) { // use const ref for efficiency ui->textBrowser->append(result); }
-
更改
callback
以使用排队连接类型的QMetaObject::invokeMethod
调用该方法:static void callback(QString result) { bool r = QMetaObject::invokeMethod(mainWinInstance, "appendText", Qt::QueuedConnection, Q_ARG(QString, result)); Q_ASSERT(r); // should only fail if there's a mistake in above code }
使用CCD_ 10是非常重要的。它将把方法调用放在目标对象的正确线程的事件队列中,并立即返回。然后,目标线程的事件循环将执行实际调用。
您需要在一个单独的头中创建一个接口:
itextbrowseraccessor.h
class ITextBrowserAccessor
{
public:
void appendText(const QString& text) = 0;
}
从ITextBrowserAccessor
继承MainWindow
并实现方法:
void MainWindow::appendText(const QString& text)
{
ui->textBrowser->append(text);
}
在库源文件中包含itextbrowseraccessor.h
。将指向接口的指针传递给回调。
static void callback(ITextBrowserAccessor* accessor, QString result)
{
accessor->appendText(result);
}
您可以尝试使用QApplication::topLevelWidgets()
查找主窗口。
找到主窗口后,使用mainWindow->findChild<QTextBrowser*>()
查找浏览器小部件,然后根据需要修改其内容。
编辑:
示例:
Q_ASSERT(QApplication::topLevelWidgets() == 1);
QWidget* mainWindow = QApplication::topLevelWidgets().first();
QTextEditor* editor = mainWindow->findChild<QTextBrowser*>();
Q_ASSERT(editor != NULL);
editor->append(QLatin1String("abc"));
这里提到的所有事情对我都不起作用。通过创建一个具有公共函数的伪Qobject来向主窗口发送信号,从而解决了这个问题。创建这个伪qobject的一个实例,并在回调中调用公共函数。
附言:我有一个限制,不能修改我的回调,因此上面的解决方案。
- Qt5 ui,多个窗口:如何从窗口 1 访问窗口 2 中的 UI 对象
- 如何创建一个接口,允许我访问C++中的按钮(和其他ui)函数,该函数是使用python中的MFC实现的
- 从多个文件访问静态全局 WinForm UI 对象
- 如何从不同类的静态成员函数访问非静态Qt-Ui函数
- Qt5 从另一个类访问 UI
- 无法从外部cpp文件访问Qt UI
- 访问列表项时的 UI 和工作线程同步
- 从 Web UI 访问C++编译的可执行二进制文件
- 从库(DLL)函数访问ui指针
- 正在尝试访问命名空间Ui中的类
- 如何访问子UI文件
- 两个线程(COM和WPF UI)访问同一个浮点
- QT/C++关于访问UI文件的另一个问题
- Qt - Ui访问违反Visual Studio 2010
- 在窗口构造函数之外动态地将QAction添加到QMenuBar中(可以从另一个文件访问Designer中生成的ui)
- QT c++如何从不同的类访问主窗口UI
- 访问来自另一个c++类的UI元素
- Qtest访问ui成员
- 工作线程需要访问UI
- Qt 无法从继承类访问 *ui 指针