jerous86 / nimqt

Qt bindings for nim
GNU General Public License v2.0
93 stars 6 forks source link

Problems adding QStandardItem to QList #43

Open hansdampfinger666 opened 5 months ago

hansdampfinger666 commented 5 months ago

I just want to build a table from a bunch of strings and I get a compile error. Not sure what to do, maybe you can help. This is my code:

import os
import nimqt
import nimqt/qpushbutton
import nimqt/qboxlayout
import nimqt/qtablewidget
import nimqt/qstandarditemmodel

nimqt.init
let app = newQApplication(commandLineParams())

inheritQObject(GuiHandler, QObject):
  slot_decl on_helloWorld_clicked()

let guiHandler: ptr GuiHandler = newGuiHandler()
let win: ptr QWidget = newQWidget()
var table: ptr QTableWidget = newQTableWidget(win)
var table_model: QStandardItemModel
var col: QList[QStandardItem] = newQList[QStandardItem]()

let pls_str: string = "pls"
let pls = Q pls_str
let pls_it: QStandardItem = newQStandardItem(pls)
col.append(pls_it)

win.makeLayout:
  - newQPushButton(Q "Click me!!"):
    connect(SIGNAL "clicked()", guiHandler, SLOT "on_helloWorld_clicked()")
  - newQPushButton( Q "Click me!!"):
    connect(SIGNAL "clicked()", guiHandler, SLOT "on_helloWorld_clicked()")
  - use_object table

proc on_helloWorld_clicked(this: ptr GuiHandler) =
  let sender = cast[ ptr QPushButton]( this.get_sender())
  sender.setText( Q "Hello world!")

win.show()
discard app.exec()

It apparently fails when trying to append the pls_it item to the QList of QStandardItems and I am unsure why. I am trying to rebuild an existing C++ application (adding a bunch of strings to columns and then adding them to a table). I have tried a bunch of combinations of using var and const and let and addr etc. I have checked the signature of the Qt functions and I have seen your discussion on using const_var etc. here https://github.com/jerous86/nimqt/tree/main#some-notes.

Compiler output:

/usr/include/qt/QtCore/qlist.h: In instantiation of ‘void QList<T>::node_construct(Node*, const T&) [with T = QStandardItem]’:
/usr/include/qt/QtCore/qlist.h:625:13:   required from ‘void QList<T>::append(const T&) [with T = QStandardItem]’
/home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp:290:27:   required from here
/usr/include/qt/QtCore/qlist.h:465:65: error: ‘QStandardItem::QStandardItem(const QStandardItem&)’ is protected within this context
  465 |     if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
      |                                                                 ^~~~~~~~
In file included from /home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp:15:
/usr/include/qt/QtGui/qstandarditemmodel.h:246:5: note: declared protected here
  246 |     QStandardItem(const QStandardItem &other);
      |     ^~~~~~~~~~~~~
/usr/include/qt/QtCore/qlist.h:466:39: error: ‘QStandardItem::QStandardItem(const QStandardItem&)’ is protected within this context
  466 |     else if (QTypeInfo<T>::isComplex) new (n) T(t);
      |                                       ^~~~~~~~~~~~
/usr/include/qt/QtGui/qstandarditemmodel.h:246:5: note: declared protected here
  246 |     QStandardItem(const QStandardItem &other);
      |     ^~~~~~~~~~~~~
/usr/include/qt/QtCore/qlist.h:471:35: error: ‘QStandardItem& QStandardItem::operator=(const QStandardItem&)’ is protected within this context
  471 |     else *reinterpret_cast<T*>(n) = t;
      |          ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
/usr/include/qt/QtGui/qstandarditemmodel.h:248:20: note: declared protected here
  248 |     QStandardItem &operator=(const QStandardItem &other);
      |                    ^~~~~~~~
compilation terminated due to -fmax-errors=3.
Error: execution of an external compiler program 'g++ -c -std=gnu++17 -funsigned-char  -w -fmax-errors=3 -fpermissive -pthread -std=c++17 -I/home/al/.nimble/pkgs2/nimqt-0.2.1-8206cd476af0ad201a0308d6e6beb24885b07955 -I/usr/include/qt -fPIC -I/usr/include/qt/QtCore -I/usr/include/qt/QtGui -I/usr/include/qt/QtWidgets   -I/home/al/.choosenim/toolchains/nim-2.0.0/lib -I/home/al/Documents/code/Nim/qt_test/src -o /home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp.o /home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp' failed with exit code: 1

I am on the newest everything, nimble installed your newest version (with the updated install instructions for Nim 2 etc.). Specs: EndeavourOS with qt6-base 6.6.1-3 installed. Nim 2.0.0, nimble v0.14.2.

jerous86 commented 5 months ago

When generating all the nim code, some things still go wrong unfortunately, as Qt is a complex codebase.

I pushed a fix, so if you update nimqt, then your code should compile.

hansdampfinger666 commented 4 months ago

I totally understand, I'm very happy you're willing to help.

I ran the

nimble install https://github.com/jerous86/nimqt@#head

