Results 1 to 6 of 6

Thread: ui_....h issue

  1. #1
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default ui_....h issue

    Hi,

    I've started a new Qt library project in Visual Studio 2005 and Qt 4.3.2.
    I've create a new solution with a Qt library template, created a Qt Gui class and put the macro for exporting the class I want to expose to the win32 world. I'm getting a .lib with my dll and everything's cool in that respect.

    I also created a tester gui application to test out my dll's ui controls.
    The dll exports 'ProcessDesigner' which is defined in 'processdesigner.h'.
    As soon as I #include this header in my tester application, I get the following error 3 times:
    Error 1 fatal error C1083: Cannot open include file: 'ui_processdesigner.h': No such file or directory D:\SourceRepository\Imaging Tools\ImagingSystemTools\ProcessDesigner\processde signer.h 7
    Given that the ui_ file is auto generated and linked into the dll, why is the gui application running a muck?

    I've used this structure a few times, but it was a while ago now, so my memory on things might be lacking a little.

    I've attached the solution for your examination.

    Thanks
    Attached Files Attached Files
    Last edited by jacek; 15th November 2007 at 13:29. Reason: changed [code] to [quote]

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ui_....h issue

    You have #include "ui_processdesigner.h" directive in processdesigner.h. Either you have to distribute that file too (which isn't a good idea) or you have to change your code in such way that would allow you to move that #include directive to a .cpp file. For example you can change ProcessDesigner::ui into a pointer and use forward declaration or use the pimpl pattern.

    Edit: Since it's going to be a library, the pimpl is the best approach.
    Last edited by jacek; 15th November 2007 at 14:13. Reason: typo

  3. #3
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ui_....h issue

    Actually thinking about this further, I've never linked to a dll that had a Qt UI subclass as it's entry point, so that's probably why I'm having this issue.
    I could always use a static create function I guess.

    Thanks for your suggestions Jacek, I'll do some experimenting.

  4. #4
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ui_....h issue

    Hi again,

    I have to confess that I'm getting lost trying to do this.
    I've followed the PIMPL exercise in Herb Sutter's book and come up with the VS solution I've attached to this post.

    My goal is to create a subclass of QFrame which which will have a QGraphicsView among other controls. I need to be able to use this class from many applications, so a Qt Library is the way to go.
    The way I see it, is that I need to use a PIMPL approach so as to hide the #include "ui_..." line so that the client of the library doesn't end up including a file not in it's search path so that it can compile.

    So this is what I've done so far:
    Qt Code:
    1. // processdesigner_impl.h
    2. #include <QFrame>
    3. #include "ui_processdesigner.h"
    4.  
    5.  
    6. class ProcessDesignerImpl : public QFrame
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. ProcessDesignerImpl(QWidget *parent = 0);
    12. ~ProcessDesignerImpl();
    13.  
    14. private:
    15. Ui::ProcessDesignerClass ui;
    16. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // processdesigner_impl.cpp
    2. #include "processdesigner_impl.h"
    3.  
    4.  
    5. ProcessDesignerImpl::ProcessDesignerImpl(QWidget *parent)
    6. : QFrame(parent)
    7. {
    8. ui.setupUi(this);
    9. }
    10.  
    11. ProcessDesignerImpl::~ProcessDesignerImpl()
    12. {
    13.  
    14. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // ProcessDesigner.h
    2. #include "processdesigner_global.h"
    3. #include <QWidget>
    4.  
    5. class PROCESSDESIGNER_EXPORT ProcessDesigner : public QWidget
    6. {
    7. Q_OBJECT
    8.  
    9. public:
    10. ProcessDesigner(QWidget* parent = 0);
    11.  
    12. private:
    13. class ProcessDesignerImpl;
    14. ProcessDesignerImpl* procDesImpl;
    15.  
    16.  
    17. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // ProcessDesigner.cpp
    2.  
    3. #include "ProcessDesigner.h"
    4. #include "processdesigner_impl.h"
    5.  
    6. ProcessDesigner::ProcessDesigner()
    7. {
    8. //procDesImpl = new ProcessDesignerImpl(parent);
    9. }
    To copy to clipboard, switch view to plain text mode 

    This was compiling at one point (or maybe a slight variation) but now I'm getting these errors:
    Error 3 error LNK2001: unresolved external symbol "public: virtual int __thiscall ProcessDesignerImpl::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@ProcessDesignerImpl@@UAEHW4Call@QMet aObject@@HPAPAX@Z) processdesigner_impl.obj
    Error 1 error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall ProcessDesignerImpl::metaObject(void)const " (?metaObject@ProcessDesignerImpl@@UBEPBUQMetaObjec t@@XZ) processdesigner_impl.obj
    Error 2 error LNK2001: unresolved external symbol "public: virtual void * __thiscall ProcessDesignerImpl::qt_metacast(char const *)" (?qt_metacast@ProcessDesignerImpl@@UAEPAXPBD@Z) processdesigner_impl.obj
    Error 4 fatal error LNK1120: 3 unresolved externals D:\SourceRepository\Imaging Tools\ImagingSystemTools\Debug\ProcessDesigner.dll

    I'm not sure where to turn next.
    Part of my confusion lies in the fact the ProcessDesigner needs to be able to be placed on another dialog, so I need to subclass it as well. If I just subclass QWidget, then I can see that I'll have to create a one-to-one mapping on every custom function I want to expose on the ProcessDesignerImpl, because if I subclass from ProcessDesignerImpl I'll be back where I started.

    The real question is, how do I actually return a ProcessDesignerImpl to the client?
    I was thinking about maybe casting "procDesImpl back to a basic QWidget then returning that somewhow, or maybe the key lies in the client passing "this" into the constructor of ProcessDesigner, then that pointer gets passed into ProcessDesignerImpl, then use in the setupUp line like this:
    Qt Code:
    1. ui.setupUi(parent);
    To copy to clipboard, switch view to plain text mode 

    First I need to resolve these linking errors in the attached solution, then decide how to proceed. Can anyone offer any suggestions?


    Regards,

    Steve York
    Attached Files Attached Files
    Last edited by jacek; 26th November 2007 at 15:48. Reason: changed [code] to [quote]

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: ui_....h issue

    Wow... hmm... strange solution... how about:

    Qt Code:
    1. #ifndef __FRAME_H
    2. #define __FRAME_H
    3. #include <QFrame>
    4. class FramePrivate;
    5. class Frame : public QFrame {
    6. public:
    7. Frame(QWidget *parent=0);
    8. ~Frame();
    9. private:
    10. FramePrivate *d;
    11. };
    12. #endif
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. #include "frame.h"
    2. #include "ui_frame.h"
    3. struct FramePrivate {
    4. Ui::Frame ui;
    5. };
    6.  
    7. Frame::Frame(QWidget *parent) : QFrame(parent), d(new FramePrivate){
    8. d->ui.setupUi(this);
    9. }
    10.  
    11. Frame::~Frame(){ delete d; }
    To copy to clipboard, switch view to plain text mode 

    This way the only place where you include the ui_xxx.h file is the implementation file and only the private class (P-IMPL) that is defined there needs the Ui component.

  6. The following user says thank you to wysota for this useful post:

    stevey (27th November 2007)

  7. #6
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ui_....h issue

    Ok, after extensive analysis, I believe I see the light now.
    That's what I love (or hate) about C++, there's ALWAYS some new concept to learn
    Just learning about forward declaration has been a good lesson. I've seen it before, but never been forced to implement it.
    Much reading of sutter's book ahead.

    Thanks heaps.

Similar Threads

  1. Qt layout issue
    By bunjee in forum Qt Programming
    Replies: 6
    Last Post: 15th August 2007, 19:43
  2. QSocketNotifier Issue
    By TheGrimace in forum Qt Programming
    Replies: 6
    Last Post: 18th July 2007, 21:29
  3. qt3 to qt4 - uic issue
    By hvengel in forum Qt Programming
    Replies: 10
    Last Post: 4th March 2007, 02:59
  4. Database access issue
    By Gayathri in forum Newbie
    Replies: 3
    Last Post: 23rd November 2006, 07:41
  5. Replies: 5
    Last Post: 22nd September 2006, 08:04

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.