Comments (25)
Also, why did we have to put a (let ((i index))) around tthe bind lambda function?
Since the loop variables in loop
are mutable in most implementations, we need to make the closure immutably capture the index
so that different columns can access data with different column indexes.
from cl-gtk4.
I wasn't even using that version of cl-gobject-introspection. I spend hours debuggin that, It works now, thanks a bunch!
from cl-gtk4.
The (gobject:type-from-name "GtkLabel")
in your code returns 0
, which causes (gtk:make-list-store ...)
to return a null pointer.
from cl-gtk4.
To make (gobject:type-from-name "GtkLabel")
return a non-zero value, you need to get this type registered by the GObject system first. For example, you can move the (item1 (make-label :str "BRUHSEIDh"))
or add a seemingly meaningless (gtk:make-label :str "")
before it.
from cl-gtk4.
BTW, Gtk.ListStore
has been deprecated in version 4.10, and you should use gio:make-list-store
to create it instead.
from cl-gtk4.
I just added an example of a ListView
for your reference:
Lines 187 to 230 in ee766c2
from cl-gtk4.
Thank you so much! I wasn't expecting an answer. That's awesome, I will try it out right now.
from cl-gtk4.
In your example, gobj:coerce is not found. I will try and download from latest commit.
from cl-gtk4.
In your example, gobj:coerce is not found. I will try and download from latest commit.
It's in cl-glib. You may need to clone it manually or update your Ultralisp distribution.
from cl-gtk4.
Yup, I cloned cl-gtk4 and cl-glib and the example works now.
from cl-gtk4.
Okay, so ultimately I wanted to create a GtkColumnView. I got to this code:
(gtk:define-application (:name closting
:id "com.closting")
(gtk:define-main-window (window (gtk:make-application-window :application gtk:*application*))
(setf (gtk:window-title window) "Closting")
(let* ((main-model (gtk:make-string-list :strings '("HP Zbook 15" "250$" "300$"
"Infinix S90" "40$" "60$"
"Casio Calculator" "50$" "80$")))
(column-view (gtk:make-column-view :model (gtk:make-single-selection :model main-model)))
(col1-factory (gtk:make-signal-list-item-factory))
(col1 (gtk:make-column-view-column :title "First Col!" :factory col1-factory))
(col2-factory (gtk:make-signal-list-item-factory))
(col2 (gtk:make-column-view-column :title "Second Col!" :factory col2-factory))
(col3-factory (gtk:make-signal-list-item-factory))
(col3 (gtk:make-column-view-column :title "Third Col!" :factory col3-factory)))
(gtk:column-view-append-column column-view col1)
(gtk:column-view-append-column column-view col2)
(gtk:column-view-append-column column-view col3)
(setf (gtk:widget-vexpand-p column-view) t
(gtk:widget-hexpand-p column-view) t)
(flet ((setup (factory item)
(declare (ignore factory))
(setf (gtk:list-item-child item) (gtk:make-label :str "")))
(bind (factory item)
(declare (ignore factory))
(format t "POSSSS: ~a~%" (gtk:list-item-position item))
(when (zerop (mod (1+ (gtk:list-item-position item)) 3))
(setf (gtk:label-text (gobj:coerce (gtk:list-item-child item) 'gtk:label))
(gobj:value-string (gobj:coerce (gtk:list-item-item item) 'gtk:string-object)))))
(unbind (factory item) (declare (ignore factory item)))
(teardown (factory item) (declare (ignore factory item))))
(gtk:connect col1-factory "setup" #'setup)
(gtk:connect col1-factory "bind" #'bind)
(gtk:connect col1-factory "unbind" #'unbind)
(gtk:connect col1-factory "teardown" #'teardown))
(setf (gtk:window-child window) column-view))
(unless (gtk:widget-visible-p window)
(gtk:window-present window))))
But instead of getting every third value in each cell. I get a lot of blank cells. What I need is to somehow skip over elements in the model. Or how should I go about just creating a simple column view at all? Maybe I am doing it wrong. Also kindly inform me if this comment is out of the scope of this issue. I figured it isn't as ColumnView uses ListView. Thanks
Regards,
Hamza
from cl-gtk4.
You can use StringList
as the elements of your ListModel
:
(gtk:define-application (:name closting
:id "com.closting")
(gtk:define-main-window (window (gtk:make-application-window :application gtk:*application*))
(setf (gtk:window-title window) "Closting")
(let* ((rows (loop :for row :in '(("HP Zbook 15" "250$" "300$")
("Infinix S90" "40$" "60$")
("Casio Calculator" "50$" "80$"))
:collect (gtk:make-string-list :strings row)))
(main-model (gio:make-list-store :item-type (gobj:type-from-name "GtkStringList")))
(column-view (gtk:make-column-view :model (gtk:make-single-selection :model main-model)))
(col1-factory (gtk:make-signal-list-item-factory))
(col1 (gtk:make-column-view-column :title "First Col!" :factory col1-factory))
(col2-factory (gtk:make-signal-list-item-factory))
(col2 (gtk:make-column-view-column :title "Second Col!" :factory col2-factory))
(col3-factory (gtk:make-signal-list-item-factory))
(col3 (gtk:make-column-view-column :title "Third Col!" :factory col3-factory)))
(gtk:column-view-append-column column-view col1)
(gtk:column-view-append-column column-view col2)
(gtk:column-view-append-column column-view col3)
(loop :for row :in rows :do (gio:list-store-append main-model row))
(setf (gtk:widget-vexpand-p column-view) t
(gtk:widget-hexpand-p column-view) t)
(flet ((setup (factory item)
(declare (ignore factory))
(setf (gtk:list-item-child item) (gtk:make-label :str "")))
(unbind (factory item) (declare (ignore factory item)))
(teardown (factory item) (declare (ignore factory item))))
(loop :for factory :in (list col1-factory col2-factory col3-factory)
:for index :from 0
:do (gtk:connect factory "setup" #'setup)
(gtk:connect factory "unbind" #'unbind)
(gtk:connect factory "teardown" #'teardown)
(gtk:connect factory "bind"
(let ((i index))
(lambda (factory item)
(declare (ignore factory))
(setf (gtk:label-text (gobj:coerce (gtk:list-item-child item) 'gtk:label))
(gtk:string-list-get-string (gobj:coerce (gtk:list-item-item item) 'gtk:string-list) i)))))))
(setf (gtk:window-child window) column-view))
(unless (gtk:widget-visible-p window)
(gtk:window-present window))))
from cl-gtk4.
Thanks a lot! Just one final question, do you have any idea of how to store custom types in a list store? For example:
Instead of every row being a StringList, how can I make it something like:
(defclass product-info (gobject:object)
((name :initarg :name
:accessor name)
(cost :initarg :cost
:accessor cost)
(sale :initarg :sale
:accessor sale)))
This does not work as it says something about gobject:object being a forward referenced class, whatever that means...
from cl-gtk4.
If you don't require eql
to guarantee object equality, using print1-to-string
and read-from-string
seems to be the simplest way. Otherwise, you may need some mechanism to identify objects. For example:
- You can put objects in an array and use the array index to retrieve the object.
- Use a UUID library or similar to generate a unique integer or string identifier for an object, and use it as a key in a hash table to retrieve the object.
from cl-gtk4.
Also, why did we have to put a (let ((i index))) around tthe bind lambda function?
from cl-gtk4.
If you don't require
eql
to guarantee object equality, usingprint1-to-string
andread-from-string
seems to be the simplest way. Otherwise, you may need some mechanism to identify objects. For example:
- You can put objects in an array and use the array index to retrieve the object.
- Use a UUID library or similar to generate a unique integer or string identifier for an object, and use it as a key in a hash table to retrieve the object.
Wait, so what does equality have to do with having custom types?
from cl-gtk4.
Wait, so what does equality have to do with having custom types?
(eql (read-from-string (prin1-to-string '(1 2 3))) '(1 2 3)) ; => NIL
(equal (read-from-string (prin1-to-string '(1 2 3))) '(1 2 3)) ; => T
from cl-gtk4.
Okay, I get that, but I still don't understand how I would go about implementing this to make a new custom type.
from cl-gtk4.
This is a simple way you can use when you don't need eql
to guarantee object equality:
(defstruct product-info
name cost sale)
(gtk:define-application (:name closting
:id "com.closting")
(gtk:define-main-window (window (gtk:make-application-window :application gtk:*application*))
(setf (gtk:window-title window) "Closting")
(let* ((rows (loop :for (name cost sale) :in '(("HP Zbook 15" "250$" "300$")
("Infinix S90" "40$" "60$")
("Casio Calculator" "50$" "80$"))
:collect (prin1-to-string (make-product-info :name name :cost cost :sale sale))))
(main-model (gtk:make-string-list :strings rows))
(column-view (gtk:make-column-view :model (gtk:make-single-selection :model main-model)))
(col1-factory (gtk:make-signal-list-item-factory))
(col1 (gtk:make-column-view-column :title "First Col!" :factory col1-factory))
(col2-factory (gtk:make-signal-list-item-factory))
(col2 (gtk:make-column-view-column :title "Second Col!" :factory col2-factory))
(col3-factory (gtk:make-signal-list-item-factory))
(col3 (gtk:make-column-view-column :title "Third Col!" :factory col3-factory)))
(gtk:column-view-append-column column-view col1)
(gtk:column-view-append-column column-view col2)
(gtk:column-view-append-column column-view col3)
(setf (gtk:widget-vexpand-p column-view) t
(gtk:widget-hexpand-p column-view) t)
(flet ((setup (factory item)
(declare (ignore factory))
(setf (gtk:list-item-child item) (gtk:make-label :str "")))
(unbind (factory item) (declare (ignore factory item)))
(teardown (factory item) (declare (ignore factory item))))
(loop :for factory :in (list col1-factory col2-factory col3-factory)
:for accessor :in (list #'product-info-name #'product-info-cost #'product-info-sale)
:do (gtk:connect factory "setup" #'setup)
(gtk:connect factory "unbind" #'unbind)
(gtk:connect factory "teardown" #'teardown)
(gtk:connect factory "bind"
(let ((accessor accessor))
(lambda (factory item)
(declare (ignore factory))
(let ((row (read-from-string (gtk:string-object-string (gobj:coerce (gtk:list-item-item item) 'gtk:string-object)))))
(setf (gtk:label-text (gobj:coerce (gtk:list-item-child item) 'gtk:label)) (funcall accessor row))))))))
(setf (gtk:window-child window) column-view))
(unless (gtk:widget-visible-p window)
(gtk:window-present window))))
from cl-gtk4.
Ohhhhhhh, Thanks once again! I couldn't have thought of that.
from cl-gtk4.
If you want to get the same object under EQL comparison, or other unreadable objects in the bind
signal handler, I prefer using UUIDs to identify objects:
(defstruct product-info
name cost sale)
(gtk:define-application (:name closting
:id "com.closting")
(gtk:define-main-window (window (gtk:make-application-window :application gtk:*application*))
(setf (gtk:window-title window) "Closting")
(let ((product-table (make-hash-table :test #'equal)))
(let* ((rows (loop :for (name cost sale) :in '(("HP Zbook 15" "250$" "300$")
("Infinix S90" "40$" "60$")
("Casio Calculator" "50$" "80$"))
:for product-info := (make-product-info :name name :cost cost :sale sale)
:for uuid := (prin1-to-string (uuid:make-v1-uuid))
:do (setf (gethash uuid product-table) product-info)
:collect uuid))
(main-model (gtk:make-string-list :strings rows))
(column-view (gtk:make-column-view :model (gtk:make-single-selection :model main-model)))
(col1-factory (gtk:make-signal-list-item-factory))
(col1 (gtk:make-column-view-column :title "First Col!" :factory col1-factory))
(col2-factory (gtk:make-signal-list-item-factory))
(col2 (gtk:make-column-view-column :title "Second Col!" :factory col2-factory))
(col3-factory (gtk:make-signal-list-item-factory))
(col3 (gtk:make-column-view-column :title "Third Col!" :factory col3-factory)))
(gtk:column-view-append-column column-view col1)
(gtk:column-view-append-column column-view col2)
(gtk:column-view-append-column column-view col3)
(setf (gtk:widget-vexpand-p column-view) t
(gtk:widget-hexpand-p column-view) t)
(flet ((setup (factory item)
(declare (ignore factory))
(setf (gtk:list-item-child item) (gtk:make-label :str "")))
(unbind (factory item) (declare (ignore factory item)))
(teardown (factory item) (declare (ignore factory item))))
(loop :for factory :in (list col1-factory col2-factory col3-factory)
:for accessor :in (list #'product-info-name #'product-info-cost #'product-info-sale)
:do (gtk:connect factory "setup" #'setup)
(gtk:connect factory "unbind" #'unbind)
(gtk:connect factory "teardown" #'teardown)
(gtk:connect factory "bind"
(let ((accessor accessor))
(lambda (factory item)
(declare (ignore factory))
(let* ((uuid (gtk:string-object-string (gobj:coerce (gtk:list-item-item item) 'gtk:string-object)))
(row (gethash uuid product-table)))
(setf (gtk:label-text (gobj:coerce (gtk:list-item-child item) 'gtk:label)) (funcall accessor row))))))))
(setf (gtk:window-child window) column-view)))
(unless (gtk:widget-visible-p window)
(gtk:window-present window))))
from cl-gtk4.
Oh, that's a really cool solution. Will definitely use that!
from cl-gtk4.
Okay, even though you closed this, I get unhandled memory errors from this:
(defun create-financial-module-column-view (columns data)
(let* ((string-list-data (loop :for row :in data
:collect (gtk:make-string-list :strings row)))
(main-model (gio:make-list-store :item-type (gobj:type-from-name "GtkStringList")))
(column-view (gtk:make-column-view :model (gtk:make-single-selection :model main-model))))
(setf (gtk:widget-vexpand-p column-view) t
(gtk:widget-hexpand-p column-view) t)
;; TEMPORARY
(setf (gtk:column-view-reorderable-p column-view) t)
(loop :for row :in string-list-data
:do (gio:list-store-append main-model row))
(loop :for column-name :in columns
:for index :from 0
:do (let* ((col-factory (gtk:make-signal-list-item-factory))
(column (gtk:make-column-view-column :title column-name :factory col-factory)))
(setf (gtk:column-view-column-resizable-p column) t)
(flet ((setup (factory item)
(declare (ignore factory))
(setf (gtk:list-item-child item) (gtk:make-label :str "DEFAULT")))
(unbind (factory item) (declare (ignore factory item)))
(teardown (factory item) (declare (ignore factory item))))
(gtk:connect col-factory "setup" #'setup)
(gtk:connect col-factory "unbind" #'unbind)
(gtk:connect col-factory "teardown" #'teardown)
(gtk:connect col-factory "bind" ;(lambda (factory item) (declare (ignore factory item)))
(let ((i index))
(lambda (factory item)
(declare (ignore factory))
(format t "PLEAAAAAASEWORKKKK: ~a~%" (gobj:coerce (gtk:list-item-child item) 'gtk:label))
;; (setf (gtk:label-text (gobj:coerce (gtk:list-item-child item) 'gtk:label))
;; (format nil "BRUHRHRUHRUHRUHR, ~a~%" i)
;; ;; (gtk:string-list-get-string (gobj:coerce (gtk:list-item-item item)
;; ;; 'gtk:string-list)
;; ;; i)
;; )
))))
(gtk:column-view-append-column column-view column)))
column-view))
I narrowed the error down to using gobj:coerce to convert from (gtk:list-item-item item) to 'gtk:label. Why does this happen? As a hint, when run another time, it runs normally. Weirdly this causes annoying sbcl errors and I have to restart the REPL.
from cl-gtk4.
This may be a memory issue caused by the garbage collector. Please refer to #20 (comment). Could you update cl-gobject-introspection and try again?
from cl-gtk4.
Okay.
from cl-gtk4.
Related Issues (20)
- Could you make the library interface more declarative? HOT 11
- DSL for Cairo library. HOT 1
- Can't install CL-GTK.WEBKIT HOT 1
- Returning from dialogs HOT 1
- Error Building via Github Actions HOT 4
- Can't load the library HOT 1
- What about Cairo in Lisp? HOT 3
- Can't make a GStream binding. HOT 1
- Typelib file for namespace 'Gtk', version '4.0' not found HOT 4
- How to make a GListStore of fixnums / How to subclass GObject HOT 2
- Library needs more documentation HOT 1
- Can't create simple application. HOT 4
- FLOATING-POINT-INVALID-OPERATION HOT 5
- arithmetic error DIVISION-BY-ZERO signalled HOT 2
- Cant create wigets to store it in variable HOT 1
- When vertically scaling the window, there is an artifact with the buttons. HOT 1
- No symbol named "POINTER-OBJECT" HOT 2
- Error g_error_free on Windows 11 HOT 6
- Can't properly pass "user_data" to callback for open file dialog HOT 2
- Support for Subclassing? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cl-gtk4.