/me looking for a "simple" Media manager on Arch to somehow organize, fetch and tag a rather big collection of podcasts and documentaries of all kind.
]]>The main advantage of Qt over Gtk atm is a far better and smoother other OS support. Because Qt4 is more evolved than Gtk2 it takes up more RAM and is a bit slower to load. But coding is generally way cleaner with Qt because of the important object orientation.
And thanks for the patch, now only the "? -> About" menu is lacking
]]>As for light weight, the current qt is nearly twice the size of gtk2, but I think this will change in qt 5, as it's modularized (similar to the fashion that qt is modularized already on debian, for example). I mention this as a bit of commentary, not to try and convince you to drop the gtk version. In fact, most people running light weight desktops (I'm thinking openbox here), would probably rather not have to install Qt, so I definitely understand.
When I said different, I meant the application itself. Upon looking at the console output, it was simply a fact of me not having gstreamer python installed, so my mistake (I didn't install from aur, simply cloned repo).
edit: another patch
This one adds a file menu to the qt version (to match the interface of gtk version).
diff --git a/qt/gui/menubar.py b/qt/gui/menubar.py
index 495b484..015e137 100644
--- a/qt/gui/menubar.py
+++ b/qt/gui/menubar.py
@@ -9,22 +9,26 @@ class MenuBar(QtGui.QMenuBar):
self.core = parent
QtGui.QMenuBar.__init__(self, parent)
toolsMenu = QtGui.QMenu(_('&Tools'))
-
+ fileMenu = QtGui.QMenu(_('&File'))
+
+ fileMenu.addAction(_('&Quit'), self.core.close)
+ self.addMenu(fileMenu)
+
toolsMenu.addAction(_('Check for new files'), self.checkForNewFiles)
toolsMenu.addAction(_('Settings'), self.openSettings)
self.addMenu(toolsMenu)
-
+
parent.moduleLoaded.connect(self.loadModuleMenus)
-
+
for module in self.core.loadedModules:
self.loadModuleMenus(module)
-
-
+
+
def checkForNewFiles(self):
progressNotifier = self.core.statusBar.addProgressNotifier()
- self.core.BDD.checkForNewFiles(progressNotifier)
-
-
+ self.core.db.checkForNewFiles(progressNotifier)
+
+
def loadModuleMenus(self, module):
if(module == 'pictures' or module == 'videos'):
pictures = QtGui.QMenu(_(module[0].capitalize() + module[1:]))
@@ -32,9 +36,9 @@ class MenuBar(QtGui.QMenuBar):
pictures.addAction(_('Check for doubloons'), self.core.managers[module].containerBrowser.checkForDoubloons)
pictures.addAction(_("Move to UC structure"), lambda: self.moveToUCStructure(module))
pictures.addSeparator()
-
+
panelGroup = QtGui.QActionGroup(self)
-
+
browserMode = settings.get_option(module + '/browser_mode', 'panel')
panes = pictures.addAction( _('Multi-panes'), lambda: self.core.managers[module].setBrowserMode('panes'))
@@ -42,7 +46,7 @@ class MenuBar(QtGui.QMenuBar):
if(browserMode == 'panes'):
panes.setChecked(True)
panes.setActionGroup(panelGroup)
-
+
panel = pictures.addAction(_('All in one panel'), lambda: self.core.managers[module].setBrowserMode('panel'))
panel.setCheckable(True)
if(browserMode == 'panel'):
@@ -53,64 +57,64 @@ class MenuBar(QtGui.QMenuBar):
elif(module == 'music'):
def reloadCovers():
progressNotifier = self.core.statusBar.addProgressNotifier()
- self.core.BDD.reloadCovers(progressNotifier)
+ self.core.db.reloadCovers(progressNotifier)
music = QtGui.QMenu(_('Music'))
music.addAction(_('Reload covers'), reloadCovers)
-
-
+
+
self.addMenu(music)
-
+
def moveToUCStructure(self, module):
dialog = modales.UCStructureHelper(module)
folder = dialog.exec_()
if folder != None:
self.core.managers[module].containerBrowser.moveToUCStructure(folder)
-
+
def openSettings(self):
dialog = modales.SettingsEditor()
dialog.exec_()
-
+
class StatusBar(QtGui.QStatusBar):
def __init__(self):
QtGui.QStatusBar.__init__(self)
-
+
def addProgressNotifier(self):
notifier = ProgressNotifier(self)
notifier.done.connect(self.removeNotifier)
self.addWidget(notifier)
return notifier
-
+
def removeNotifier(self):
notifier = self.sender()
self.removeWidget(notifier)
class ProgressNotifier(QtGui.QProgressBar):
-
+
valueRequested = QtCore.Signal(int)
pulseRequested = QtCore.Signal()
done = QtCore.Signal()
-
+
def __init__(self, statusBar):
QtGui.QProgressBar.__init__(self)
self.statusBar = statusBar
self.valueRequested.connect(self.setValue)
self.pulseRequested.connect(self.doPulse)
-
+
def doPulse(self):
self.setRange(0, 0)
-
+
def emitDone(self):
self.done.emit()
-
+
def pulse(self):
self.pulseRequested.emit()
-
-
+
+
def setFraction(self, val):
val *= 100
if(self.maximum != 100):
self.setMaximum(100)
self.valueRequested.emit(val)
-
+
Differences between Gtk and Qt versions should only be due to how each framework handle underlying functions (for example Gtk view/model is not object oriented). As of now it's not the case everywhere but this is the purpose of classes in abstract fodler. It's not exactly a library but it sure is a wrapper between Bullseye logic and specific GUI logic. For example, abstract panel (which display containers; artist, album, etc in music module and universes, categories, etc in other modules) call append(self, model, data, parentNode) to fill its model from db. This method is part of the GUI panel subclass, not the abstract one. I try to isolate core logic as much as possible but at the end of the day you still have to write a lot of stuff if you support two differents frameworks.
There is no reason to maintain two versions aside that it doesn't require that much effort if done properly. Because it's just translation. I also think Gtk 2 version fits better lightweight systems using Xfce, LXDE, etc...
]]>My vim setup trims extra whitespace from files, so I created a diff that ignores white space to allow a cleaner application of the patch:
diff --git a/qt/gui/menubar.py b/qt/gui/menubar.py
index 495b484..0d1189f 100644
--- a/qt/gui/menubar.py
+++ b/qt/gui/menubar.py
@@ -22,7 +22,7 @@ class MenuBar(QtGui.QMenuBar):
def checkForNewFiles(self):
progressNotifier = self.core.statusBar.addProgressNotifier()
- self.core.BDD.checkForNewFiles(progressNotifier)
+ self.core.db.checkForNewFiles(progressNotifier)
def loadModuleMenus(self, module):
As a side note, there seems to be a lot of differences between the gtk and qt versions. Aside from potentially not having qt installed, is there a reason to maintain two versions? Alternatively, i wonder if it would make since to separate the project into a library and the gui's which implement the library (kind of like xmms and mpd do)? These are just ramblings, so feel free to ignore this part of my reply. the important part is the patch. :-)
edit:
If the above didn't apply cleanly, try this instead:
diff --git a/qt/gui/menubar.py b/qt/gui/menubar.py
index 495b484..0d1189f 100644
--- a/qt/gui/menubar.py
+++ b/qt/gui/menubar.py
@@ -9,22 +9,22 @@ class MenuBar(QtGui.QMenuBar):
self.core = parent
QtGui.QMenuBar.__init__(self, parent)
toolsMenu = QtGui.QMenu(_('&Tools'))
-
+
toolsMenu.addAction(_('Check for new files'), self.checkForNewFiles)
toolsMenu.addAction(_('Settings'), self.openSettings)
self.addMenu(toolsMenu)
-
+
parent.moduleLoaded.connect(self.loadModuleMenus)
-
+
for module in self.core.loadedModules:
self.loadModuleMenus(module)
-
-
+
+
def checkForNewFiles(self):
progressNotifier = self.core.statusBar.addProgressNotifier()
- self.core.BDD.checkForNewFiles(progressNotifier)
-
-
+ self.core.db.checkForNewFiles(progressNotifier)
+
+
def loadModuleMenus(self, module):
if(module == 'pictures' or module == 'videos'):
pictures = QtGui.QMenu(_(module[0].capitalize() + module[1:]))
@@ -32,9 +32,9 @@ class MenuBar(QtGui.QMenuBar):
pictures.addAction(_('Check for doubloons'), self.core.managers[module].containerBrowser.checkForDoubloons)
pictures.addAction(_("Move to UC structure"), lambda: self.moveToUCStructure(module))
pictures.addSeparator()
-
+
panelGroup = QtGui.QActionGroup(self)
-
+
browserMode = settings.get_option(module + '/browser_mode', 'panel')
panes = pictures.addAction( _('Multi-panes'), lambda: self.core.managers[module].setBrowserMode('panes'))
@@ -42,7 +42,7 @@ class MenuBar(QtGui.QMenuBar):
if(browserMode == 'panes'):
panes.setChecked(True)
panes.setActionGroup(panelGroup)
-
+
panel = pictures.addAction(_('All in one panel'), lambda: self.core.managers[module].setBrowserMode('panel'))
panel.setCheckable(True)
if(browserMode == 'panel'):
@@ -56,61 +56,61 @@ class MenuBar(QtGui.QMenuBar):
self.core.BDD.reloadCovers(progressNotifier)
music = QtGui.QMenu(_('Music'))
music.addAction(_('Reload covers'), reloadCovers)
-
-
+
+
self.addMenu(music)
-
+
def moveToUCStructure(self, module):
dialog = modales.UCStructureHelper(module)
folder = dialog.exec_()
if folder != None:
self.core.managers[module].containerBrowser.moveToUCStructure(folder)
-
+
def openSettings(self):
dialog = modales.SettingsEditor()
dialog.exec_()
-
+
class StatusBar(QtGui.QStatusBar):
def __init__(self):
QtGui.QStatusBar.__init__(self)
-
+
def addProgressNotifier(self):
notifier = ProgressNotifier(self)
notifier.done.connect(self.removeNotifier)
self.addWidget(notifier)
return notifier
-
+
def removeNotifier(self):
notifier = self.sender()
self.removeWidget(notifier)
class ProgressNotifier(QtGui.QProgressBar):
-
+
valueRequested = QtCore.Signal(int)
pulseRequested = QtCore.Signal()
done = QtCore.Signal()
-
+
def __init__(self, statusBar):
QtGui.QProgressBar.__init__(self)
self.statusBar = statusBar
self.valueRequested.connect(self.setValue)
self.pulseRequested.connect(self.doPulse)
-
+
def doPulse(self):
self.setRange(0, 0)
-
+
def emitDone(self):
self.done.emit()
-
+
def pulse(self):
self.pulseRequested.emit()
-
-
+
+
def setFraction(self, val):
val *= 100
if(self.maximum != 100):
self.setMaximum(100)
self.valueRequested.emit(val)
-
+
The difference is that whitespace edits aren't ignored
]]>Not to mention I'm not sure if custom widgets integration is made easy with these ui-tools.
]]>And btw here's some basic information about the structure :
abstract : when Gtk and Qt classes for the same widget share a lot of code, an abstract base class is created here
common : common stuff not related to data (~ settings and folders definition)
data : data related stuff : db module contains database utility classes and elements module contains classes representing single objects (track, picture, pictures container, etc)
gui : modales contains big dialog windows classes and menus contains menus big enough to deserve their own class
media : library playback (GStreamer, VLC, Phonon) interfaces
music : stuff related to music module
uc_sections : stuff related to modules that work with categories/universes organization. Specific modules classes should be in subfolder.
qt - a copy of the above structure (except abstract) containing matching Qt classes
]]>I'll start cleaning and documenting the code this week end. And maybe I'll start implementing custom modules integration on the way; uc_sections code is nearly ready for that.
]]>Some old parts of the code (especially gtk) are quite messy and contains bits of french. However Qt code should be fine. But still, I need to clean and standardize everything some day.
]]>If you feel anything is misrepresented or missing, please let me know.
]]>Yes I was using glib for setting paths, but decided not to continue with it after starting a Qt version. Therefore I quickly replaced glib calls without much polish, so your patch is welcome, especially the Windows commented lines.
As for the getters setters, I rarely use them; It's mainly when I'm not sure if the underlying variable name will change or not.
And thanks for the translation exception, didn't test this that much.
EDIT: packages updated.
]]>