[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: Starting out in KDE and GUI Building
From:       lordSauron <lordsauronthegreat () gmail ! com>
Date:       2005-10-17 19:11:47
Message-ID: e5a3e9ac0510171211m130b99ddn9cf5e607a6101f53 () mail ! gmail ! com
[Download RAW message or body]

Others that repied after: I have read, just not saying anything.

On 10/17/05, Andreas Pakulat <apaku@gmx.de> wrote:
> On 16.10.05 21:50:05, lordSauron wrote:
> > On 10/16/05, Michael Pyne <michael.pyne@kdemail.net> wrote:
> > > On Sunday 16 October 2005 20:22, lordSauron wrote:
> > > The overall lifecycle of a KDE application is this:
> > >
> > > There is a function main() (usually in something like main.cpp or
> > > <appname>.cpp).
> >
> > Ha ha!  I knew you couldn't wrest main() from C++ - it's to C-ish.
>
> Actually not only C++ has a main function, also Java and in python you
> have a check wether you are in a main-function (here the main is
> implicit). I think there are few languages without a main function as
> the System relies on an entry point for executable code - it has to
> start somewhere, there needs to be a point to create a class instance
> and this is the main function.

Effectively main() but with a different name, correct?

> > the only thing they could do more is a index of all the various types
> > of cowpies (old Scouting joke...)
>
> Check the settings->configure konqueror and then the web-shortcuts Page,
> these are all XX: shortcuts konqueror knows about.
>
> > > The KApplication line is easy enough.  The KApplication is literally your
> > > application.  The GUI for it isn't created until you create the
> > > AppMainWindow, which means you could have a KDE app running without a main
> > > window for some reason although that's obviously not horribly useful.  It
> > > handles a lot of things for you such as setting up DCOP, loading settings,
> > > etc.
> >
> > Wait... so, I've already got main() in amino.cpp now (theoretically, I
> > haven't yet done that) and so now I'm creating my program app inside
> > of itself?  That sounds a bit strange to me...
>
> No, the template of kdevelop creates a file called main.cpp which is the
> one that has the main-function. Of course you could move that function
> into amino.cpp, but most of the time it's better held in its own file
> for clarity reasons.

so in my /amino/src area there's also a main.cpp?  I didn't notice it
if it was there...

> > > The AppMainWindow thingy is where things can start to change.  In this
> > > instance, AppMainWindow is a subclass of KMainWindow.  In this subclass you
> > > would handle creating the elements of your graphical interface, either by
> > > directly creating QWidgets and such, or by creating a class generated from Qt
> > > Designer.
> >
> > And that class extension happened in amino.cpp, correct?  With the
> > line amino :: amino() : KMainWindow (0, "amino") {
>
> Kind of, in C++ the .h and .cpp are both part of the extension as the
> interface is separate from the implementation. So basically extension
> takes place in both files - in the .h (the header) file you extend the
> super class by adding new functions and in the .cpp file you extend the
> super class by reimplementing the functions you inhrited.
>
> For your amino example, the line you quoted is just the first line of
> the constructor. The "real" extension are the 2 calls within the
> constructor call: setXMLFile and new QLabel. These two add functionality
> to your class which wasn't there in the KMainWindow class. If you leave
> those 2 statements out your amino class can't do anything else that
> KMainWindow can't do.

So it's like the Java practise of making an extension of a JFrame or
whatever it was (it's been a while) that's got all the little
customisations in it so it's not in the actual program, so it prevents
the program from being cluttered up with MyFrame.setTitle("MyFrame");
and rot like that?

> > > To setup your menus and toolbars you could use the XML-GUI system, which would
> > > allow you to use KDE's configurable shortcuts and such for yours users as
> > > well.
> >
> > Bam.  You just put the final nail in poor Java's pitiful UI tools.
> > They were great for learning the basics of UI design and how things
> > work on a higher level... but they were so rigid and um... database
> > oriented?  They will never go beyond the little miserable server apps
> > they were designed for.
>
> Have you haver seen Eclipse? Or Websphere Studio? Or JBuilder? Or
> SunONE? Of course those are all IDE's but I think there are quite a
> bunch of non-DB-Java apps out there. Oh, I got 2: jabref - a tool to
> handle bibtex files and argouml - a uml modeller.

I've tried JBuilder, and that weird free one from Sun.  Never tried
Eclipse (though I hear it's good) and never heard of SunONE, though I
thought Websphere was from IBM...

> > However, I would have never thought of stuffing that content in an XML
> > file... that's brilliant.
>
> There is no real content in the XML file, I think the idea is great but
> KDE didn't really use it to it's full extent. All there is in the xml
> file is the structure of the menus and for each item an action with a
> name. That's all. What this action looks like, what text it has, what it
> does all this is still done in code, by creating an instance of the
> KAction class.

It's better than Java's annoying way of doing things.

> > > To let your KApplication know which GUI widget is the main one, you use the
> > > setMainWidget() call, and then make sure to show() the widget since it isn't
> > > shown by default.
> >
> > What's the importance of knowing which widget is the main one???  I
> > can't think of a reason (though there's probably a really big fat
> > hairy obvious one just on the other side of my horizon of
> > understanding...)
>
> Because else KApplication doesn't know when to stop ;-) KApplication
> get's notified when the main widget is closed and then ends it's
> execution. Now I don't know all the nitty gritty details, but AFAIK the
> exec() call starts the event loop, which is happening in KApplication,
> not the main widget. If you don't set the main widget then you can close
> all your windows and still the program doesn't end it's execution - not
> very good. The next thing is that when you hide the main widget you
> almost always want to hide any window that belongs to it...

Ah.  But you can still hide the main widget without getting your app
terminated, right?

> > > Finally you turn the program execution over to KApplication by calling exec().
> > > KApplication then controls the event loop and basically makes everything
> > > tick.
> >
> > So then how do I tell it what to do mid-execution?  I think I've got
> > the getting the KMainWindow part down, but then you return app.exec()
> > and that should kill your main() function, and your control over the
> > program, right?
>
> But app.exec() starts the event loop, which is happening in Java too,
> but more implicit. This only returns when the main widget is closed.
> From there you have 3 options to "do something mid-execution":
> 1. Use function calls to other UI-objects - this should be familiar to
> you as this is a general OO-thing
>
> 2. Use signals/slots - this is a technique done by the Qt framework
> which lets you connect signaling functions with slot-functions and when
> the signal is send out all connected slots get executed right away. More
> on this can be found in the Qt documentation available from the
> assistant program
>
> 3. normal Events - you still have the possibility to send out events and
> have a event handler that handles them, but I think in KDE/Qt this is
> most often used when communicating between different Threads.

So I'm orchestrating things through the equivalent of a Java ActionEvent?

> > > > So, for my first mind-numbingly simple question, what's going on?
> > > > This is the nice and dainty little program the template made for me:
> > >
> > > > amino :: amino() : KMainWindow (0, "amino") {
> > > >     // set the shell's ui resource file
> > > >     setXMLFile("aminoui.rc");
> > >
> > > This line is the interface to the XML-GUI system.  You would populate
> > > <appname>ui.rc (which is an XML file) to form the menus and toolbars you want
> > > to make available to the user.
> > >
> > > Every menu item and toolbar button has a corresponding KAction created in your
> > > code.  This is how the menus and toolbars become configurable with no cost to
> >
> > But my app was just terminated in the return exec(), right?  So then
> > how does that function call work?
>
> You can always check the source ;-) The exec() function starts a loop
> which does nothing most of the time and executes event handlers and
> slots the rest of it. For example if you click on a menu or toolbar
> item a corresponding slot is executed, which one is normally defined
> during the creation of the corresponding KAction.

Oh, so the constructor returned that, but main is still going strong,
am I correct?

> > > you.  As long as you create a KAction for every action that your program can
> > > perform (and KDE provides a few "standard actions" as well, see KStdAction),
> > > your users can add it to their menu or toolbar even if you don't have it
> > > there by default.  Or users can remove things that they don't use.
> >
> > Oh, we're talking about menubar items, right?
>
> Not only, a KAction is something that can sit in a menubar, in a toolbar
> or in a popup-menu all at the same time. This way you don't have
> separate MenuItem, ToolbarItem, PopupItem classes, but only "one to rule
> them all" ;-) Also you only have to define what to do when clicking any
> of these items once, by telling the KAction which slot is to be executed
> in that case. You see signals/slots are a fundamental thing in KDE/Qt
> programming. I know that there is really _much_ to learn when beginning,
> so I'd really encourage you to first read up on the Qt tutorial and
> documentation.

Clever.  'Cause in Java you'd have perhaps 4 different things pointing
to the same stupid ActionEvent.

> > > In order to coordinate KActions with the menus and toolbars, a
> > > KActionCollection is needed, but you can use the one provided by your
> > > KMainWindow (KMainWindow::actionCollection()).
> >
> > No clue what that is... I'll try to decipher what the API says later
> > tomorrow (it's getting really late at night) but don't be suprised if
> > I pop up again asking what that's all about.
>
> Don't think about that too much, as long as you're in the learning
> phase, just remember to call actionCollection() to use the one provided
> by KMainWindow. Basically this thing does nothing else than collecting
> all the KActions and showing only the menu items/toolbar items that it
> has in it's collection.

So in short it's at least comparable to a Java ActionEvent, correct?

> > > >     new QLabel( "Hello World", this, "hello label" );
> > >
> > > This creates a GUI element in the code.  In this case, it's QLabel, created as
> > > a child of the KMainWindow subclass (this) with text of "Hello World".
> >
> > You mean the window title?
>
> No, you have a full blown KMainWindow with a menu and a toolbar and so
> on. The QLabel is just below the toolbar (or at least it should be). The
> text should be displayed below the toolbar. The window title is set by
> the KAboutData object.

So this is just a little label that floats somewhere around the top
left corner of the window? I could remove that without sending some
binaries to an early grave?

> > > > #include "amino.moc"
> > >
> > > This line is important for any object which descends directly or indirectly
> > > from QObject (or QWidget).  It includes the automatically generated code that
> > > Qt creates in order to handle its signals/slots system, along with many other
> > > things that Qt can use moc for.
> > >
> > > If you had a class defined in a foo.h file that was descended from QObject,
> > > you would start the class definition off with the line Q_OBJECT, and then
> > > #include "foo.moc" in the corresponding foo.cpp file.
> >
> > Sounds like something I don't need to know about at the moment, right?
>
> You basically never want to know about what's going on behind the scenes
> with Q_OBJECT and the .moc file. Those just create the "glue" to make
> signals/slots and the QObject inheritance tree work. I certainly don't
> know much about it and I don't want to anyway - this part just works
> nearly all the time. And the .moc-file has "generated" code anyway, so
> there's not really a way to change that code.

Thanks heavens.  This stuff is complex as it is.

> > > > I have no clue why it needs to include amino.h
> > >
> > > amino.h contains the interface definition of the class.  You see, unlike Java,
> > > where the implementation happens right with the interface, in C++ the
> > > interface of a class is different from its implementation.  There are a few
> > > reasons for this, but basically it's historical.
> >
> > So that's the interface so that it can work correctly with other Qt
> > widgets and things?
>
> Right. Other "things" just have to know this interface - what functons
> this class prvides what signals and slots and then can work with it.
>
> > > > I also don't understand
> > > > the part about making a new QLabel...  It's unnamed (as a object is, I
> > > > think...)
> > >
> > > It wasn't unnamed.  The third parameter held the object name ("hello label")
> >
> > Oh.  I've only ever seen things named outside of the parameters.
>
> What you probably mean is that this QLabel cannot be easily changed
> during runtime as you don't have a variable pointing to it. For QLabels
> this is common, as most of the time they just present some text or icon
> that won't change. So there's no need to store them twice (they are
> already stored once in the QObject-inheritance-tree, behind the scene),
> by having a variable that points to them.

Okay, so just don't worry about it it's fine.  How would I remove such
an annonymous object?  Is there some kind of
KMainWindow->remove("hello label"); or something like that?

> > > > and I've absolutely no idea how this all fits into program
> > > > control flow.
> > >
> > > It's how I described it before.  Find the main() function, and you'll find
> > > that it is creating an instance of amino there.
> > >
> > > > So if any of you are up to a small and painfully detailed and simple
> > > > crash-course in basic widget-ology pertaining to KDE, I'd really
> > > > appreciate it.
> > >
> > > The best way to learn about widgets might be to first take a tour of Qt
> > > Designer and explore the widget types (and get familiar with layouting, which
> > > is a very nice Qt feature).
> >
> > I think I'll do that, in spite of my horrid track record with GUI
> > buiders (I made JBuilder 2k5 Foundation do some pretty scary things
> > before I threw it out like an old sack of potatoes)
>
> I don't really like those GUI designers, apart from the QT designer.
> Don't get me wrong creating GUI's by putting together some widgets is
> really time saving, but the approach of the Java-things is just wrong.
> Qt-designer lets you create parts of your application as widgets made up
> of simpler widgets. You can then combine them either within another
> widget or by code within the main window. That approach is much better,
> because you don't screw up your UI so easily.

The whole Java approach to GUIs is just wrong.  They shove you through
all of these garbage things like JFrame.show(); and stuff that goes on
for pages that does so little... the least they could do is make it
interesting and change it around a bit to look more visually
intimidating...  I went into a coma about halfway through one program
once.

> > > Also, something to keep in mind is that KDE is very Qt-ish in nature (which
> > > makes sense I think), so the Qt tutorial which you can find by using the
> > > "assistant" program included with the Qt development Kit might be useful as
> > > well.
> >
> > Ok, so I should keep on the lookout for Qt things, since KDE is built
> > similarly to Qt.
>
> Not only similarly but also on top of. For example almost all KDE
> widgets have a QWidget* parent parameter in the constructor, QWidget is
> a class from the Qt framework.

Okay, like how java.swing.* was built atop java.awt.*?

--
=== GCB v3.1 ===
GCS d-(+) s+:- a? C+(++++) UL+++(++++) P L++(+++)
E- W+(+++) N++ w--- M>++ PS-- PE Y+ PGP- t++(+++) 5?
X? R !tv>-- b++>++++ DI+++>++++ D-- G !e h(*) !r x---
=== EGCB v3.1 ===
 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic