Author Archives: slopjong

Qt: set the main window title from everywhere

In Qt the title of the main window can be set from everywhere and thankfully to the QApplication class we gain access to all created widgets by using the method findChildren() or topLevelWidgets(). The difference between both is that findChildren() returns a list only with widgets which reside inside another widget and in contrast topLevelWidgets() returns a list with parentless widgets which are always independent windows or dialogs.

With this background knowledge topLevelWidgets() is the way to go because findChildren only finds… children.

As a showing example here is a code snippet:

foreach(QWidget *widget, QApplication::topLevelWidgets()) {
  if(widget->objectName() == "MainWindow")
    qobject_cast<QMainWindow*>(widget)->setWindowTitle("-_-");
}

In the foreach loop we walk through the whole list of top-level widgets and because we want to change the title of the main window, we check the widget’s object name. In this example the main window’s object name is ‘MainWindow’ which is the default in Qt Designer.

Object names are not necessarily unique, multiple objects can have the same object name and thus the wrong widget could be chosen. MainWindow kind of implies there should only be one, so this simple check should be fine in most cases.

An alternative to the class QApplication is the macro qApp which is an instance of that class.

#define qApp (static_cast<QApplication *>(QCoreApplication::instance()))

Because QApplication implements the singleton design pattern only one instance can exist at most. If we are sure that there are no other objects of the type QMainWindow in the top-level widget list we could also check if it inherits from that class.

In place of the code above this would be fine then as well:

foreach(QWidget *widget, qApp->topLevelWidgets()) {
  if(widget->inherits("QMainWindow"))
    qobject_cast<QMainWindow*>(widget)->setWindowTitle("-_-");
}
DeliciousDiggTechnorati FavoritesRedditLinkedInFacebookSpurlTwitterWebnewsYiGGMySpaceYahoo BookmarksFriendFeedGoogle BookmarksLiveJournalShare

Qt: error message telling the copy constructor is private

In the following code sample a singleton is implemented with a static instance getter which can be called in any other class.

class MyClass{

public:

    static MyClass *instance(){
        if(!m_instance)
            m_instance = new MyClass;
        return m_instance;
    }

private:

    MyClass(){}
    ~MyClass(){}

    static MyClass *m_instance;
};

MyClass *MyClass::m_instance = NULL;

class SomeOtherClass{
    void doSomething(){
        MyClass *c = MyClass::instance();
    }
};

In SomeOtherClass the method doSomething() grabs the instance of MyClass and keeps it in a local pointer variable. Now if the asterisk * is forgotten, the variable c no longer defines a pointer and in that case ‘=’ is no assignment but the copy constructor used to initialize the local variable declaration while the compiler complains this with a error message telling you that the copy constructor is private.

If in your Qt application the compiler outputs similar messages as follows, check if you’ve forgotten the asterisk.

/usr/include/qt4/QtCore/qobject.h: In copy constructor 'MyClass::MyClass(const MyClass&)':
/usr/include/qt4/QtCore/qobject.h:309: error: 'QObject::QObject(const QObject&)' is private
src/MyClass.h:17: error: within this context
/usr/include/qt4/QtGui/qstandarditemmodel.h:424: error: 'QStandardItemModel::QStandardItemModel(const QStandardItemModel&)' is private
src/MyClass.h:17: error: within this context
/usr/include/qt4/QtGui/qstandarditemmodel.h:424: error: 'QStandardItemModel::QStandardItemModel(const QStandardItemModel&)' is private
src/MyClass.h:17: error: within this context
/usr/include/qt4/QtGui/qstandarditemmodel.h:424: error: 'QStandardItemModel::QStandardItemModel(const QStandardItemModel&)' is private
src/MyClass.h:17: error: within this context

Note: the singleton implementation above has some drawbacks like not being thread-safe. Here it’s only used as a showing example.

DeliciousDiggTechnorati FavoritesRedditLinkedInFacebookSpurlTwitterWebnewsYiGGMySpaceYahoo BookmarksFriendFeedGoogle BookmarksLiveJournalShare

Qt: QString constant in a class

A constant QString can be achieved by defining the macro

#CONSTSTRING "-_-"

and by creating a temporary QString instance in each place the constant is needed e.g. for a window title.

...
window.setWindowTitle(QString(CONSTSTRING));
...

A lot of the Qt goodness is due to macros but most of them are defined as empty for good reason. Macros are processed by a preprocessor which replaces the macro by the given text in the source file before the compiler knows what happens. Amongst others they can produce unplanned side-effects due to the missing data type and thus in Qt they are mainly used as markers for the Meta-Object-Compiler.

Another drawback is that if the constant is used in numerous places, numerous of anonymous, unnamed variables are created which reduces the efficiency.

All these drawbacks can be avoided by simply defining a static constant as shown in the following example. In myclass.h the constant is defined …

class MyClass
{
private:
  static const QString constString;
}

… and initialized in myclass.cpp

#include "MyClass.h"

const QString MyClass::constString = QString("-_-");

The assignment of const QStrings are also faster thanks to implicit sharing of QString because the first example doesn’t use implicit shared objects and thus they can’t be shallow copied.

If this global constant QString is used in other modules too then it can happen that your program crashes because of the static initialization order fiasco which should always be avoided because such errors are hard to find.

To not run into any trouble in that case use the construct on first use idiom [1, 2], where you simply wrap your static object inside a function.

const QString & constantQString()
{
  static const QString constant("-_-");
  return constant;
}
DeliciousDiggTechnorati FavoritesRedditLinkedInFacebookSpurlTwitterWebnewsYiGGMySpaceYahoo BookmarksFriendFeedGoogle BookmarksLiveJournalShare

Radio Protector

No, Radio Protector has nothing to do with a protective shield around your radio device but it’s a genious but also emotional song of the band 65daysofstatic I’ve found while I was zapping through some music channels on youtube.

Just watcht the video and enjoy. Tell me what feeling it arouses in you.

DeliciousDiggTechnorati FavoritesRedditLinkedInFacebookSpurlTwitterWebnewsYiGGMySpaceYahoo BookmarksFriendFeedGoogle BookmarksLiveJournalShare

Arch Linux: could not open file /var/lib/pacman/sync

With a fresh install of the Arch’s package manager pacman the user might not be able to open its databases located in /var/lib/pacman/sync .

error: could not open file /var/lib/pacman/sync/testing.db: Failed to open '/var/lib/pacman/sync/testing.db'
error: could not open file /var/lib/pacman/sync/core.db: Failed to open '/var/lib/pacman/sync/core.db'
error: could not open file /var/lib/pacman/sync/extra.db: Failed to open '/var/lib/pacman/sync/extra.db'
error: could not open file /var/lib/pacman/sync/community-testing.db: Failed to open '/var/lib/pacman/sync/community-testing.db'
error: could not open file /var/lib/pacman/sync/community.db: Failed to open '/var/lib/pacman/sync/community.db'
error: could not open file /var/lib/pacman/sync/multilib.db: Failed to open '/var/lib/pacman/sync/multilib.db'

In a bug report someone filed this description:

Pacman 3.5.0 sets the db files according to the umask, which can make them not world readable and hence users might need root privileges to search the db. This is a change since <3.5, since then everything needed to search for packages was set world readable.

After executing pacman -Syy the databases were accessible.

DeliciousDiggTechnorati FavoritesRedditLinkedInFacebookSpurlTwitterWebnewsYiGGMySpaceYahoo BookmarksFriendFeedGoogle BookmarksLiveJournalShare