This is known problem, and is caused by how Lqt handles custom slots.
> I have admittedly no clue about how lqt works internally
In order for this to work, Lqt has to create subclasses for every
QObject-derived class. When you call 'QWidget.new()', Lqt actually
creates this new subclass.
The UiLoader however creates "raw" objects, and therefore Lqt is
unable to add custom slots to them.
> if its a mistake on my part
No it isn't :)
> if there is some way to circumvent this problem
One way to overcome this problem is to create an object from Lqt
(which will have custom slots ability), and use it to handle all the
signals that you need, i.e.:
local w = loadUiFile "test.ui"
local button = w:findChild("pushButton")
local handler = QObject.new()
handler:__addmethod('handleButton()', function() print("Handled!") end)
handler:connect(button, '2pressed()', '1handleButton()')
To fix this, I assume one would have to reimplement at least part of
the UI- loader in Lua to generate all objects properly?
I just have no idea how much time/knowledge it would take to make this
work properly; I'd definitely give it a look if I thought I could do
it.
You would have to study the actual source of QUiLoader, because it
involves some parsing and setting up. I have never seen it myself, so
I am not sure how hard it would be to implement it. However, I feel
that it should be possible to do in plain Lua (once QtCore, QtGui and
QtXml modules are loaded).
----- copy in uiLoader.lua -----
require 'qtcore'
require 'qtgui'
require 'qtuitools'
module('uiLoader', package.seeall)
local mLoader = QUiLoader.new_local()
local mObjectsByName = {}
mLoader.createWidget = function (loader, _className, parent, name)
local className = _className:toUtf8()
local widget
if className == 'QMainWindow' then
widget = QMainWindow.new(parent)
elseif className == 'QWidget' then
widget = QWidget.new(parent)
elseif className == 'QMenuBar' then
widget = QMenuBar.new(parent)
elseif className == 'QMenu' then
widget = QMenu.new(parent)
elseif className == 'QStatusBar' then
widget = QStatusBar.new(parent)
elseif className == 'QDockWidget' then
widget = QDockWidget.new(parent)
elseif className == 'QGroupBox' then
widget = QGroupBox.new(parent)
elseif className == 'QToolButton' then
widget = QToolButton.new(parent)
elseif className == 'QTreeView' then
widget = QTreeView.new(parent)
elseif className == 'QListView' then
widget = QListView.new(parent)
elseif className == 'QListWidget' then
widget = QListWidget.new(parent)
elseif className == 'QTabWidget' then
widget = QTabWidget.new(parent)
else
error('Cannot create object: '..tostring(className))
widget = QWidget.new(parent)
end
widget.__isWidget = true
widget:setObjectName(name)
local n = name:toUtf8()
mObjectsByName[n] = widget
return widget
end
mLoader.createLayout = function (loader, _className, parent, name)
local parentWidget = parent.__isWidget and parent or nil
local parentLayout = parent.__isLayout and parent or nil
local function create(class)
return parentWidget and class.new(parentWidget) or class.new()
end
local layout
local className = _className:toUtf8()
if className == 'QVBoxLayout' then
layout = create(QVBoxLayout)
elseif className == 'QHBoxLayout' then
layout = create(QHBoxLayout)
else
print('Cannot create layout: '..tostring(className))
layout = create(QLayout)
end
layout.__isLayout = true
layout:setObjectName(name)
local n = name:toUtf8()
mObjectsByName[n] = layout
return layout
end
function load(fileName)
local file = QFile.new_local(fileName)
file:open({'ReadOnly'})
return mLoader:load(file)
end
function findObjectByName(name)
return mObjectsByName[name]
end
---------
On Nov 19, 9:42 pm, Michal Kottman <k0mpju...@gmail.com> wrote:
Neat! I didn't know this was so easy :)
> Not all the widgets are handled but can be added easily.
> The createLayout was copied from the cpp factory implementation.
> Use findObjectByName to retrieve widgets. QWidget:findChild might also
> work but I didn't try it.
We could simplify the implementation by using some Lua magic :)
> mLoader.createWidget = function (loader, _className, parent, name)
> local className = _className:toUtf8()
>
> local widget
> if className == 'QMainWindow' then
> widget = QMainWindow.new(parent)
> ....
> else
> error('Cannot create object: '..tostring(className))
> widget = QWidget.new(parent)
> end
This can be rewritten as:
mLoader.createWidget = function (loader, _className, parent, name)
local className = _className:toUtf8()
local class = _G[_className]
local widget
if class then
widget = class.new(parent)
else
error('Cannot create object: '..tostring(_className))
widget = QWidget.new(parent)
end
The same can be done in createLayout.
----------------
require 'qtcore'
require 'qtgui'
require 'qtuitools'
module('uiLoader', package.seeall)
local mLoader = QUiLoader.new_local()
local mObjectsByName = {}
mLoader.createWidget = function (loader, _className, parent, name)
local className = _className:toUtf8()
local widget
local class = _G[className]
if class then
widget = class.new(parent)
else
error('Cannot create object: '..tostring(className))
end
widget.__isWidget = true
widget:setObjectName(name)
local n = name:toUtf8()
mObjectsByName[n] = widget
return widget
end
mLoader.createLayout = function (loader, _className, parent, name)
local parentWidget = parent.__isWidget and parent or nil
local parentLayout = parent.__isLayout and parent or nil
local layout
local className = _className:toUtf8()
local class = _G[className]
if class then
layout = create(class)
else
error('Cannot create layout: '..tostring(className))
end
layout.__isLayout = true
layout:setObjectName(name)
local n = name:toUtf8()
mObjectsByName[n] = layout
return layout
end
function load(fileName)
local file = QFile.new_local(fileName)
file:open({'ReadOnly'})
return mLoader:load(file)
end
function findObjectByName(name)
return mObjectsByName[name]
end
-----------------
On Nov 30, 1:37 am, Michal Kottman <k0mpju...@gmail.com> wrote: