DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions

Replacing the View Widget

[ Previous: Refactoring Existing Code ] [ Home ] [ Next: Replacing the Print Dialog ]

We are ready to start replacing the View widget. However, our example program uses the XmNotebook widget class. Qt does not provide a direct equivalent of this class, so we are faced with three possibilities, each with several advantages and disadvantages.

  1. We can continue the conversion using existing Qt widgets.

  2. We can write a new QWidget subclass that is identical to the XmNotebook widget class.

  3. We can leave the XmNotebook widget untouched.

We will use the first approach to complete the migration of the example project used in this walkthrough, using QTextEdit, QLabel and QSpinBox to provide a similar look. The only difference is that we will not have tabs.

We use Qt Designer to add the QTextEdit, QLabel and QSpinBox widgets to the Main Window widget.

Data Structure Modifications

The Page struct contains majorPB and minorPB members which need to be removed.  These members correspond to the tabs displayed in the existing version. The new version will not have any tabs, so we remove them.


Code Modifications

Most of the existing functions in our application need to be modified to work with the new View widget. The MainWindow class has five new functions that correspond to existing functions.

Existing Function New Function
void SetPage( int ) void MainWindow::setPage( int )
void PageChange( ... ) void MainWnidow::pageChange( int )
void TextChanged( ... ) void MainWnidow::textChanged()
void ReadDB( char * ) void MainWindow::readDB( char * )
void SaveDB( char * ) void MainWindow::saveDB( char * )

The SetPage() function implementation is moved to the MainWindow::setPage() function in mainwindow.ui.h. We remove the SetPage() function declaration and implementation from page.h and actions.cpp, respectively. In order to make MainWindow::setPage() work correctly, we need to modify the code to use the new widgets in our Main Window widget.


First, we set the current value of the spinbox to the current page number.


Next, we set the current text and cursor position of the textedit to the contents of the current page.


If the current page has a custom label, we set it as the current text of the textlabel; otherwise we set the textlabel contents to "Page X" (where X is the current page number).


If the current page has major and/or minor tab text, we append these to the labeltext. This ensures that all information entered by the user remains visible.


We should continue to handle the possibility that the current page does not exist. In this case, we clear the contents of the textedit widget and set the textlabel contents to the current page number (with an indication that the page is invalid).


The PageChange() function is moved from todo.cpp to the MainWindow::pageChange() function in mainwindow.ui.h. As with the MainWindow::setPae() function, we need to modify the code to use the new widgets in our Main Window widget.

Note: QTextEdit::text() returns a QString, which needs to be converted into a normal char* array. To do this we create a copy of the string in the local encoding. We need to make the copy using qstrdup() because the data contained in the QCString returned by QString::local8Bit() is deallocated when the QCString is destroyed.


The TextChanged() function does nothing more than set the modified variable to 1. Our new MainWindow::textChanged() function does exactly the same.


Since both the MainWindow::pageChange() and MainWindow::textChanged() functions access the modified global variable, we add a forward declaration at the top of mainwindow.ui.h.

The ReadDB() and \s SaveDB() implementations in io.cpp are renamed to MainWindow::readDB() and MainWindow::saveDB(), respectively. We need to modify the code in order to make the code work properly.

First, We add #include statements for the MainWindow, QSpinBox and QTextEdit classes.


The new MainWindow::readDB() and MainWindow::saveDB() functions will not use any Xt/Motif functions, so we remove the Xt/Motif #include statements and the global variables notebook and textw. These functions remain largely unchanged, maintaining compatibility with previous versions. Also, the ReadDB() and SaveDB() functions have been converted into MainWindow member functions, so we can pass this as the parent argument to the QMessageBox functions.


After reading the file in the MainWindow::readDB() function, we set the current and maximum values of the spinbox to the appropriate values.


In the MainWindow::saveDB() function, we need to store the text currently displayed, so we use QTextEdit::text() instead of XmTextGetString(). Note: QTextEdit::text() returns a QString, which needs to be converted into a normal char* array. To do this we create a copy of the string in the local encoding. We need to make the copy using qstrdup() because the data contained in the QCString returned by QString::local8Bit() is deallocated when the QCString is destroyed.


Due to the removal of the majorPB and minorPB members from the Page struct, the FixPages() function in actions.cpp is no longer needed. We remove the implementation and forward declaration of FixPages() from actions.cpp and page.h, respectively. Calls to FixPages() are removed from the MainWindow::selNewPage() and MainWindow::selDeletePage(), both of which are in mainwindow.ui.h.

We move AdjustPages() to mainwindow.ui.h and make it static, since it is only used in this file. We remove the forward declaration from page.h as well.

After our modifications, the actions.cpp file is empty. We remove it from our project file and regenerate our Makefile.

Now that we have implemented our new View widget, we need to remove the old Motif based view widget from todo.cpp.

Since we will not be using any Motif widgets, we remove all Motif #include statements, including qmotifwidget.h.


We also remove the forward declarations of the ReadDB() function and the notebook, textw and labelw global variables.


Next, we remove the center widget, which uses QMotifWidget. The Main Window widget and View widget are contained entirely in our MainWindow class, so no extra initialization is needed after creating the mainwindow widget.


Since the ReadDB() and SetPage() functions have been changed into MainWindow member functions, we need to call them using our mainwindow instance.


The View widget has now been replaced. After building our project, we confirm that the application works correctly.

[ Previous: Refactoring Existing Code ] [ Home ] [ Next: Replacing the Print Dialog ]


Copyright © 2007 TrolltechTrademarks
Qt 3.3.8