again, which created a new directory in my ~/.nimble/pkgs2/ directory and I deleted the older directory. Since the version did not change I think this should do the trick.

Going to definition with gd in my neovim setup seem to show the new code.

My .nimble file in my test project includes this:

backend = "cpp"
requires "nim >= 2.0.0"
requires "nimqt >= 0.2.1"

Now I have the following code with my annotated toughts. Forgive me if I'm betraying a lack of knowledge about Nim or CPP here:

import os
import nimqt
import nimqt/qpushbutton
import nimqt/qboxlayout
import nimqt/qtablewidget
import nimqt/qstandarditemmodel

nimqt.init
let app = newQApplication(commandLineParams())

inheritQObject(GuiHandler, QObject):
  slot_decl on_helloWorld_clicked()

let guiHandler: ptr GuiHandler = newGuiHandler()
let win: ptr QWidget = newQWidget()
var table: ptr QTableWidget = newQTableWidget(win)
var table_model: QStandardItemModel

# confused, because using new implies that we're doing new QList<QStandardItem>
# in CPP, which should return a ptr, but we're getting a value back here
var col: QList[QStandardItem] = newQList[QStandardItem]()

let pls_str: string = "pls"

# same confusion as above, the Q proc is the shorthand for newQstring,
# but we're getting a value back, not a ptr
let pls = Q(pls_str)
# let pls: QString = QString(pls_str) would make sense to me and
# let pls: ptr QString = newQString(pls_str)

# then this works again, since pls is a QString value
let pls_it: ptr QStandardItem = newQStandardItem(pls)

# this fails to compile here, because the template in CPP seems to complain
# about the const refness of the pls_it,
# I don't know how to solve this
# if my knowledge of CPP/Qt is correct, this function should take the value of
# pls_it and copy initialize an item in the QList with that value
col.append(pls_it[])

win.makeLayout:
  - newQPushButton(Q "Click me!!"):
    connect(SIGNAL "clicked()", guiHandler, SLOT "on_helloWorld_clicked()")
  - newQPushButton( Q "Click me!!"):
    connect(SIGNAL "clicked()", guiHandler, SLOT "on_helloWorld_clicked()")
  - use_object table

proc on_helloWorld_clicked(this: ptr GuiHandler) =
  let sender = cast[ ptr QPushButton]( this.get_sender())
  sender.setText( Q "Hello world!")

win.show()
discard app.exec()

Executing nimble run in my directory gives me the following compiler error:

/usr/include/qt/QtCore/qlist.h: In instantiation of ‘void QList<T>::node_construct(Node*, const T&) [with T = QStandardItem]’:
/usr/include/qt/QtCore/qlist.h:625:13:   required from ‘void QList<T>::append(const T&) [with T = QStandardItem]’
/home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp:291:27:   required from here
/usr/include/qt/QtCore/qlist.h:465:65: error: ‘QStandardItem::QStandardItem(const QStandardItem&)’ is protected within this context
  465 |     if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
      |                                                                 ^~~~~~~~
In file included from /home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp:15:
/usr/include/qt/QtGui/qstandarditemmodel.h:246:5: note: declared protected here
  246 |     QStandardItem(const QStandardItem &other);
      |     ^~~~~~~~~~~~~
/usr/include/qt/QtCore/qlist.h:466:39: error: ‘QStandardItem::QStandardItem(const QStandardItem&)’ is protected within this context
  466 |     else if (QTypeInfo<T>::isComplex) new (n) T(t);
      |                                       ^~~~~~~~~~~~
/usr/include/qt/QtGui/qstandarditemmodel.h:246:5: note: declared protected here
  246 |     QStandardItem(const QStandardItem &other);
      |     ^~~~~~~~~~~~~
/usr/include/qt/QtCore/qlist.h:471:35: error: ‘QStandardItem& QStandardItem::operator=(const QStandardItem&)’ is protected within this context
  471 |     else *reinterpret_cast<T*>(n) = t;
      |          ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
/usr/include/qt/QtGui/qstandarditemmodel.h:248:20: note: declared protected here
  248 |     QStandardItem &operator=(const QStandardItem &other);
      |                    ^~~~~~~~
compilation terminated due to -fmax-errors=3.
Error: execution of an external compiler program 'g++ -c -std=gnu++17 -funsigned-char  -w -fmax-errors=3 -fpermissive -pthread -std=c++17 -I/home/al/.nimble/pkgs2/nimqt-0.2.1-277d74164e27b1ff49f223848fe6497b3105a2f0 -I/usr/include/qt -fPIC -I/usr/include/qt/QtCore -I/usr/include/qt/QtGui -I/usr/include/qt/QtWidgets   -I/home/al/.choosenim/toolchains/nim-2.0.0/lib -I/home/al/Documents/code/Nim/qt_test/src -o /home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp.o /home/al/.cache/nim/qt_test_d/@mqt_test.nim.cpp' failed with exit code: 1

       Tip: 6 messages have been suppressed, use --verbose to show them.
nimble.nim(229)          buildFromDir

    Error:  Build failed for the package: qt_test