DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

[DZone Research] Observability + Performance: We want to hear your experience and insights. Join us for our annual survey (enter to win $$).

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Queue in Data Structures and Algorithms
  • Effective Java Collection Framework: Best Practices and Tips
  • MLOps: Definition, Importance, and Implementation
  • Python Stack Data Structure: A Versatile Tool for Real-time Applications

Trending

  • What Is a Flaky Test?
  • A Guide To Multithreading in SQL
  • Wild West to the Agile Manifesto [Video]
  • Build a Flow Collectibles Portal Using Cadence (Part 2)
  1. DZone
  2. Data Engineering
  3. Data
  4. wxPython: Moving Items in ObjectListView

wxPython: Moving Items in ObjectListView

In this post, we take a look at how you might implement drag-and-drop in wx.ListCtrl or ObjectListView in Python. Read on to find out how and see some code!

Mike Driscoll user avatar by
Mike Driscoll
·
Nov. 20, 17 · Tutorial
Like (1)
Save
Tweet
Share
7.04K Views

Join the DZone community and get the full member experience.

Join For Free

i was recently asked about how to implement drag-and-drop of items in a wx.listctrl or in objectlistview . unfortunately, neither control has this built-in although i did find an article on the wxpython wiki that demonstrated one way to do drag-and-drop of the items in a listctrl.

however, i did think that implementing some buttons to move items around in an objectlistview widget should be fairly easy to implement. so that’s what this article will be focusing on.

changing item order

image title

if you don’t have wxpython and objectlistview installed, then you will want to use pip to install them:

pip install wxpython objectlistview

once that is done, open up your favorite text editor or ide and enter the following code:

import wx
from objectlistview import objectlistview, columndefn


class book(object):
    """
    model of the book object
    contains the following attributes:
    'isbn', 'author', 'manufacturer', 'title'
    """

    def __init__(self, title, author, isbn, mfg):
        self.isbn = isbn
        self.author = author
        self.mfg = mfg
        self.title = title

    def __repr__(self):
        return "<book: {title}>".format(title=self.title)


class mainpanel(wx.panel):

    def __init__(self, parent):
        wx.panel.__init__(self, parent=parent, id=wx.id_any)
        self.current_selection = none
        self.products = [book("wxpython in action", "robin dunn",
                              "1932394621", "manning"),
                         book("hello world", "warren and carter sande",
                              "1933988495", "manning"),
                         book("core python programming", "wesley chun",
                             "0132269937", "prentice hall"),
                         book("python programming for the absolute beginner",
                              "michael dawson", "1598631128",
                              "course technology"),
                         book("learning python", "mark lutz",
                              "0596513984", "o'reilly")
                         ]

        self.dataolv = objectlistview(self, wx.id_any, 
                                      style=wx.lc_report|wx.sunken_border)
        self.setbooks()

        # allow the cell values to be edited when double-clicked
        self.dataolv.celleditmode = objectlistview.celledit_singleclick

        # create up and down buttons
        up_btn = wx.button(self, wx.id_any, "up")
        up_btn.bind(wx.evt_button, self.move_up)

        down_btn = wx.button(self, wx.id_any, "down")
        down_btn.bind(wx.evt_button, self.move_down)

        # create some sizers
        mainsizer = wx.boxsizer(wx.vertical)

        mainsizer.add(self.dataolv, 1, wx.all|wx.expand, 5)
        mainsizer.add(up_btn, 0, wx.all|wx.center, 5)
        mainsizer.add(down_btn, 0, wx.all|wx.center, 5)
        self.setsizer(mainsizer)

    def move_up(self, event):
        """
        move an item up the list
        """        
        self.current_selection = self.dataolv.getselectedobject()
        data = self.dataolv.getobjects()
        if self.current_selection:
            index = data.index(self.current_selection)
            if index > 0:
                new_index = index - 1
            else:
                new_index = len(data)-1
            data.insert(new_index, data.pop(index))
            self.products = data
            self.setbooks()
            self.dataolv.select(new_index)

    def move_down(self, event):
        """
        move an item down the list
        """
        self.current_selection = self.dataolv.getselectedobject()
        data = self.dataolv.getobjects()
        if self.current_selection:
            index = data.index(self.current_selection)
            if index < len(data) - 1:
                new_index = index + 1
            else:
                new_index = 0
            data.insert(new_index, data.pop(index))
            self.products = data
            self.setbooks()
            self.dataolv.select(new_index)

    def setbooks(self):
        self.dataolv.setcolumns([
            columndefn("title", "left", 220, "title"),
            columndefn("author", "left", 200, "author"),
            columndefn("isbn", "right", 100, "isbn"),
            columndefn("mfg", "left", 180, "mfg")
        ])

        self.dataolv.setobjects(self.products)


class mainframe(wx.frame):
    def __init__(self):
        wx.frame.__init__(self, parent=none, id=wx.id_any, 
                          title="objectlistview demo", size=(800,600))
        panel = mainpanel(self)
        self.show()


if __name__ == "__main__":
    app = wx.app(false)
    frame = mainframe()
    app.mainloop()

the code we care about most in this example are the move_up() and move_down() methods. each of these methods will check to see if you have an item in the objectlistview widget selected. it will also grab the current contents of the widgets. if you have an item selected, then it will grab that item’s index from the objectlistview widget’s data that we grabbed when we called getobjects() . then we can use that index to determine whether we should increment (move_down) or decrement (move_up) its index depending on which of the buttons we press.

after we update the list with the changed positions, then we update self.products , which is our class variable that we use in the setbooks() to update our objectlistview widget. finally we actually call setbooks() and we reset the selection since our original selection moved.

wrapping up

i thought this was a neat little project that didn’t take very long to put together. i will note that there is at least one issue with this implementation and that is that it doesn’t work correctly when you select multiple items in the control. you could probably fix this by disabling multiple selection in your objectlistview widget or by figuring out the logic to make it work with multiple selections. but i will leave that up the reader to figure out. have fun an happy coding!

Text editor Grab (software) Coding (social sciences) Data (computing) Reset (computing) Implementation

Published at DZone with permission of Mike Driscoll, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Queue in Data Structures and Algorithms
  • Effective Java Collection Framework: Best Practices and Tips
  • MLOps: Definition, Importance, and Implementation
  • Python Stack Data Structure: A Versatile Tool for Real-time Applications

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: