Coder Social home page Coder Social logo

QTableView & QAbstractItemModel about qt HOT 14 CLOSED

therecipe avatar therecipe commented on September 24, 2024
QTableView & QAbstractItemModel

from qt.

Comments (14)

therecipe avatar therecipe commented on September 24, 2024

Hey

I got it working by using a QAbstractTableModel instead of a QAbstractItemModel.
And I needed to make a few changes, like deducing the interface{} to int in the data() function.

Also the model.DataChanged() function is currently not available due to this #9 issue (generic lists).

I hope the QAbstractTableModel still fits your needs.

package main

import (
    "strconv"

    "github.com/emirpasic/gods/maps/treemap"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/widgets"
)

var (
    vl    *treemap.Map
    model *core.QAbstractTableModel
    view  *widgets.QTableView
)

func NewArgsTable() *widgets.QTableView {
    vl = treemap.NewWithIntComparator()
    view = widgets.NewQTableView(nil)
    model = core.NewQAbstractTableModel(nil)

    model.ConnectRowCount(rowcount)
    model.ConnectColumnCount(columncount)
    model.ConnectData(data)
    model.ConnectSetData(setdata)
    model.ConnectInsertRows(insertrows)
    //model.ConnectFlags(flags)
    //model.ConnectRemoveRows(removerows)

    model.InsertRows(0, 5, core.NewQModelIndex()) // model.Parent(?)

    for i := 0; i < 6; i++ {
        // set data in model
        var index = model.Index(i, 0, core.NewQModelIndex())
        model.SetData(index, core.NewQVariant14(strconv.Itoa(i+1)), 2) // edit role = 2
        // set data in dataset
        vl.Put(i, i)
    }

    view.SetModel(model)

    return view

}

func rowcount(parent *core.QModelIndex) int {
    return vl.Size()
}

func columncount(parent *core.QModelIndex) int {
    return 1
}

func data(index *core.QModelIndex, role int) *core.QVariant { // dataset to model/view
    if role == 0 && index.IsValid() { // display role = 0
        text, exists := vl.Get(index.Row())
        if exists {
            switch deducedText := text.(type) {
            case int:
                {
                    return core.NewQVariant7(deducedText)
                }
            case string:
                {
                    return core.NewQVariant14(deducedText)
                }
            }
        }
    }
    return core.NewQVariant()
}

func setdata(index *core.QModelIndex, value *core.QVariant, role int) bool { // model/view to dataset
    if role == 2 && index.IsValid() {
        vl.Put(index.Row(), value.ToString())
        // The dataChanged() signal should be emitted if the data was successfully set.
        //model.DataChanged() // signal
        return true
    }
    return true
}

func insertrows(row int, count int, parent *core.QModelIndex) bool {

    model.BeginInsertRows(core.NewQModelIndex(), count, count+row-1)
    for r := 0; r < row; r++ {
        // view.InsertRow() ?
    }
    model.EndInsertRows()

    return true
}

//func removerows(row int, count int, parent *core.QModelIndex) bool {}

//func flags(index *core.QModelIndex) core.Qt__ItemFlag {}

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Flags function needed to change:

func flags(index *core.QModelIndex) core.Qt__ItemFlag {
    return 35 // flag // 1 || 2 || 32
    // core.Qt__ItemIsSelectable || core.Qt__ItemIsEditable || ItemIsEnabled
}

Ok, so this extended example with the delegate works - except:

  1. the font changes to the wrong font when in edit mode
  2. there is no line number column
package main

import (
    "strconv"

    "github.com/emirpasic/gods/maps/treemap"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/gui"
    "github.com/therecipe/qt/widgets"
)

var (
    vl    *treemap.Map
    model *core.QAbstractTableModel // QAbstractItemModel
    view  *widgets.QTableView
)

type Delegate struct {
    widgets.QStyledItemDelegate //don't use *pointers or it won't work
}

func NewArgsTable() *widgets.QTableView {
    view = widgets.NewQTableView(nil)
    model = core.NewQAbstractTableModel(nil) // NewQAbstractItemModel(nil)

    delegate := InitDelegate()
    view.SetItemDelegate(delegate)

    model.ConnectRowCount(rowcount)
    model.ConnectColumnCount(columncount)
    model.ConnectData(data)
    model.ConnectSetData(setdata)
    model.ConnectInsertRows(insertrows)
    model.ConnectFlags(flags)
    //model.ConnectRemoveRows(removerows)
    model.ConnectHeaderData(headerdata)

    model.InsertRows(0, 5, core.NewQModelIndex()) // model.Parent(?)

    vl = treemap.NewWithIntComparator()

    for i := 0; i < 6; i++ {
        vl.Put(i, i+i)
    }

    view.SetModel(model)

    return view

}

func InitDelegate() *Delegate {
    item := NewDelegate(nil) //will be generated in moc.go
    item.ConnectCreateEditor(createEditor)
    item.ConnectSetEditorData(setEditorData)
    item.ConnectSetModelData(setModelData)
    item.ConnectUpdateEditorGeometry(updateEditorGeometry)
    return item
}

func createEditor(parent *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) *widgets.QWidget {

    editor := widgets.NewQLineEdit(parent)
    font := gui.NewQFont2("verdana", 13, 1, false)
    editor.SetFont(font)
    return editor.QWidget_PTR()
}

func setEditorData(editor *widgets.QWidget, index *core.QModelIndex) {

    value := index.Model().Data(index, int(core.Qt__EditRole)).ToString()
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast

    lineedit.SetText(value)
}

func setModelData(editor *widgets.QWidget, model *core.QAbstractItemModel, index *core.QModelIndex) {

    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast

    font := gui.NewQFont2("verdana", 13, 1, false)
    lineedit.SetFont(font)

    text := lineedit.Text()
    model.SetData(index, core.NewQVariant14(text), int(core.Qt__EditRole))

}

func updateEditorGeometry(editor *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) {
    editor.SetGeometry(option.Rect())
}

func headerdata(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
    // if orientation == core.Qt__Horizontal && role = core.Qt__DisplayRole
    if orientation == 1 && role == 0 && section == 0 {
        return core.NewQVariant14("column 1")
    }
    return core.NewQVariant()

}

func rowcount(parent *core.QModelIndex) int {
    return vl.Size()
}

func columncount(parent *core.QModelIndex) int {
    return 1
}

func data(index *core.QModelIndex, role int) *core.QVariant { // dataset to model/view
    //  if role == 0 && index.IsValid() { // display role = 0
    //      text, _ := vl.Get(index.Row())
    //      return core.NewQVariant14(text.(string))
    //  }
    //  return core.NewQVariant()

    if role == 0 && index.IsValid() { // display role = 0
        text, exists := vl.Get(index.Row())
        if exists {
            switch deducedText := text.(type) {
            case int:
                {
                    return core.NewQVariant7(deducedText)
                }
            case string:
                {
                    return core.NewQVariant14(deducedText)
                }
            }
        }
    }
    return core.NewQVariant()

}

func setdata(index *core.QModelIndex, value *core.QVariant, role int) bool { // model/view to dataset
    if role == 2 && index.IsValid() {
        vl.Put(index.Row(), value.ToString())
        // The dataChanged() signal should be emitted if the data was successfully set.
        // model.DataChanged() // signal
        return true
    }
    return true
}

func insertrows(row int, count int, parent *core.QModelIndex) bool {

    model.BeginInsertRows(core.NewQModelIndex(), count, count+row-1)
    for r := 0; r < row; r++ {
        // view.InsertRow() ?
    }
    model.EndInsertRows()

    return true
}

//func removerows(row int, count int, parent *core.QModelIndex) bool {}

func flags(index *core.QModelIndex) core.Qt__ItemFlag {
    return 35 // flag // 1 || 2 || 32
    // core.Qt__ItemIsSelectable || core.Qt__ItemIsEditable || ItemIsEnabled
}

Attempting to fix the font, in the data function:

    if role == 6 { // Qt::FontRole
        return gui.NewQFont2("verdana", 13, 1, false)
    }

could not find a QVariant type for font type.

In another version of the QTableView, I have column count equal to my dataset size + 1 so I will have an extra row for someone to enter a new line. It seems the way setdata and rowcount are implemented they would be able to detect that change when new data is entered. This doesn't seem to work automatically so I was attempting to find the ConnectDataChanged event for QTableView but I can't find it in your godoc:
http://doc.qt.io/qt-5/qtableview-members.html

from qt.

therecipe avatar therecipe commented on September 24, 2024

Hey

I got the row header working and changed the font for the hole QTableView.

I marked the changes with //new

edit:
Yes, QFont to QVariant is currently not supported because the Qt docs suggested function qvariant_cast is not supported.
And the ConnectDataChanged() function is not available due to this #9 issue (generic lists).
(I will probably implement these generic lists in the next update, but it will take some time)

package main

import (
    "fmt"

    "github.com/emirpasic/gods/maps/treemap"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/gui"
    "github.com/therecipe/qt/widgets"
)

var (
    vl    *treemap.Map
    model *core.QAbstractTableModel // QAbstractItemModel
    view  *widgets.QTableView
)

type Delegate struct {
    widgets.QStyledItemDelegate //don't use *pointers or it won't work
}

func NewArgsTable() *widgets.QTableView {
    view = widgets.NewQTableView(nil)

    //new
    view.SetFont(gui.NewQFont2("verdana", 13, 1, false))
    //new

    model = core.NewQAbstractTableModel(nil) // NewQAbstractItemModel(nil)

    delegate := InitDelegate()
    view.SetItemDelegate(delegate)

    model.ConnectRowCount(rowcount)
    model.ConnectColumnCount(columncount)
    model.ConnectData(data)
    model.ConnectSetData(setdata)
    model.ConnectInsertRows(insertrows)
    model.ConnectFlags(flags)
    //model.ConnectRemoveRows(removerows)
    model.ConnectHeaderData(headerdata)

    model.InsertRows(0, 5, core.NewQModelIndex()) // model.Parent(?)

    vl = treemap.NewWithIntComparator()

    for i := 0; i < 6; i++ {
        vl.Put(i, i+i)
    }

    view.SetModel(model)

    return view

}

func InitDelegate() *Delegate {
    item := NewDelegate(nil) //will be generated in moc.go
    item.ConnectCreateEditor(createEditor)
    item.ConnectSetEditorData(setEditorData)
    item.ConnectSetModelData(setModelData)
    item.ConnectUpdateEditorGeometry(updateEditorGeometry)
    return item
}

func createEditor(parent *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) *widgets.QWidget {

    editor := widgets.NewQLineEdit(parent)

    //new
    //font := gui.NewQFont2("verdana", 13, 1, false)
    //editor.SetFont(font)
    //new

    return editor.QWidget_PTR()
}

func setEditorData(editor *widgets.QWidget, index *core.QModelIndex) {

    value := index.Model().Data(index, int(core.Qt__EditRole)).ToString()
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast

    lineedit.SetText(value)
}

func setModelData(editor *widgets.QWidget, model *core.QAbstractItemModel, index *core.QModelIndex) {

    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast

    //new
    //font := gui.NewQFont2("verdana", 13, 1, false)
    //lineedit.SetFont(font)
    //new

    text := lineedit.Text()
    model.SetData(index, core.NewQVariant14(text), int(core.Qt__EditRole))

}

func updateEditorGeometry(editor *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) {
    editor.SetGeometry(option.Rect())
}

func headerdata(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
    // if orientation == core.Qt__Horizontal && role = core.Qt__DisplayRole
    if orientation == 1 && role == 0 {
        return core.NewQVariant14(fmt.Sprintf("column %v", section+1))
    }

    //new
    if orientation == 2 && role == 0 {
        return core.NewQVariant14(fmt.Sprintf("row %v", section+1))
    }
    //new

    return core.NewQVariant()
}

func rowcount(parent *core.QModelIndex) int {
    return vl.Size()
}

func columncount(parent *core.QModelIndex) int {
    return 1
}

func data(index *core.QModelIndex, role int) *core.QVariant { // dataset to model/view
    //  if role == 0 && index.IsValid() { // display role = 0
    //      text, _ := vl.Get(index.Row())
    //      return core.NewQVariant14(text.(string))
    //  }
    //  return core.NewQVariant()

    if role == 0 && index.IsValid() { // display role = 0
        text, exists := vl.Get(index.Row())
        if exists {
            switch deducedText := text.(type) {
            case int:
                {
                    return core.NewQVariant7(deducedText)
                }
            case string:
                {
                    return core.NewQVariant14(deducedText)
                }
            }
        }
    }
    return core.NewQVariant()

}

func setdata(index *core.QModelIndex, value *core.QVariant, role int) bool { // model/view to dataset
    if role == 2 && index.IsValid() {
        vl.Put(index.Row(), value.ToString())
        // The dataChanged() signal should be emitted if the data was successfully set.
        // model.DataChanged() // signal
        return true
    }
    return true
}

func insertrows(row int, count int, parent *core.QModelIndex) bool {

    model.BeginInsertRows(core.NewQModelIndex(), count, count+row-1)
    for r := 0; r < row; r++ {
        // view.InsertRow() ?
    }
    model.EndInsertRows()

    return true
}

//func removerows(row int, count int, parent *core.QModelIndex) bool {}

func flags(index *core.QModelIndex) core.Qt__ItemFlag {
    return 35 // flag // 1 || 2 || 32
    // core.Qt__ItemIsSelectable || core.Qt__ItemIsEditable || ItemIsEnabled
}

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Very nice thank you!

func headerdata(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
    // if orientation == core.Qt__Horizontal && role = core.Qt__DisplayRole
    if orientation == 1 && role == 0 {
        return core.NewQVariant14(fmt.Sprintf("column %v", section+1))
    }

    //new
    if orientation == 2 && role == 0 {
        if section < vl.Size() {
            return core.NewQVariant14(strconv.Itoa(section + 1))
        } else {
            return core.NewQVariant14("*")
        }
    }
    return core.NewQVariant()

}

This is a little strange. section <= vl.Size() gives 1-7. section < vl.Size() gives 1-6 and an astrix. When I add text to this, after edit the astrix automatically updates to a 7.

I would expect section <= vl.Size() to give 1-6 and an astrix. I would expect after editing the astrix row for a new row to be inserted with an astrix since rowcount is vl.Size() + 1.

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Hi,

I think qabstracttablemodel is missing the LayoutChanged() method:

http://doc.qt.io/qt-5/qabstracttablemodel-members.html

http://stackoverflow.com/questions/6586493/qtreeview-qabstractitemmodel-insertrow?rq=1

from qt.

therecipe avatar therecipe commented on September 24, 2024

Hey

I looked into this and it seems like you would need to call http://doc.qt.io/qt-5/qabstractitemmodel.html#layoutChanged to update the table and display the new row.
But this function also requieres generic lists ...

I will try to support them asap, probably with the next update.

edit:
😄
You were faster

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Still not working exactly but a lot closer.

Using delegate's createEditor I can add a row as soon as it begins edit. Using editor.ConnectTextChanged(textchanged) I can commit the first input as a numbered line.

package main

import (
    "strconv"

    "github.com/emirpasic/gods/maps/treemap"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/gui"
    "github.com/therecipe/qt/widgets"
)

var (
    vl        *treemap.Map
    model     *core.QAbstractTableModel // QAbstractItemModel
    view      *widgets.QTableView
    textIndex *core.QModelIndex
)

type Delegate struct {
    widgets.QStyledItemDelegate //don't use *pointers or it won't work
}

// implement alphanum sort http://www.davekoelle.com/alphanum.html

func NewArgsTable() *widgets.QTableView {
    view = widgets.NewQTableView(nil)        // setObjectName
    model = core.NewQAbstractTableModel(nil) // NewQAbstractItemModel(nil)

    delegate := InitDelegate()
    view.SetItemDelegate(delegate)

    view.SetFont(gui.NewQFont2("verdana", 13, 1, false))

    model.ConnectRowCount(rowcount)
    model.ConnectColumnCount(columncount)
    model.ConnectData(data)
    model.ConnectSetData(setdata)
    model.ConnectInsertRows(insertrows)
    model.ConnectFlags(flags)
    //model.ConnectRemoveRows(removerows)
    model.ConnectHeaderData(headerdata)

    vl = treemap.NewWithIntComparator()
    for i := 0; i < 6; i++ {
        vl.Put(i, i+i)
    }

    view.SetModel(model)

    return view

}

func InitDelegate() *Delegate {
    item := NewDelegate(nil) //will be generated in moc.go
    item.ConnectCreateEditor(createEditor)
    item.ConnectSetEditorData(setEditorData)
    item.ConnectSetModelData(setModelData)
    item.ConnectUpdateEditorGeometry(updateEditorGeometry)
    return item
}

func createEditor(parent *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) *widgets.QWidget {

    editor := widgets.NewQLineEdit(parent)
    textIndex = index
    if index.Row() == vl.Size() {
        model.InsertRow(index.Row(), core.NewQModelIndex())
    }

    editor.ConnectTextChanged(textchanged)
    return editor.QWidget_PTR()
}

func textchanged(text string) {
    model.SetData(textIndex, core.NewQVariant14(text), 2) // edit role = 2
}

func setEditorData(editor *widgets.QWidget, index *core.QModelIndex) {

    value := index.Model().Data(index, int(core.Qt__EditRole)).ToString()
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast

    lineedit.SetText(value)
}

func setModelData(editor *widgets.QWidget, model *core.QAbstractItemModel, index *core.QModelIndex) {

    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast

    text := lineedit.Text()
    model.SetData(index, core.NewQVariant14(text), int(core.Qt__EditRole))

}

func updateEditorGeometry(editor *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) {
    editor.SetGeometry(option.Rect())
}

func headerdata(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
    // if orientation == core.Qt__Horizontal && role = core.Qt__DisplayRole
    if orientation == 1 && role == 0 {
        return core.NewQVariant14("column" + strconv.Itoa(section+1))
    }

    if orientation == 2 && role == 0 {
        if section < vl.Size() {
            return core.NewQVariant14(strconv.Itoa(section + 1))
        } else {
            return core.NewQVariant14("*")
        }
    }
    return core.NewQVariant()

}

func rowcount(parent *core.QModelIndex) int {
    return vl.Size() + 1
}

func columncount(parent *core.QModelIndex) int {
    return 1
}

func data(index *core.QModelIndex, role int) *core.QVariant { // dataset to model/view

    if role == 0 && index.IsValid() { // display role = 0
        text, exists := vl.Get(index.Row())
        if exists {
            switch deducedText := text.(type) {
            case int:
                {
                    return core.NewQVariant7(deducedText)
                }
            case string:
                {
                    return core.NewQVariant14(deducedText)
                }
            }
        }
    }

    return core.NewQVariant()

}

func setdata(index *core.QModelIndex, value *core.QVariant, role int) bool { // model/view to dataset
    if role == 2 && index.IsValid() { // edit role = 2

        vl.Put(index.Row(), value.ToString())

        //statusbar.ShowMessage("row: "+strconv.Itoa(index.Row())+"  value: "+value.ToString(), 0)

        // The dataChanged() signal should be emitted if the data was successfully set.
        // model.DataChanged() // signal

        return true
    }

    return true
}

func insertrows(row int, count int, parent *core.QModelIndex) bool {

    model.BeginInsertRows(core.NewQModelIndex(), row, row) // count, count+row-1)

    model.EndInsertRows()

    return true
}

//func removerows(row int, count int, parent *core.QModelIndex) bool {}

func flags(index *core.QModelIndex) core.Qt__ItemFlag {
    return 35 // flag // 1 || 2 || 32 // core.Qt__ItemIsSelectable || core.Qt__ItemIsEditable || ItemIsEnabled
}

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Thanks for your help :)

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

I don't think LayoutChanged is necessary. I have something working. I will post it later when I have a complete example.

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Completed example. There seems to be a bug around deleting the last row of the table sometimes.

Keeps an empty string at the end of the arraylist and shows this as a row with a star for editing.

To delete a row select a row and press delete -- except the last row with a star, it won't let you. Single row delete only.

package main

import (
    "os"

    "github.com/therecipe/qt/widgets"
)

var statusbar *widgets.QStatusBar

func main() {
    widgets.NewQApplication(len(os.Args), os.Args)

    // Main Window
    var window = widgets.NewQMainWindow(nil, 0)
    window.SetWindowTitle("Table")

    // Main Widget
    var table = NewArgsTable()

    // Set Central Widget
    window.SetCentralWidget(table)

    // Statusbar
    statusbar = widgets.NewQStatusBar(window)
    window.SetStatusBar(statusbar)

    // Run App
    widgets.QApplication_SetStyle2("fusion")
    window.ShowMaximized()
    widgets.QApplication_Exec()
}
package main

import (
    "strconv"

    "github.com/emirpasic/gods/lists/arraylist"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/gui"
    "github.com/therecipe/qt/widgets"
)

var (
    list  *arraylist.List
    model *core.QAbstractTableModel
    view  *widgets.QTableView

    textIndex  *core.QModelIndex
    currentRow int
)

type Delegate struct {
    widgets.QStyledItemDelegate //don't use *pointers or it won't work
}

func NewArgsTable() *widgets.QTableView {
    view = widgets.NewQTableView(nil)
    model = core.NewQAbstractTableModel(nil)

    delegate := InitDelegate()
    view.SetItemDelegate(delegate)
    view.SetFont(gui.NewQFont2("verdana", 13, 1, false))

    view.ConnectKeyPressEvent(keypressevent)
    view.ConnectCurrentChanged(currentchanged)

    model.ConnectRowCount(rowcount)
    model.ConnectColumnCount(columncount)
    model.ConnectData(data)
    model.ConnectSetData(setdata)
    model.ConnectInsertRows(insertrows)
    model.ConnectFlags(flags)
    model.ConnectRemoveRows(removerows)
    model.ConnectHeaderData(headerdata)

    list = arraylist.New()

    for i := 0; i < 6; i++ {
        list.Add(strconv.Itoa(i + i))
    }
    list.Add("") // blank

    view.SetModel(model)
    return view
}

func keypressevent(e *gui.QKeyEvent) {
    if e.Key() == int(core.Qt__Key_Delete) {
        if currentRow < list.Size()-1 {
            model.RemoveRows(currentRow, 1, core.NewQModelIndex())
        }
    } else {
        view.KeyPressEventDefault(e)
    }
}

func currentchanged(current *core.QModelIndex, previous *core.QModelIndex) {
    currentRow = current.Row()
}

func InitDelegate() *Delegate {
    item := NewDelegate(nil) //will be generated in moc.go
    item.ConnectCreateEditor(createEditor)
    item.ConnectSetEditorData(setEditorData)
    item.ConnectSetModelData(setModelData)
    item.ConnectUpdateEditorGeometry(updateEditorGeometry)
    return item
}

func createEditor(parent *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) *widgets.QWidget {
    editor := widgets.NewQLineEdit(parent)
    textIndex = index

    if index.Row() == list.Size()-1 {
        model.InsertRow(index.Row(), core.NewQModelIndex())
    }

    editor.ConnectTextChanged(textchanged)
    return editor.QWidget_PTR()
}

func textchanged(text string) {
    model.SetData(textIndex, core.NewQVariant14(text), 2) // edit role 
}

func setEditorData(editor *widgets.QWidget, index *core.QModelIndex) {
    value, _ := list.Get(index.Row())
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer())
    lineedit.SetText(value.(string))
}

func setModelData(editor *widgets.QWidget, model *core.QAbstractItemModel, index *core.QModelIndex) {
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer())
    text := lineedit.Text()
    model.SetData(index, core.NewQVariant14(text), int(core.Qt__EditRole))

}

func updateEditorGeometry(editor *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) {
    editor.SetGeometry(option.Rect())
}

func headerdata(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
    if orientation == 1 && role == 0 { // Qt__Horizontal, Qt__DisplayRole
        return core.NewQVariant14("column" + strconv.Itoa(section+1))
    }

    if orientation == 2 && role == 0 {
        if section < list.Size()-1 {
            return core.NewQVariant14(strconv.Itoa(section + 1))
        } else {
            return core.NewQVariant14("*")
        }
    }
    return core.NewQVariant()
}

func rowcount(parent *core.QModelIndex) int {
    return list.Size()
}

func columncount(parent *core.QModelIndex) int {
    return 1
}

func data(index *core.QModelIndex, role int) *core.QVariant {
    if role == 0 && index.IsValid() { // display role
        text, exists := list.Get(index.Row())
        if exists {
            switch deducedText := text.(type) {
            case int:
                {
                    return core.NewQVariant7(deducedText)
                }
            case string:
                {
                    return core.NewQVariant14(deducedText)
                }
            }
        }
    }
    return core.NewQVariant()
}

func setdata(index *core.QModelIndex, value *core.QVariant, role int) bool {
    if (role == 2 || role == 0) && index.IsValid() { // edit role
        list.Remove(index.Row())
        list.Insert(index.Row(), value.ToString())
        return true
    }
    return true
}

func insertrows(row int, count int, parent *core.QModelIndex) bool {
    model.BeginInsertRows(core.NewQModelIndex(), row, row) 
    list.Add("")
    model.EndInsertRows()
    view.SelectRow(row)
    return true
}

func removerows(row int, count int, parent *core.QModelIndex) bool {
    model.BeginRemoveRows(core.NewQModelIndex(), row, row)
    list.Remove(row)
    model.EndRemoveRows()
    return true
}

func flags(index *core.QModelIndex) core.Qt__ItemFlag {
    return 35 // ItemIsSelectable || ItemIsEditable || ItemIsEnabled
}

from qt.

therecipe avatar therecipe commented on September 24, 2024

Hey

I get this error list.Insert undefined (type *arraylist.List has no field or method Insert), while compiling your example.

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

There is an Insert method on arraylist.List: https://godoc.org/github.com/emirpasic/gods/lists/arraylist#List.Insert

Maybe if I change the variable name 'list' to 'listv'?

package main

import (
    "strconv"

    "github.com/emirpasic/gods/lists/arraylist"
    "github.com/therecipe/qt/core"
    "github.com/therecipe/qt/gui"
    "github.com/therecipe/qt/widgets"
)

var (
    listv *arraylist.List
    model *core.QAbstractTableModel // QAbstractItemModel
    view  *widgets.QTableView

    textIndex  *core.QModelIndex
    currentRow int
)

type Delegate struct {
    widgets.QStyledItemDelegate //don't use *pointers or it won't work
}

func NewArgsTable() *widgets.QTableView {
    view = widgets.NewQTableView(nil)        // setObjectName
    model = core.NewQAbstractTableModel(nil) // NewQAbstractItemModel(nil)

    delegate := InitDelegate()
    view.SetItemDelegate(delegate)
    view.SetFont(gui.NewQFont2("verdana", 13, 1, false))

    view.ConnectKeyPressEvent(keypressevent)
    view.ConnectCurrentChanged(currentchanged)

    model.ConnectRowCount(rowcount)
    model.ConnectColumnCount(columncount)
    model.ConnectData(data)
    model.ConnectSetData(setdata)
    model.ConnectInsertRows(insertrows)
    model.ConnectFlags(flags)
    model.ConnectRemoveRows(removerows)
    model.ConnectHeaderData(headerdata)

    listv = arraylist.New()

    for i := 0; i < 6; i++ {
        listv.Add(strconv.Itoa(i + i))
    }
    listv.Add("") // blank
    view.SetModel(model)
    return view

}

func keypressevent(e *gui.QKeyEvent) {
    if e.Key() == int(core.Qt__Key_Delete) {
        if currentRow < listv.Size()-1 {
            model.RemoveRows(currentRow, 1, core.NewQModelIndex())
        }
    } else {
        view.KeyPressEventDefault(e)
    }
}

