大家好我想从非成员函数更新ui。除了将'this'指针作为我的非成员传递之外的任何帮助都是来自库的回调。
以下是我的代码:
mainwindow.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。请帮帮我。
编辑:我不允许修改我的回调
基于评论编辑:callback
将在另一个线程中调用,因此从那里调用widget方法会出现错误'cannot send events to objects owned by a different thread'
答案 0 :(得分:2)
通过你的评论
"我试图创建全局指针Ui :: MainWindow * myui并分配 myui到ui在构造函数中,但它会抛出以下错误: '无法将事件发送到不同线程所拥有的对象。"
问题是,你的callback
被错误的线程调用了。这是一个解决方案:
创建指向实际主窗口实例的全局指针,让我们将其称为MainWindow *mainWinInstance;
。另外要注意主窗口实例的活动时间比回调所针对的库/线程要长,或者使用QPointer
即使在主窗口之后有callback
被调用的风险被毁坏了。
将以下广告位方法添加到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
}
使用Qt::QueuedConnection
是非常重要的。它将方法调用放在目标对象的正确线程的事件队列中并立即返回。然后,目标线程的事件循环将进行实际调用。
答案 1 :(得分:1)
您需要在单独的标题中创建一个界面:
itextbrowseraccessor.h
class ITextBrowserAccessor
{
public:
void appendText(const QString& text) = 0;
}
从MainWindow
继承ITextBrowserAccessor
并实施方法:
void MainWindow::appendText(const QString& text)
{
ui->textBrowser->append(text);
}
在库源文件中包含itextbrowseraccessor.h
。将指向接口的指针传递给回调。
static void callback(ITextBrowserAccessor* accessor, QString result)
{
accessor->appendText(result);
}
答案 2 :(得分:0)
您可以尝试使用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"));
答案 3 :(得分:0)
这里提到的所有事情都没有。 通过创建一个虚拟Qobject来解决它,它有一个公共函数来向主窗口发送信号。创建这个虚拟qobject的实例,并在我的回调中调用公共函数。
PS:我有限制不修改我的回调因此上面的解决方案。