Read the source code.
In this case, read QPrintPreviewDialog source code to see how it does it. This standard dialog has navigation buttons and a current page display, so it kind of does what you want (that is, if I really understood what you want to accomplish). The methods you're looking for are the following (src/gui/dialogs/qprintpreviewdialog.cpp):
void QPrintPreviewDialogPrivate::_q_previewChanged()
void QPrintPreviewDialogPrivate::_q_navigate(QAction* action)
void QPrintPreviewDialogPrivate::updateNavActions()
Basically, _q_previewChanged() is connected to QPrintPreviewWidget::previewChanged() signal. When it is emitted, the page number is updated with information acquired from QPrintPreviewWidget::currentPage() and QPrintPreviewWidget::pageCount().
As for extending the behavior of QPrintPreviewWidget you can try two approaches, both of them do not require a tailored version of Qt:
Extend QPrintPreviewWidget
In the constructor, access the layout() (it is a QVBoxLayout that is used interanally), add the footer widget, connect the previewChanged() signal to a slot that updates the page number and be done. The problem with this approach is that it counts on the layout to be present and be a QVBoxLayout. Since this is somehow private, it can break with newer versions.
Create a new class extending QWidget or QFrame
If you don't require your widget to be a QPrintPreviewWidget, just create a new QWidget derived class and add the print preview widget and the footer to a layout, connects slots etc. Use your derived widget instead of QPrintPreviewWidget.
Now, if you want to modify the behavior of the widget on already deployed binaries, things get uglier. I cannot help in this case.