如何在C4Droid中编译简单的Qt 5.2项目
How to compile simple Qt 5.2 project in C4Droid
我正试图弄清楚如何在C4Droid中构建和编译一个简单的Qt项目,C4Droid是一个适用于Android的C++编译器。
该程序提供了两个简单的示例:一个"Hello world"标签(一个文件)和一个示例记事本。第二个看起来很有趣,但它处理的是完全由代码创建的表单。
我正在调查是否可以使用从.ui文件生成的表单进行此操作。我在Qt Creator中为Qt 4.8创建了一个简单的项目,编译了.ui表单,并将代码从Qt 4.8改编为Qt 5.2。项目本身非常简单:一个带有QButton和QLineEdit的表单。当按下Q按钮时,QLineEdit中将显示"Hello world"。
据我所见,C4Droid不解析.pro文件。要编译项目,我必须打开main.cpp并长按"编译",选择"编译多个源代码文件(简单)",然后运行。C4droid在.cdroid文本文件中使用自己的"makefile"文件。
这些是我在C4droid测试文件夹中发布的文件:
按钮HelloWorld.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ButtonHelloWorld
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp:
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
主窗口.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_ButtonSayHello_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_ButtonSayHello_clicked()
{
ui->LeditSayHello->setText(tr("Hello world"));
}
ui_mainwindow.h:
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QAction>
#include <QApplication>
#include <QButtonGroup>
#include <QHeaderView>
#include <QLineEdit>
#include <QMainWindow>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QVBoxLayout *verticalLayout;
QPushButton *ButtonSayHello;
QLineEdit *LeditSayHello;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(198, 103);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
verticalLayout = new QVBoxLayout(centralWidget);
verticalLayout->setSpacing(6);
verticalLayout->setContentsMargins(11, 11, 11, 11);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
ButtonSayHello = new QPushButton(centralWidget);
ButtonSayHello->setObjectName(QString::fromUtf8("ButtonSayHello"));
verticalLayout->addWidget(ButtonSayHello);
LeditSayHello = new QLineEdit(centralWidget);
LeditSayHello->setObjectName(QString::fromUtf8("LeditSayHello"));
LeditSayHello->setAlignment(Qt::AlignCenter);
verticalLayout->addWidget(LeditSayHello);
MainWindow->setCentralWidget(centralWidget);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
ButtonSayHello->setText(QApplication::translate("MainWindow", "Say Hello", 0));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
我把原始的mainwindow.ui放在这里供参考(c4droid不使用它):
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>198</width>
<height>103</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="ButtonSayHello">
<property name="text">
<string>Say Hello</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="LeditSayHello">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
当我尝试在C4droid中从main.cpp编译这个项目时,输出是:
/storage/emulated/0/Bull/C4Droid/ButtonHelloWorld/main.cpp:0:注意:否找到相关类。未生成输出。/data/data.com/n0n3m4.droidc/files/gcc/tmpdir/ccyCC2RV.o:In函数
MainWindow::MainWindow(QWidget*)': mainwindow.cpp:(.text+0xc4): undefined reference to
主窗口的vtable/data/data.com/n0n3m4.droidc/files/gcc/tmpdir/ccyCC2RV.o:In函数MainWindow::~MainWindow()': mainwindow.cpp:(.text+0x14c): undefined reference to
主窗口的vtable/data/data.com/n0n3m4.droidc/files/gcc/tmpdir/ccyCC2RV.o:In函数MainWindow::tr(char const*, char const*, int)': mainwindow.cpp:(.text._ZN10MainWindow2trEPKcS1_i[_ZN10MainWindow2trEPKcS1_i]+0x5c): undefined reference to
MainWindow::staticMetaObject'集合2:错误:ld返回1退出状态
我能做些什么来成功编译这个项目?
当然,我在谷歌上搜索了很多,并试图将.moc文件包括在内,但没有成功。
(顺便说一句,我现在刚刚尝试创建标签"C4Droid",但我没有足够的声誉来做到这一点://)
Update1---仔细查看C4droid附带的多个文件Qt示例,我注意到它使用了Makefile。阅读Makefile时,我注意到这个文件是使用以下命令生成的:
/data/data/com.n0n3m4.droidc/files/gcc/qt/bin/qmake-spec-android-g++-o Makefile应用程序.pro
(这也让我知道moc、qmake、rcc和uic可执行文件在我的android中的/data/data/com.n0n3m4.droidc/files/gcc/qt/bin/文件夹中)
这应该根据file.pro创建一个Makefile,它会自动告诉系统在编译之前使用uic、moc等,然后进行正确的链接。所以我在我的android中输入了终端并键入:
/data/data/com.n0n3m4.droidc/files/gcc/qt/bin/qmake-spec-android-g++-o Makefile按钮HelloWorld.pro
我得到的只是:
sh:arm linux androidabi gcc:未找到
更新2
C4droid开发人员回答我:
"C4droid可以解析.pro文件,请仔细查看示例。Google Play上的描述是唯一可用的教程,但它已经足够了。">
所以我决定转到C4droid中的.pro文件。在查看了示例编译选项后,我决定长按compile,选择"Makefile"编译模式和"Qt application"运行模式,并选择"ButtonHelloWorld.qexe"作为可执行文件。
我现在编译了,一切似乎都好多了,但最后弹出了这样的消息:
复制文件失败
有什么提示吗?
更新3
好吧,我测试并玩了(很多)捆绑的Qt应用程序示例,我再次给开发人员发了电子邮件,现在它已经非常方便了。
我:
我决定用你的例子做一个测试。我已经复制到一个新文件夹(/storage/emulated/0/Bull/C4Droid/application)
images folder application.pro application.qrc main.cpp mainwindow.cpp mainwindow.h
然后,在C4droid中,我打开application.pro,长按"编译"。选择"Makefile"编译模式和"Qt应用程序"运行模式,并将可执行文件"application.so"。它编译正常,但失败"复制文件失败"。
但如果我把"libapplication.so"作为可执行文件,它会编译并完成正常。
?为什么?
He:
因为在Android上,Qt可执行文件总是命名为libXXX.so
Me:
嗯,我尝试了"libappli.so",但得到了相同的错误。
但是,调查一下,我发现可执行文件的名称必须是lib[NameOf.proFileWithoutExtension].so,以及它的文件夹名称独立的。现在你复制的例子和我的工作!!
此外,他告诉我,一旦编译,将其导出到.APK就像菜单->导出一样简单。我试过了。。。太神奇了!!
结论
已解决。回答我自己的问题,以帮助处于同样处境的其他人。
这个答案可以被视为
在C4droid中编译和导出Qt项目的迷你教程
如何在Android的C++编译器C4Droid中构建和编译一个简单的Qt项目?
我在Qt Creator中为Qt 4.8创建了一个简单的项目,编译了.ui表单,并将代码从Qt 4.8改编为Qt 5.2。项目本身非常简单:一个带有QButton和QLineEdit的表单。当按下Q按钮时,QLineEdit中将显示"Hello world"。
这些是我在C4droid测试文件夹中发布的文件:
按钮HelloWorld.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ButtonHelloWorld
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp:
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
主窗口.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_ButtonSayHello_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_ButtonSayHello_clicked()
{
ui->LeditSayHello->setText(tr("Hello world"));
}
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>198</width>
<height>103</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="ButtonSayHello">
<property name="text">
<string>Say Hello</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="LeditSayHello">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
现在,从C4Droid打开ButtonHelloWorld.pro或main.cpp。长按Compile,选择"Makefile"编译模式和"Qt application"运行模式,并选择"libButtonHelloWorld.so"作为可执行文件。
这一点很重要:在Android Qt中,可执行文件总是命名为libXXX.so。可执行文件的名称必须是lib[NameOf.proFileWithoutExtension].so,并且它的文件夹名称是独立的。
编译和测试后,它运行正常,将其导出到.APK就像菜单->导出一样简单。
我试过了。。。太神奇了!!
PS:如果你想知道moc、qmake、rcc和uic可执行文件在哪里,它们在/data/data/com.n0n3m4.droidc/files/gcc/qt/bin/文件夹中(至少在我的android中)。
您忘记处理元对象编译器,简称"moc",用于主窗口的文件。否则,QObject机制将无法正常工作。
你需要做以下任何一件事:
moc -o mainwindow.moc mainwindow.h
g++ ... mainwindow.moc
作为构建过程的一部分,即通过显式运行moc来扩展Makefile,并将*.moc模式添加到要编译的文件列表中,或者通过它单独运行编译器命令。
或者,C4Droid似乎从3.49版本开始支持qmake项目文件。
- 错误-我无法在VS2019中打开新的Qt项目
- 将QT项目导入Visual Studio 2019会给我带来很多LNK2001错误
- 尝试在 QT 项目中调用 Java 代码时未找到类异常
- 无法在默认Qt项目中打开源文件"ui_QtGuiApplication.h"
- 在路径的独立Qt项目中包括外部库
- 为Qt项目树中的所有项目定义全局宏
- CMake用于C++/Qt项目中的外部库
- 如何将ICU库添加到ARM的Qt项目中
- 将libtensorflow_cc.so文件链接到QT项目
- 将网络添加到Qt项目
- 编译Qt项目,得到错误QQmlEngine:没有这样的文件或目录编译终止
- 是否可以在QT项目中使用Tensorflow C++ API?
- 在Qt C++项目中使用Go
- 编译Qt项目给出了对运算符delete(void*,unsigned int)的未定义引用
- 为Qt项目的每个模块添加一个包含
- 如何使用.UI文件在QT Creator中使用CMAKE制作GUI QT项目
- 在Qt项目中包括谷歌测试
- Qt项目与自定义共享库交叉编译Qt
- 如何从Qt C++项目运行Python函数
- 如何使用 qmake 将 pcl 库成功添加到 qt 项目中