gpt4 book ai didi

c++ - 当更新值用作回调时如何在QT/C++中处理进度条

转载 作者:行者123 更新时间:2023-11-28 06:28:57 26 4
gpt4 key购买 nike

我正在编写一个应用程序来在 Android 设备和 Mac 之间传输文件。 Tha 文件传输正在运行,但就用户体验而言,我想添加一个进度条以便能够看到传输何时结束。

当我转移到安卓设备时,我不得不使用 mtp 堆栈。用于复制文件的函数是

LIBMTP_Send_File_From_File(device, path, genfile, ProgressBar, NULL);

ProgressBar是一个回调函数,MTP栈是用C写的。

我的应用程序是用 C++/Qt 编写的。

我首先设计了一个进度条,并希望使用 CONNECT/SIGNAL/SLOT 机制来更新进度条,但它不起作用。

我所做的是在 dialog.h 中定义我的回调:

extern "C" int ProgressBar(const uint64_t data_sent, const uint64_t data_total, void const * const data);

和一个类来设计对话框。

class Dialog : public QWidget
{
Q_OBJECT
public:
Dialog();
void CreateProgressBar();
void DestroyProgressBar();

private:
QWidget *ProgressDialog;
QProgressBar *ProgressIndicator;
QVBoxLayout *ProgressLayout;

QPushButton *CancelButton;

private slots:
void onCancelButtonAction();
};

在 Dialog.c 中,

Dialog::Dialog()
{
}

void Dialog::CreateProgressBar() {
ProgressDialog = new QWidget(this);
ProgressDialog->setWindowTitle("Progress");

ProgressLayout = new QVBoxLayout(this);

ProgressIndicator = new QProgressBar();
ProgressIndicator->resize(200,25);
//ProgressIndicator->setrange(0,100);
ProgressIndicator->setValue(0);
ProgressIndicator->setOrientation(Qt::Horizontal);
connect(ProgressIndicator,SIGNAL(ProgressBar(const uint64_t, const uint64_t, void const * const)),ProgressIndicator,SLOT(setValue(int)));

CancelButton = new QPushButton();
CancelButton->setFixedSize(25,25);
CancelButton->setText("Cancel");
CancelButton->setFlat(true);
CancelButton->setAutoFillBackground(true);
CancelButton->setStyleSheet("QPushButton { background-color : white;}");
connect(CancelButton, SIGNAL(clicked()), this, SLOT(onCancelButtonAction()));

ProgressLayout->addWidget(ProgressIndicator);
ProgressLayout->addWidget(CancelButton);

ProgressDialog->setLayout(ProgressLayout);
ProgressDialog->show();
}

void Dialog::DestroyProgressBar() {
ProgressDialog->close();
}

void Dialog::onCancelButtonAction() {
DestroyProgressBar();
}

和“ProgressBar”的 C 代码

int ProgressBar(const uint64_t data_sent, const uint64_t data_total, void const * const data) {
return (data_sent * 100) / data_total;
}

这基本上不起作用,因为连接拒绝将 SIGNAL 连接到 ProgressBar,因为它不是类的一部分。

另一方面,如果我在类中移动 ProgressBar,连接正常,但代码不会构建,因为 LIBMTP_Send 拒绝使用类。

我正在使用 MyProgress.ProgressBar 在 LIBMTP_Send 中调用 ProgressBar

    Dialog MyProgress;
MyProgress.CreateProgressBar();

LIBMTP_Send_File_From_File(device, path, genfile, MyProgress.ProgressBar, NULL);

它不起作用,因为如果我的类而不是 C 回调,我使用对方法的调用

我尝试使用类而不是 C 代码时的方法定义如下:

int Dialog::ProgressBar(const uint64_t data_sent, const uint64_t data_total, void const * const data) {
char* tmp_string;
char* tmp_sent;
char* tmp_total;

if(ProgressIndicator.destroyed() == true)
return true;

if (ProgressIndicator != NULL) {

ProgressIndicator->setValue();
}

if (progressDialog != NULL) {
return (data_sent * 100) / data_total;
}
return 0;
}

在那种情况下,我正在做:

ret = LIBMTP_Send_File_From_File(PulsDeviceMngr->device, strdup(AbsolutePath), genfile, MyProgress.ProgressBar, NULL);

但构建错误是:必须调用对非静态成员函数的引用

我正在调用 LIBMTP 函数的代码中创建 Dialog 的实例,如下所示:

  Dialog MyProgress;
MyProgress.CreateProgressBar();

genfile = LIBMTP_new_file_t();
...

ret = LIBMTP_Send_File_From_File(PulsDeviceMngr->device, strdup(AbsolutePath), genfile, MyProgress.ProgressBar, NULL);

我真的卡住了……空的:-)

最佳答案

要做到这一点,你必须传递一个指向类的指针作为回调的参数

LIBMTP_Send_File_From_File(device, path, genfile, MyProgress.ProgressBar, NULL);

NULL 参数是回调参数

Dialog *MyProgress = new Dialog(parentWindow);
LIBMTP_Send_File_From_File(device, path, genfile, ProgressBar, MyProgress);
/* ^ here a pointer to */
/* progress dialog */

注意:parentWindow 可能是您的QMainWindow,它非常重要,否则您会发生内存泄漏。

然后在回调中数据参数将指向对话框,所以你可以这样做

Dialog *dialog = reinterpret_cast<Dialog *>(data);
dialog->setValue((data_sent * 100) / data_total);

关于c++ - 当更新值用作回调时如何在QT/C++中处理进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27994971/

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