QWorkspace for Qt 5

  • I had the problem to port my Applications from QWorkspace to QMdiArea to use Qt 5, it does not work for me. I spent about 5 days to port QWorkspace to QMdiArea, then I gave up.

    I took QWorkspace from Qt 4.8.5 and put it in my own application gui dll. One problem is inside (see source), but I found a workaround. If one can use this, here is the source:

    I tried to show the source, but this post has a limit of 6000 chars, I did not found any way to send a zip file to the forum. So I show the Header first. If anyone give me a info how to send a zip, I'll do this...

    ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
    ** Contact: http://www.qt-project.org/legal
    ** This file is part of the QtGui module of the Qt Toolkit.
    ** Licensees holding valid Qt Enterprise licenses may use this file in
    ** accordance with the Qt Enterprise License Agreement provided with the
    ** Software or, alternatively, in accordance with the terms contained in
    ** a written agreement between you and Digia.
    ** If you have questions regarding the use of this file, please use
    ** contact form at http://qt.digia.com
    ** Modified for Qt 5 by Peter Bienert, Soft-Nrg Development GmbH Erlangen
    ** To use it, use the following statements for the pro-File
    ** greaterThan(QT_MAJOR_VERSION, 4): HEADERS += qworkspace/qworkspace.h
    **g reaterThan(QT_MAJOR_VERSION, 4): SOURCES += qworkspace/qworkspace.cpp
    ** greaterThan(QT_MAJOR_VERSION, 4): INCLUDEPATH += $$[QT_INSTALL_HEADERS]/QtWidgets/$$[QT_VERSION]/QtWidgets/
    ** greaterThan(QT_MAJOR_VERSION, 4): INCLUDEPATH += INCLUDEPATH *= $$PROGDIR/scdll/qworkspace/
    ** and use a construct like this to add it to a dll...
    **#ifndef NO_DLL_USE
    ** #ifdef YOUR_DLL
    ** #else
    ** #pragma comment(lib , "yourlib.lib")
    ** #endif
    ** #define SCBASE_EXPORT

    #ifndef QWORKSPACE_H
    #define QWORKSPACE_H

    #include "sc_dll.h"

    #include <QtWidgets>




    #ifndef QT_NO_WORKSPACE

    class QAction;
    class QWorkspaceChild;
    class QShowEvent;
    class QWorkspacePrivate;

    class SCBASE_EXPORT QWorkspace : public QWidget
    Q_PROPERTY(bool scrollBarsEnabled READ scrollBarsEnabled WRITE setScrollBarsEnabled)
    Q_PROPERTY(QBrush background READ background WRITE setBackground)

    explicit QWorkspace(QWidget* parent=0);

    enum WindowOrder { CreationOrder, StackingOrder };

    QWidget* activeWindow() const;
    QWidgetList windowList(WindowOrder order = CreationOrder) const;

    QWidget * addWindow(QWidget *w, Qt::WindowFlags flags = 0);

    QSize sizeHint() const;

    bool scrollBarsEnabled() const;
    void setScrollBarsEnabled(bool enable);

    #ifdef QT3_SUPPORT
    QT3_SUPPORT_CONSTRUCTOR QWorkspace(QWidget* parent, const char* name);
    QT3_SUPPORT void setPaletteBackgroundColor(const QColor &);
    QT3_SUPPORT void setPaletteBackgroundPixmap(const QPixmap &);

    void setBackground(const QBrush &background);
    QBrush background() const;

    void windowActivated(QWidget* w);

    public Q_SLOTS:
    void setActiveWindow(QWidget *w);
    void cascade();
    void tile();
    void arrangeIcons();
    void closeActiveWindow();
    void closeAllWindows();
    void activateNextWindow();
    void activatePreviousWindow();

    bool event(QEvent *e);
    void paintEvent(QPaintEvent *e);
    void changeEvent(QEvent *);
    void childEvent(QChildEvent *);
    void resizeEvent(QResizeEvent *);
    bool eventFilter(QObject *, QEvent *);
    void showEvent(QShowEvent *e);
    void hideEvent(QHideEvent *e);
    #ifndef QT_NO_WHEELEVENT
    void wheelEvent(QWheelEvent *e);

    Q_PRIVATE_SLOT(d_func(), void _q_normalizeActiveWindow())
    Q_PRIVATE_SLOT(d_func(), void _q_minimizeActiveWindow())
    Q_PRIVATE_SLOT(d_func(), void _q_showOperationMenu())
    Q_PRIVATE_SLOT(d_func(), void _q_popupOperationMenu(const QPoint&))
    Q_PRIVATE_SLOT(d_func(), void _q_operationMenuActivated(QAction *))
    Q_PRIVATE_SLOT(d_func(), void _q_updateActions())
    Q_PRIVATE_SLOT(d_func(), void _q_scrollBarChanged())

    friend class QWorkspaceChild;

    #endif // QT_NO_WORKSPACE



    #endif // QWORKSPACE_H


  • So, I send the source part, I have changed....
    I found out, how to create a diff file... I hope this helps
    @--- E:/Entwicklung/qt485/src/gui/widgets/qworkspace.cpp Thu Jul 04 16:19:10 2013
    +++ E:/Entwicklung/qtsourcen/scdll/qworkspace/qworkspace.cpp Mon Oct 21 13:40:12 2013
    @@ -15,8 +15,8 @@
    ** contact form at http://qt.digia.com
    +** Modified for Qt 5 by Peter Bienert, Soft-Nrg Development GmbH Erlangen

    #include "qworkspace.h"
    #ifndef QT_NO_WORKSPACE
    #include "qapplication.h"
    @@ -640,7 +640,53 @@

    // from qwidget.cpp
    -extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);
    +// Peter Bienert: commented the extern out
    +// extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);

    +// Peter Bienert: no external, source part copied from QWidget (Qt 5.1.1)
    +QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)

    • Q_ASSERT(widget);

    +#ifdef QT_EVAL

    • extern QString qt_eval_adapt_window_title(const QString &title);
    • QString cap = qt_eval_adapt_window_title(title);
    • QString cap = title;
    • if (cap.isEmpty())
    • return cap;
    • QLatin1String placeHolder("[*]");
    • int index = cap.indexOf(placeHolder);
    • // here the magic begins
    • while (index != -1) {
    • index += placeHolder.size();
    • int count = 1;
    • while (cap.indexOf(placeHolder, index) == index) {
    • ++count;
    • index += placeHolder.size();
    • }
    • if (count%2) { // odd number of [*] -> replace last one
    • int lastIndex = cap.lastIndexOf(placeHolder, index - 1);
    • if (widget->isWindowModified()
    • && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget))
    • cap.replace(lastIndex, 3, QWidget::tr("*"));
    • else
    • cap.remove(lastIndex, 3);
    • }
    • index = cap.indexOf(placeHolder, index);
    • }
    • cap.replace(QLatin1String("[][]"), placeHolder);
    • return cap;

    void QWorkspaceTitleBar::paintEvent(QPaintEvent *)
    @@ -1074,7 +1120,7 @@
    actions[QWorkspacePrivate::CloseAct] = new QAction(QIcon(q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, q)),
    #ifndef QT_NO_SHORTCUT

    •                                                      +QLatin1Char('\t')+(QString)QKeySequence(Qt::CTRL+Qt::Key_F4)
    •            +QLatin1Char('\t')+(QString)QKeySequence(Qt::CTRL+Qt::Key_F4).toString()

    QObject::connect(actions[QWorkspacePrivate::CloseAct], SIGNAL(triggered()), q, SLOT(closeActiveWindow()));
    @@ -1207,7 +1253,8 @@

    • QWidgetPrivate::adjustFlags(flags);
      +// removed by Peter Bienert because this gives a crash
      +// QWidgetPrivate::adjustFlags(flags);

    #if 0
    bool wasMaximized = w->isMaximized();
    @@ -1228,6 +1275,8 @@
    this, SLOT(_q_popupOperationMenu(QPoint)));
    connect(child, SIGNAL(showOperationMenu()),
    this, SLOT(_q_showOperationMenu()));

    • // Peter Bienert, as adjustFlags crashs, we give the child the flags back...
    • child->setWindowFlags(flags);
      if (child->isVisibleTo(this))
      @@ -3218,7 +3267,7 @@
      QWorkspaceChild *child = *it;
      if (!child->isHidden())
    •            r = r.unite(child->geometry());
    • r = r.united(child->geometry());

  • Moderators


    QWorkspace is a Qt 3 class. It was deprecated in Qt 4 because its design wasn't good, and it was removed in Qt 5.

    What issues did you have with QMdiArea?

  • Hi, JKSH

    I have a Application with about 10 Windows, based on QMainWindow which should work as MDI windows. None of the windows are equal with other windows. As long, as I work with Qt 4, QWorkspace works exactly how I like that. Now Qt 5 removed QWorkspace, documentation says, to use QMdiArea and only replace the QWorkspace functions with QMdiArea functions. This does not work as I excpectd. I spent a week to get it to run, Digia Support was not able to help me, I guess, no of them have used this in a complex App. So I decide to port QWorkspace to Qt 5 and all works exactly as expected.
    I earn my money with develop software, not with playing around with incompatible functions...

    I decided also to post it here, perhaps one can use it.

    And I'm not willing, to discuss about why I have done it. It works for me and give me the time to work on my applications and not on windows manager functions...

    So, the short thing is: Take it or leave it... It's just an offer. Not more, not less.

    Kind regards from germany

    Sorry for my bad english, I'm no native english speaker...

  • Moderators

    I see. Thank you for sharing your work with the community.

    P.S. Please don't apologize for your English; it is clear and understandable :)

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.