Copy link to clipboard
Copied
I tried creating AI plugin using
- Visual Studio Premium 2010
- Visual Studio Addin for Qt
- QWinWidget for Qt 4.8
- Qt 4.8 for windows
- Windows 7 32 bit
However, I could not compile the plugin for 64 bit edition as the Qt addin for visual studio do not support Qt 4.8 for 64 bit compilation.
I cannot switch to Qt 5.1 as compatible QWinWidget is not available there.
So I decided to migrate to Qt Creator 2.8 IDE instead of visual studio and bypass the addin.
I could migrate the VS project to a Qt project and compile it. I get a .aip file now.
However, this AI plugin is not loaded by Illustrator.exe
I added the following to get my aip file.
TARGET_EXT = .aip
TEMPLATE = lib
CONFIG += dll embed_manifest_dll
However,
1. the plugin main was not exposed. So, tried
DEF_FILE += "Definitions/PluginMain.def"
Dependency walker now shows "PluginMain", but AI cannot load the plugin.
Qt documentation tell, use "DEF_FILE" only with "app" template. Is this the reason for the failure ?
What is the solution ?
2. How to get the 64 bit target in Qt creator ?
I tried QMAKE_TARGET.arch = x86_64 but the target was 32 bit (checked in dependency walker).
My OS is 32 bit win 7. Is this the reason I cannot get 64 bit target ?
Do I need to install Qt environment on 64bit OS to get the 64 bit target ??
Message was edited by: Dataset
1 Correct answer
We don't use the VS addin, we use qmake at the command line to generate projects. If you do that, it will add all the UIC & MOC steps for you. You do have to regenerate the project every time you add something that has the Q_OBJECT macro in it, but that's actually less of a pain then you'd think. We have a batch file that does the heavy lifting and a script on Mac to do the same.
Explore related tutorials & articles
Copy link to clipboard
Copied
make sure your qt build is 64 bit (4x windows installer on qt site is 32 bit, so you may have to build the 64 bit version. I use qt visual studio plugin so that I am in familiar territory when building qt apps. It is better than struggling with qt build files.
I am not sure if you will be able to build 64 bit apps in 32 bit os. Should be possible, as long as required libraries are available. But you will not be able to run 64 bit illustrator on that machine anyway. It may be better to develop plugin using 32 bit env, then once it is working, move the code to 64 bit env, build and test. I have all 64 bit env (os, illustrator, plugin) except visual studio which is 32 bit (but also emits 64 bit code).
One more thing to check is that in qtcreator preferences, compilers, see if a 64 bit compiler is listed (amd64)
Copy link to clipboard
Copied
I don't know anything about Qt Creator, we use Studio and qmake to generate projects. Which admittedly is a bit of a problem, as qmake won't generate 64-bit project settings (which is insane, there's a bug that goes back a couple of years for that one). We solved a bunch of qmake related issues by writing a dinky little C# program called QMakeFix that will do things like convert 32-bit projects into 64-bit projects (it's quite easy using XPath). We also use it to clean up the generated projects (we find the default qmake include/source split stupid) and lets us do other handy things.
Presumably there's a way in Qt Creator to get aroudn the 32/64-bit thing but I don't know off hand.
Copy link to clipboard
Copied
Oh ! .. lot of stuff to handle for 64 bit stuff !
How are things at mac platform ?
XCode + CS6 SDK + Qt 4.8 , what is the counter part for QWinWidget and Visual Studio Addin ?
Copy link to clipboard
Copied
QMacNativeWidget
Copy link to clipboard
Copied
How about the Qt moc on Mac ?
On windows, visual studio addin does the moc'ing and uic'ing.
Who does this on mac ? How do we configure with xcode ?
Copy link to clipboard
Copied
We don't use the VS addin, we use qmake at the command line to generate projects. If you do that, it will add all the UIC & MOC steps for you. You do have to regenerate the project every time you add something that has the Q_OBJECT macro in it, but that's actually less of a pain then you'd think. We have a batch file that does the heavy lifting and a script on Mac to do the same.
Copy link to clipboard
Copied
Life is not simple with Qt + CS6 plugin for 64 bit. But thanx guys you made it relatively comfortable with these solutions
One query in this context .. even on MAC do we have to compile for 32 and 64 bit CS6 separately ?
Copy link to clipboard
Copied
It depends on what targets you're htiting. There's no 32-bit CC or CS6 (I think) on Mac. So I don't believe there's any version that requires 32-bit and 64-bit on Mac, its just one or the other.
Now if only they'd do the same on PC and drop 32-bit!
Copy link to clipboard
Copied
I like to reopen this issue because, although made lots of progress with Qt from this thread, but still have major issues, hope you can help.
I develop for CS6 and CC on Mac. Got a few button (including Qt generated white background) to displayed on AIPanel after AI boots, but AI main top menu bar menu items disappeared,
Screen shot:
then AI crashed with this dump in Xcode:
#0 0x000000011f27614d in QHashData::nextNode(QHashData::Node*) at /temp/qt4.8.5src/src/corelib/tools/qhash.cpp:294
#1 0x000000011f662cd7 in QHash<QWidget*, QHashDummyValue>::const_iterator::operator++() at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qhash.h:427
#2 0x000000011f662d10 in QSet<QWidget*>::const_iterator::operator++() at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qset.h:155
#3 0x000000011f664334 in QSet<QWidget*>::toList() const at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qset.h:303
#4 0x000000011f64c860 in QApplication::allWidgets() at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:2180
#5 0x000000011f64c8a6 in QApplication::topLevelWidgets() at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:2154
#6 0x000000011f6056b0 in findWindowThatShouldDisplayMenubar at /temp/qt4.8.5src/src/gui/widgets/qmenu_mac.mm:1976
#7 0x000000011f60f52d in QMenuBarPrivate::macUpdateMenuBarImmediatly() at /temp/qt4.8.5src/src/gui/widgets/qmenu_mac.mm:2070
#8 0x000000011f5936f5 in -[QCocoaMenuLoader qtUpdateMenubar] at /temp/qt4.8.5src/src/gui/kernel/qcocoamenuloader_mac.mm:229
#9 0x000000011f595352 in -[NSApplication(QApplicationIntegration) qt_sendPostedMessage:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaapplication_mac.mm:126
#10 0x000000011f5950d3 in -[NSApplication(QApplicationIntegration) qt_filterEvent:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaapplication_mac.mm:150
#11 0x000000011f594ded in -[QNSApplication qt_sendEvent_replacement:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaapplication_mac.mm:177
#12 0x0000000108612145 in -[DVAMacApplication sendEvent:] ()
#13 0x0000000108e981cc in -[ExoMacApplication sendEvent:] ()
#14 0x00007fff9246b21a in -[NSApplication run] ()
#15 0x0000000108e96807 in exo::app::OS_AppBase::RunEventLoop() ()
#16 0x000000010075b698 in 0x10075b698 ()
#17 0x00000001006ff385 in 0x1006ff385 ()
#18 0x00000001006ef5d4 in 0x1006ef5d4 ()
#19 0x00000001001635f8 in 0x1001635f8 ()
It seems Qt is messing around with the menu bar as seen above. How to avoid this problem?
Thanks
Copy link to clipboard
Copied
write :
QApplication::setAttribute(Qt::AA_MacPluginApplication); |
before creating object of QApplication. This will solve the menu issue.
This line basically informs Qt's event loop that Qt event loop is not the only event loop in the application. The AI event loop is also the major one.
Copy link to clipboard
Copied
Thank you very much!
That solve that problem, but AI only boot 1 in a few times.
Most of the time it crashes before AI boots.
I guess I need to investigate using qt as a plugin now that you mentioned it.
I will get back with more question, I am sure, once I have spent more time investigating the remaining problems.
But, right now, here is what I have so far (please let me know if spot anything strange):
By the way, I compiled and used Qt as a static lib. The end .aip is not small compared to the old ADM method.
At plugin startup:
QApplication::setAttribute(Qt::AA_MacPluginApplication);
g->qtApp = new QApplication(argc, argv);
AIPanelPlatformWindow dlgHnd = NULL;
error = sAIPanel->GetPlatformWindow(this->fPanel, dlgHnd);
g->pEditWidget = new qtEditWidget();
g->pEditWidget->sMenuItem->SetNotifyProc(g->pEditWidget->normalBtn, normalBtnClick);
g->pEditWidget->sMenuItem->SetNotifyProc(g->pEditWidget->relativeBtn, relativeBtnClick);
//set panel to contain qt stuffs
NSView* newView = (NSView*)g->pEditWidget->winId();
[dlgHnd setFrame:[newView frame]];
[dlgHnd addSubview:newView];
g->pEditWidget->show();
Copy link to clipboard
Copied
AI crash everytime a button on AIPanel is pushed with this dump:
I assume that we only responsible for connecting and processing of the button click since Qt::AA_MacPluginApplication was set previously. As shown below, the thread stop at QHashData::nextNode, what ever that mean, before the pushbutton event traverse up, but never got to my event handler. Ofcourse the qt connect method were tested out of AI successfully before introduced into it, so I can only say Qt is not as easy to work it.
#0 | 0x000000011f1ff2dd in QHashData::nextNode(QHashData::Node*) at /temp/qt4.8.5src/src/corelib/tools/qhash.cpp:294 |
#1 | 0x000000011f5ebe67 in QHash<QWidget*, QHashDummyValue>::const_iterator::operator++() at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qhash.h:427 |
#2 | 0x000000011f5ebea0 in QSet<QWidget*>::const_iterator::operator++() at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qset.h:155 |
#3 | 0x000000011f5ed4c4 in QSet<QWidget*>::toList() const at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qset.h:303 |
#4 | 0x000000011f5d59f0 in QApplication::allWidgets() at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:2180 |
#5 | 0x000000011f5d5a36 in QApplication::topLevelWidgets() at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:2154 |
#6 | 0x000000011f532270 in QEventDispatcherMac::flush() at /temp/qt4.8.5src/src/gui/kernel/qeventdispatcher_mac.mm:766 |
#7 | 0x000000011f3c4907 in QCoreApplication::flush() at /temp/qt4.8.5src/src/corelib/kernel/qcoreapplication.cpp:690 |
#8 | 0x000000011fe19e74 in QAbstractButton::mousePressEvent(QMouseEvent*) at /temp/qt4.8.5src/src/gui/widgets/qabstractbutton.cpp:1097 |
#9 | 0x000000011f6834a0 in QWidget::event(QEvent*) at /temp/qt4.8.5src/src/gui/kernel/qwidget.cpp:8385 |
#10 | 0x000000011fe1a1c6 in QAbstractButton::event(QEvent*) at /temp/qt4.8.5src/src/gui/widgets/qabstractbutton.cpp:1082 |
#11 | 0x000000011ff6e611 in QPushButton::event(QEvent*) at /temp/qt4.8.5src/src/gui/widgets/qpushbutton.cpp:683 |
#12 | 0x000000011f5cc5f2 in QApplicationPrivate::notify_helper(QObject*, QEvent*) at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:4562 |
#13 | 0x000000011f5cd99a in QApplication::notify(QObject*, QEvent*) at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:4105 |
#14 | 0x000000011f3c931a in QCoreApplication::notifyInternal(QObject*, QEvent*) at /temp/qt4.8.5src/src/corelib/kernel/qcoreapplication.cpp:953 |
#15 | 0x000000011f5ebd67 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:234 |
#16 | 0x000000011f5ddb95 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:3171 |
#17 | 0x000000011f528182 in qt_mac_handleMouseEvent(NSEvent*, QEvent::Type, Qt::MouseButton, QWidget*, bool) at /temp/qt4.8.5src/src/gui/kernel/qt_cocoa_helpers_mac.mm:1271 |
#18 | 0x000000011f50d1da in -[QCocoaView mouseDown:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaview_mac.mm:555 |
#19 | 0x00007fff9255950e in -[NSWindow sendEvent:] () |
#20 | 0x0000000105bfa558 in OWLRemoveObjCExceptionCallback () |
#21 | 0x0000000105bfc961 in OWLRemoveObjCExceptionCallback () |
#22 | 0x00007fff92555644 in -[NSApplication sendEvent:] () |
#23 | 0x000000011f51dfb6 in -[QNSApplication qt_sendEvent_replacement:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaapplication_mac.mm:178 |
#24 | 0x0000000108612145 in -[DVAMacApplication sendEvent:] () |
Copy link to clipboard
Copied
I implemented Qt as a GUI module inside an Adobe Illustrator Plugin for Mac OS X.
Half of the time, after boot up, the button click results in successful click event delivery. Once successful, it never failed, until next application reboots. When fails, it always crashes on the first button click and crashes at the execution of QApplication::flush(); inside QAbstractButton::mousePressEvent(QMouseEvent *e) function from qabstracbutton.cpp.
Do you handle any mouse event for button at all other than connect the button to a callback?
The following is code I written to instantiate QApplication and Qt GUI components to reside inside an container provided by Illustrator’s API:
GetPlatformWindow returns dlgHnd which is NSView of a GUI container.
pEditWidget is a QWidget class containing a few QPushButton.
SetNotifyProc calls Qt connect method to setup button click callback.
At startup Illustrator application loads the following codes which reside in a dll module. int argc; char **argv=NULL;
QApplication::setAttribute(Qt::AA_MacPluginApplication);
QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation);
g->qtApp = new QApplication(argc, argv);
AIPanelPlatformWindow dlgHnd = NULL;
sAIPanel->GetPlatformWindow(this->fPanel, dlgHnd);
g->pEditWidget = new qtEditWidget();
g->pEditWidget->sMenuItem->SetNotifyProc(g->pEditWidget->normalBtn, normalBtnClick);
g->pEditWidget->sMenuItem->SetNotifyProc(g->pEditWidget->relativeBtn, relativeBtnClick);
//set panel to contain qt stuffs NSView* newView = (NSView*)g->pEditWidget->winId(); [dlgHnd setFrame:[newView frame]]; [dlgHnd addSubview:newView]; g->pEditWidget->show();
After show(), the application show the buttons. When fail, always break in this mousePressEvent() function at event flush() function (Code from Qt 4.8.5 source):
void QAbstractButton::mousePressEvent(QMouseEvent *e)
{ Q_D(QAbstractButton); if (e->button() != Qt::LeftButton) { e->ignore(); return; } if (hitButton(e->pos())) { setDown(true); d->pressed = true; repaint(); //flush paint event before invoking potentially expensive operation
**********my note: after flush() EXE_BAD_ACCESS (code = 13, address = 0×0)**************** QApplication::flush(); d->emitPressed(); e->accept(); } else { e->ignore(); }
}
Here is the dump from within Xcode 4.6 in Thread 1:
Thread 1, Queue : com.apple.main-thread
#0 0×000000011f68298d in QHashData::nextNode(QHashData::Node*) at /temp/qt4.8.5src/src/corelib/tools/qhash.cpp:294
#1 0×000000011fa6f4d7 in QHash<QWidget*, QHashDummyValue>::const_iterator::operator++() at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qhash.h:427
#2 0×000000011fa6f510 in QSet<QWidget*>::const_iterator::operator++() at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qset.h:155
#3 0×000000011fa70b34 in QSet<QWidget*>::toList() const at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/tools/qset.h:303
#4 0×000000011fa59060 in QApplication::allWidgets() at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:2180
#5 0×000000011fa590a6 in QApplication::topLevelWidgets() at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:2154
#6 0×000000011f9b5900 in QEventDispatcherMac::flush() at /temp/qt4.8.5src/src/gui/kernel/qeventdispatcher_mac.mm:766
#7 0×000000011f847f97 in QCoreApplication::flush() at /temp/qt4.8.5src/src/corelib/kernel/qcoreapplication.cpp:690
#8 0×000000012029d4e4 in QAbstractButton::mousePressEvent(QMouseEvent*) at /temp/qt4.8.5src/src/gui/widgets/qabstractbutton.cpp:1097
#9 0×000000011fb06b10 in QWidget::event(QEvent*) at /temp/qt4.8.5src/src/gui/kernel/qwidget.cpp:8385
#10 0×000000012029d836 in QAbstractButton::event(QEvent*) at /temp/qt4.8.5src/src/gui/widgets/qabstractbutton.cpp:1082
#11 0×00000001203f1c81 in QPushButton::event(QEvent*) at /temp/qt4.8.5src/src/gui/widgets/qpushbutton.cpp:683
#12 0×000000011fa4fc62 in QApplicationPrivate::notify_helper(QObject*, QEvent*) at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:4562
#13 0×000000011fa5100a in QApplication::notify(QObject*, QEvent*) at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:4105
#14 0×000000011f84c9aa in QCoreApplication::notifyInternal(QObject*, QEvent*) at /temp/qt4.8.5src/src/corelib/kernel/qcoreapplication.cpp:953
#15 0×000000011fa6f3d7 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) at /temp/qt4.8.5src/src/gui/../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:234
#16 0×000000011fa61205 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) at /temp/qt4.8.5src/src/gui/kernel/qapplication.cpp:3171
#17 0×000000011f9ab812 in qt_mac_handleMouseEvent(NSEvent*, QEvent::Type, Qt::MouseButton, QWidget*, bool) at /temp/qt4.8.5src/src/gui/kernel/qt_cocoa_helpers_mac.mm:1271
#18 0×000000011f99086a in -[QCocoaView mouseDown:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaview_mac.mm:555
#19 0×00007fff9255950e in -[NSWindow sendEvent:] ()
#20 0×0000000105bfa558 in OWLRemoveObjCExceptionCallback ()
#21 0×0000000105bfc961 in OWLRemoveObjCExceptionCallback ()
#22 0×00007fff92555644 in -[NSApplication sendEvent:] ()
#23 0×000000011f9a1646 in -[QNSApplication qt_sendEvent_replacement:] at /temp/qt4.8.5src/src/gui/kernel/qcocoaapplication_mac.mm:178
#24 0×0000000108612145 in -[DVAMacApplication sendEvent:] ()
#25 0×0000000108e981cc in -[ExoMacApplication sendEvent:] ()
#26 0×00007fff9246b21a in -[NSApplication run] ()
#27 0×0000000108e96807 in exo::app::OS_AppBase::RunEventLoop() ()
#28 0×000000010075b698 in 0×10075b698 ()
#29 0×00000001006ff385 in 0×1006ff385 ()
#30 0×00000001006ef5d4 in 0×1006ef5d4 ()
#31 0×00000001001635f8 in 0×1001635f8 ()
This problem is repeatable and happens frequently (after few application boot ups).

