C++ app.exec()无法调用其他方法(静态库)
我创建了一个静态库。我需要通过调用一些方法来改变图片的位置。问题是“app.exec()”完全阻塞了进程。你知道怎么做吗 非常感谢 这是我的lib头文件C++ app.exec()无法调用其他方法(静态库),c++,qt,C++,Qt,我创建了一个静态库。我需要通过调用一些方法来改变图片的位置。问题是“app.exec()”完全阻塞了进程。你知道怎么做吗 非常感谢 这是我的lib头文件 int init(int argc, char *argv[], int width, int height); void changePos (int x, int y); void destroyPic(); 我的初衷是: QWidget*窗口(0); QLabel*pic(0) 问题是我无法在我的主代码(使用此库)中调用方法change
int init(int argc, char *argv[], int width, int height);
void changePos (int x, int y);
void destroyPic();
我的初衷是:
QWidget*窗口(0);
QLabel*pic(0)
问题是我无法在我的主代码(使用此库)中调用方法changePos或destroy,因为app.exec()会阻止进程。。。怎么做
非常感谢 在使用QApplication::exec()进入QApplication事件循环之前,可以调用init()
我能想到的唯一其他选择是:
QTimer::singleShot(0, this, SLOT(init()));
这需要您有一个QObject,并且init或其他调用init的函数需要很多。在QApplication::exec()之前调用此函数,插槽将在事件循环启动后执行。您需要在单独的QThread中启动QApplication。这在下面的代码中显示。我还没有让它在OSX上运行,但我相信它应该是可行的。我需要先为OSX做一个调试构建,然后看看有什么进展。经过测试,它可以在Windows上工作,并且可能也可以在X11上工作。目标C代码仅适用于mac,它可能是必需的,但还不够 它是一个完整的可运行应用程序,对于一个库,您可以删除
main()
函数并调用init、changePos,然后根据需要直接完成
#applib.pro
QT += core gui
TARGET = applib
TEMPLATE = app
!x11:!embedded:!qpa:mac {
LIBS_PRIVATE += -framework Cocoa -lz
OBJECTIVE_SOURCES += thread.mm
}
SOURCES += main.cpp
//main.cpp
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//
//原料药
//
外部“C”{
void init(int argc,字符**argv);
无效更改位置(整数x,整数y);
空隙饰面();
}
//演示代码,从库中删除
int main(int argc,字符**argv)
{
类帮助程序:私有QThread{
公众:
静态void msleep(无符号长ms){
QThread::msleep(ms);
}
};
初始值(argc,argv);
助手:msleep(2000);
changePos(0,0);
助手:msleep(2000);
完成();
}
//
//实施
//
结构PosEvent:publicqevent
{
PosEvent(intx,inty):QEvent(t()),
x(x_),y(y_){
常数int x,y;
静态QEvent::Type t(){return(QEvent::Type)(QEvent::User+0);}
};
类小部件:公共QLabel
{
公众:
Widget():QLabel(“你好!”){}
受保护的:
无效自定义事件(QEvent*ev){
如果(ev->type()==PosEvent::t()){
PosEvent*pev=静态_铸造(ev);
移动(pev->x,pev->y);
}
}
};
类QCoreApplicationPrivate{
公众:
静态QThread*主线程;
};
外部“C++”{Qt::HANDLE Qt_应用程序_线程_id;}
类AppThread:publicQThread
{
公众:
AppThread(int&argc,char**argv){
Q_断言(!实例);
实例=此;
QMutexLocker锁(&argMutex);
argc=&argc;
argv=argv_389;;
start();
wc.wait(&argMutex);
}
静态无效更改位置(整数x,整数y){
QCoreApplication::postEvent(实例->小部件,新的PosEvent(x,y));
}
静态空隙饰面(){
实例->应用->退出();
实例->等待();
删除实例;
}
受保护的:
无效运行(){
int i=0;
#ifdef Q_OS_UNIX
//qDebug(“%p”,qt\u应用程序\u线程\u id);
QCoreApplicationPrivate::theMainThread=QThread::currentThread();
#恩迪夫
申请a(i,0);
app=&a;
wc.wakeAll();
小部件w;
widget=&w;
w、 show();
rc=a.exec();
}
私人:
静态AppThread*实例;
QCoreApplication*app;
QObject*小部件;
QMutex argMutex;
qwaitconditionwc;
int*argc;
字符**argv;
int rc;
};
AppThread*AppThread::instance=0;
bool多线程();
#ifndef Q_OS_MAC
bool多线程(){return true;}
#恩迪夫
外部“C”void init(内部argc,字符**argv){
多线程();
#ifdef Q_OS_MAC
qDebug(“DYLD\u图像后缀=%s”,getenv(“DYLD\u图像后缀”);
#恩迪夫
新的AppThread(argc、argv);
}
外部“C”void changePos(intx,inty){AppThread::changePos(x,y);}
外部“C”void finish(){AppThread::finish();}
//thread.mm
#进口
@接口死线程:NSObject{;;}
+(void)输入多线程模式;
+(void)清空读取方法:(id)obj;
@结束
@实现死线程
+(无效)输入多线程模式{
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
[NSThread detachNewThreadSelector:@selector(emptyThreadMethod:)
toTarget:[DeadThread类]和对象:nil];
[池释放];
}
+(void)emptyThreadMethod:(id)obj{(void)obj;}
@结束
bool多线程()
{
[死线程进入多线程模式];
返回[NSThread isMultiThreaded];
}
事实上,我知道app.exec()是一个阻塞函数,我想知道如何在不使用此函数的情况下显示窗口,或者如何在不阻塞我的程序的情况下显示窗口。看起来您的静态库实际上是一个程序。。。你想再做什么?我有一个不使用QT的程序。我只是在里面添加了Qt库。因为这个程序的一部分需要显示一个窗口,带有一些图片,移动这个图片,然后“销毁”这个窗口,我想使用一个lib来显示窗口,图片,移动它们,然后销毁它们,而不在我的主程序中添加Qt(带有qmake,等等)(因为这很复杂,我真的不想在我的主程序中包括Qt)在这种情况下,你需要在一个新的进程中启动Qt,你的意思是在线程中启动init方法,对吗?
#applib.pro
QT += core gui
TARGET = applib
TEMPLATE = app
!x11:!embedded:!qpa:mac {
LIBS_PRIVATE += -framework Cocoa -lz
OBJECTIVE_SOURCES += thread.mm
}
SOURCES += main.cpp
//main.cpp
#include <cstdlib>
#include <QtCore/QThread>
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QWaitCondition>
#include <QtCore/QEvent>
#include <QtGui/QLabel>
#include <QtGui/QApplication>
//
// API
//
extern "C" {
void init(int argc, char ** argv);
void changePos(int x, int y);
void finish();
}
// demonstration code, remove from the library
int main(int argc, char ** argv)
{
class Helper : private QThread {
public:
static void msleep(unsigned long ms) {
QThread::msleep(ms);
}
};
init(argc, argv);
Helper::msleep(2000);
changePos(0, 0);
Helper::msleep(2000);
finish();
}
//
// IMPLEMENTATION
//
struct PosEvent : public QEvent
{
PosEvent(int x_, int y_) : QEvent(t()),
x(x_), y(y_) {}
const int x, y;
static QEvent::Type t() { return (QEvent::Type)(QEvent::User + 0); }
};
class Widget : public QLabel
{
public:
Widget() : QLabel("Hello!") {}
protected:
void customEvent(QEvent * ev) {
if (ev->type() == PosEvent::t()) {
PosEvent * pev = static_cast<PosEvent*>(ev);
move(pev->x, pev->y);
}
}
};
class QCoreApplicationPrivate {
public:
static QThread * theMainThread;
};
extern "C++" { Qt::HANDLE qt_application_thread_id; }
class AppThread : public QThread
{
public:
AppThread(int& argc_, char ** argv_) {
Q_ASSERT(!instance);
instance = this;
QMutexLocker lock(&argMutex);
argc = &argc_;
argv = argv_;
start();
wc.wait(&argMutex);
}
static void changePos(int x, int y) {
QCoreApplication::postEvent(instance->widget, new PosEvent(x,y));
}
static void finish() {
instance->app->exit();
instance->wait();
delete instance;
}
protected:
void run() {
int i = 0;
#ifdef Q_OS_UNIX
//qDebug("%p", qt_application_thread_id);
QCoreApplicationPrivate::theMainThread = QThread::currentThread();
#endif
QApplication a(i, 0);
app = &a;
wc.wakeAll();
Widget w;
widget = &w;
w.show();
rc = a.exec();
}
private:
static AppThread * instance;
QCoreApplication * app;
QObject * widget;
QMutex argMutex;
QWaitCondition wc;
int* argc;
char** argv;
int rc;
};
AppThread * AppThread::instance = 0;
bool multiThreader();
#ifndef Q_OS_MAC
bool multiThreader() { return true; }
#endif
extern "C" void init(int argc, char ** argv) {
multiThreader();
#ifdef Q_OS_MAC
qDebug("DYLD_IMAGE_SUFFIX=%s", getenv("DYLD_IMAGE_SUFFIX"));
#endif
new AppThread(argc, argv);
}
extern "C" void changePos(int x, int y) { AppThread::changePos(x, y); }
extern "C" void finish() { AppThread::finish(); }
//thread.mm
#import <Foundation/Foundation.h>
@interface DeadThread : NSObject { ;; }
+ (void)enterMultiThreadedMode;
+ (void)emptyThreadMethod:(id)obj;
@end
@implementation DeadThread
+ (void)enterMultiThreadedMode {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSThread detachNewThreadSelector:@selector(emptyThreadMethod:)
toTarget:[DeadThread class] withObject:nil];
[pool release];
}
+ (void)emptyThreadMethod:(id)obj { (void)obj; }
@end
bool multiThreader()
{
[DeadThread enterMultiThreadedMode];
return [NSThread isMultiThreaded];
}