func currentchanged(current *core.QModelIndex, previous *core.QModelIndex) {
    currentRow = current.Row()
}

func InitDelegate() *Delegate {
    item := NewDelegate(nil) //will be generated in moc.go
    item.ConnectCreateEditor(createEditor)
    item.ConnectSetEditorData(setEditorData)
    item.ConnectSetModelData(setModelData)
    item.ConnectUpdateEditorGeometry(updateEditorGeometry)
    return item
}

func createEditor(parent *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) *widgets.QWidget {
    editor := widgets.NewQLineEdit(parent)
    textIndex = index

    if index.Row() == listv.Size()-1 {
        model.InsertRow(index.Row(), core.NewQModelIndex())
    }
    editor.ConnectTextChanged(textchanged)
    return editor.QWidget_PTR()
}

func textchanged(text string) {
    model.SetData(textIndex, core.NewQVariant14(text), 2) // edit role = 2
}

func setEditorData(editor *widgets.QWidget, index *core.QModelIndex) {
    value, _ := listv.Get(index.Row())
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast
    lineedit.SetText(value.(string))
}

func setModelData(editor *widgets.QWidget, model *core.QAbstractItemModel, index *core.QModelIndex) {
    lineedit := widgets.NewQLineEditFromPointer(editor.Pointer()) //like static_cast
    text := lineedit.Text()
    model.SetData(index, core.NewQVariant14(text), int(core.Qt__EditRole))

}

func updateEditorGeometry(editor *widgets.QWidget, option *widgets.QStyleOptionViewItem, index *core.QModelIndex) {
    editor.SetGeometry(option.Rect())
}

func headerdata(section int, orientation core.Qt__Orientation, role int) *core.QVariant {
    if orientation == 1 && role == 0 { // Qt__Horizontal, Qt__DisplayRole
        return core.NewQVariant14("column" + strconv.Itoa(section+1))
    }
    if orientation == 2 && role == 0 {
        if section < listv.Size()-1 {
            return core.NewQVariant14(strconv.Itoa(section + 1))
        } else {
            return core.NewQVariant14("*")
        }
    }
    return core.NewQVariant()
}

func rowcount(parent *core.QModelIndex) int {
    return listv.Size()
}

func columncount(parent *core.QModelIndex) int {
    return 1
}

func data(index *core.QModelIndex, role int) *core.QVariant { // dataset to model/view
    if role == 0 && index.IsValid() { // display role = 0
        text, exists := listv.Get(index.Row())
        if exists {
            switch deducedText := text.(type) {
            case int:
                {
                    return core.NewQVariant7(deducedText)
                }
            case string:
                {
                    return core.NewQVariant14(deducedText)
                }
            }
        }
    }
    return core.NewQVariant()
}

func setdata(index *core.QModelIndex, value *core.QVariant, role int) bool { // model/view to dataset
    if (role == 2 || role == 0) && index.IsValid() { // edit role = 2
        listv.Remove(index.Row())
        listv.Insert(index.Row(), value.ToString())
        return true
    }
    return true
}

func insertrows(row int, count int, parent *core.QModelIndex) bool {
    model.BeginInsertRows(core.NewQModelIndex(), row, row) // count, count+row-1) //
    listv.Add("")
    model.EndInsertRows()
    view.SelectRow(row)

    return true
}

func removerows(row int, count int, parent *core.QModelIndex) bool {
    model.BeginRemoveRows(core.NewQModelIndex(), row, row) // count, count+row-1) //
    listv.Remove(row)
    model.EndRemoveRows()
    return true

}

func flags(index *core.QModelIndex) core.Qt__ItemFlag {
    return 35 // 1 || 2 || 32 // ItemIsSelectable || ItemIsEditable || ItemIsEnabled
}

from qt.

therecipe avatar therecipe commented on September 24, 2024

Sorry, I just had to update the arraylist package. It works now :)

Can I use this as a new example in internal/examples/widgets?

from qt.

5k3105 avatar 5k3105 commented on September 24, 2024

Yes of course. Thank you.

from qt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.