GLWidget
You'll quickly notice that there is no option for placing a GLWidget on the canvas, especially not your GLWidget. You can actually create a plug-in for the designer that will put your Custom Widget into the designer menu. For this lab, that's more trouble than it's worth. Instead, drag a Frame onto your canvas. Right click on it and select "Promote to Custom Widget". Fill out the appropriate values. Unfortunately, the QGLWidget does not inherit from QFrame. So you need to make sure the designer doesn't try to set any QFrame specific values. Specifically, if you look at the "Property Editor", you'll see that frameShape and frameShadow are both bolded. That means the value is not the default value. Select both and click the little red arrow on the side to make the value revert to default (NoFrame and Plain).
Other widgets
Drag and drop the necessary widgets onto your canvas. QLabels are nice for labeling your widgets.
Layouts
There are three kinds of layouts: Horizontal, Vertical, and Grid (there are also Splitters which are sort of like Layouts). The difference is obvious. You can either drag layouts onto the canvas and then drag other widgets into them, or you can select a number of widgets and then click the appropriate layout button. You need to have your widgets in layouts to make sure that the right things happen when you resize the window or other events happen. Use layouts liberally. Use spacers to keep your widgets from cramping together or spreading about too much. The provided example image is not, by any means, ideal, but it more or less gives a visual summary of what you need.
Create a new directory for this lab and save the .ui file to it.
Using your New Interface
Assuming you didn't rename the files from the example code we used in the last lab, copy main.cpp, glwidget.h, and glwidget.cpp over to your new directory. Now you need to create a class that will use the object layout you created with the designer. There are a few ways. You could learn a lot about it in the on-line documentation. Because it can be a hassle, however, here's code for the most common:
MainWindow.h file
#ifndef __MAINWINDOW_H
#define __MAINWINDOW_H
//This file will be generated automatically,
//assuming you didn't change the objectName of
//your main form in the designer.
#include "ui_MainWindow.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
public:
Ui::MainWindow ui;
};
#endif
MainWindow.cpp file
#include "MainWindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//Connect the SIGNALS and SLOTS here
}
You'll have to change main.cpp to #include and instantiate your MainWindow class instead of Window. I think you can handle that. With these six files (3 .cpp, 2 .h, and a .ui in a pear tree) you should be able to get your code to compile:
qmake -project QT+=opengl -o myProject.pro
qmake myProject.pro
make
Event Handling
Generally, programs handle events with interupts which generate messages that are then processed by a message loop. QT does that too, but it is mostly abstracted away with SIGNALS and SLOTS. You should have already learned about that during the last lab while you were dutifully going through the tutorials. After the exectuing the ui.setupUi function, the ui member of your MainWindow class provides access to all the variables you created with the designer. For example, if you created a menu item and set its objectName to "actionExit" and wanted to make clicking on that menu item close the program, you would use:
connect( ui.actionExit,SIGNAL(triggered(bool)),this,SLOT(close()) );
You'll need to create slots and connect them to signals as appropriate to complete the requirements. Mouse-events are handled with a callback instead of a SLOT, but you should already have one functional from the sample code we used. You just need to tweak it so that when you click on the screen, you leave a marker behind. Tie the scroll bars to these markers so that you can move them around. Note that this is probably the hardest part of the lab. We used gluSphere to create markers, but you can use whatever you want. You'll have to use the perspective information and the scroll bars to decide where to draw the markers. Ask questions. Help each other.