Nieuws:

Ubuntu-NL weer online!

Na een periode van technische problemen en een overbelaste server zijn we eindelijk weer bereikbaar.
Samen met Hobbynet, onze sponsor en hostingpartner, hebben we een oplossing gevonden zodat alles weer soepel draait.

Bedankt voor jullie geduld en begrip. We hopen nu weer verder te gaan waar we gebleven waren.

Het team van Ubuntu-NL

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: python tkinter listbox selecteer en highlight eerste item  (gelezen 2909 keer)

Offline peer

  • Lid
python tkinter listbox selecteer en highlight eerste item
« Gepost op: 2025/11/22, 15:21:57 »
Ik heb een python programma  shutdown met keuzemogelijkheden shutdown, reboot en logout en een countdowntimer.
Ik  gebruik tkinter. In de bijlage is een voorbeeld van het window met daarin de drie keuzemogelijkheden, direct na het starten van de programmaatje.

De eerste optie (shutdown) is hier geselecteerd maar niet gehighlight. Met de pijltjestoetsen kan ik de andere opties selecteren maar die worden ook niet gehighlight.

Als ik met de muis op één van de opties klik dan wordt deze geselecteerd en gehighlight. Daarna kan ik zowel met de muis als met de pijltjestoetsen een andere optie kiezen waarbij deze zowel geselecteerd wordt als gehighlight.


Hoe kan ik mijn programmaa aanpassen zodat bij start de eerste optie geselecteerd wordt èn gehighlight?


Hier is het programma:
#!/usr/bin/env python3
import subprocess
import tkinter as tk
import os
import re

# constants
MAXTIME=30
# global variables
selection = 0
isOk = False
timer = MAXTIME

# get screenresolution
output = subprocess.Popen('xrandr | grep "\*" | cut -d" " -f4',shell=True, stdout=subprocess.PIPE).communicate()[0] #get resolutions
output = re.split(r'[^\w]', str(output)) #remove special characters
output=output[1] #get first resolution
output=output.split('x') # split in [x,y]
maxX=int(output[0])
maxY=int(output[1])

# set workdirectory
os.chdir(os.path.dirname(__file__))


# show the shutdown selection window
root = tk.Tk()
root.title("Shutdown")
root.iconphoto(False, tk.PhotoImage(file='shutdown.png'))

Tk_Width = 400
Tk_Height = 200
x_Left = int(maxX/2 - Tk_Width/2)
y_Top = int(maxY/2 - Tk_Height/2)
root.geometry("+{}+{}".format(x_Left, y_Top))   
root.resizable(False, False)

# set timeText variable for showing countdown
timeText = tk.StringVar()
timeText.set(str(timer))
# countdown timer
def countdown():
    global timer
    if timer == 0:
        okAction(0)
    timer = timer - 1
    timeText.set(str(timer))
    root.after(1000,countdown)
   
# reset timer after selection 
def setSelected(event):
    global timer
    global selection
    timer = MAXTIME
    timeText.set(str(timer))
    selected_indices = List.curselection()
    try:
        selection = selected_indices[0] 
    except:
        selection = 0       
# cancelButton action
def cancelAction(event):
    global isOk
    isOk = False         
    root.quit()
# okButton action
def okAction(event):
    global selection
    global isOk
    isOk = True
    selected_indices = List.curselection()
    selection = selected_indices[0] 
    root.quit()
#Up action
def upAction(event):
    global timer
    global selection
    timer = MAXTIME
    timeText.set(str(timer))
    selected_indices = List.curselection()
    index = selected_indices[0]
    List.select_clear(index)
    if index > 0:
        index = index - 1
    List.select_clear(0, 2)
    List.selection_set(index)
    List.see(index)
    List.activate(index)
    selected_indices = List.curselection()
    selection = selected_indices[0]
#Down action
def downAction(event):
    global timer
    global selection
    timer = MAXTIME
    timeText.set(str(timer))
    selected_indices = List.curselection()
    index = selected_indices[0]
    List.select_clear(index)
    if index < 2:
        index = index + 1   
    List.selection_set(index)
    List.see(index)
    List.activate(index)
    selected_indices = List.curselection()
    selection = selected_indices[0]
   
   
List_border = tk.Frame(root, bd=1, relief="sunken", background="#EFF0F1")                 
List = tk.Listbox(List_border, font=("Arial", 14), width=25, height=3, selectmode=tk.SINGLE, borderwidth=0, highlightthickness=0 )
List.insert(1, "                  Shutdown")
List.insert(2, "                   Reboot")
List.insert(3, "                   Logout")
List.selection_set(0)

List.bind('<<ListboxSelect>>', setSelected)
List.bind('<Up>', upAction)
List.bind('<Down>', downAction)
List.bind('<Return>', okAction)
List.bind('<KP_Enter>', okAction)
List.bind('<Escape>', cancelAction)

cancelButton = tk.Button(root, text="Cancel", font=("Arial", 14), height = 1, width = 6, command=lambda: cancelAction(0))
timeLabel = tk.Label(root, textvariable = timeText, font=("Arial", 14), height = 1, width = 6)
okButton = tk.Button(root, text="OK", font=("Arial", 14), height = 1, width = 6, command=lambda: okAction(0))

List_border.grid(row=0,column=0,columnspan=3)
List.pack(padx=10, pady=20, fill="both", expand=True)   
cancelButton.grid(row=1,column=0)
timeLabel.grid(row=1,column=1)
okButton.grid(row=1,column=2)

List.focus()

root.after(1000,countdown)
root.mainloop()   
   

# the actual shutdown, reboot and logout commands
if isOk == True:
    if selection == 0:
        # poweroff shutdown
        bashCommand = "/usr/bin/systemctl poweroff"
    elif selection == 1:
        # poweroff reboot
        bashCommand = "/usr/bin/systemctl reboot"
    elif selection == 2:   
        # logout
        userName = subprocess.run(["whoami"],stdout=subprocess.PIPE, text=True)
        userName = userName.stdout
        bashCommand = "pkill -KILL -u " + userName
    subprocess.run(bashCommand.split())       
















Offline bart85

  • Lid
Re: python tkinter listbox selecteer en highlight eerste item
« Reactie #1 Gepost op: 2025/11/22, 16:24:40 »
Je leert maar mooi over weg gaan met de commandline.
Linus: "I'm happy with the people who are wandering around looking at the stars but I am looking at the ground and I want to fix the pothole before I fall in."
I look to the clouds behind me and see the thunder coming.

Offline bart85

  • Lid
Re: python tkinter listbox selecteer en highlight eerste item
« Reactie #2 Gepost op: 2025/11/22, 16:38:48 »
select_set

Deze methode is voor selecteren
Je leert maar mooi over weg gaan met de commandline.
Linus: "I'm happy with the people who are wandering around looking at the stars but I am looking at the ground and I want to fix the pothole before I fall in."
I look to the clouds behind me and see the thunder coming.

Offline peer

  • Lid
Re: python tkinter listbox selecteer en highlight eerste item
« Reactie #3 Gepost op: 2025/11/22, 18:32:51 »
select_set is in het programma te zien maar geeft juist de selectiie zonder highlight
activate heb ik ook geprobeerd maar dat werkt ook niet

Offline peer

  • Lid
Re: python tkinter listbox selecteer en highlight eerste item
« Reactie #4 Gepost op: 2025/11/23, 16:18:42 »
na wat uitproberen en checken denk ik dat het probleem zit in het duiden van de variabelen in tkinter. Als ik een item selecteer en daarna kijk welk item geselecteerd is dan wordt het niet gevonden. Vermoedelijk omdat ik niet met de self-variabele heet dat zo?) gewerkt heb. Er zitten verder nog wat andere foutjes in dus ik denk dat ik maar ovenieuw ga beginnen (het was ook al een wat ouder programma) en dan overstap op pyqt6. Dat ziet er gelijk ook een stuk beter uit op mijn pc.   

Offline peer

  • Lid
Re: python tkinter listbox selecteer en highlight eerste item
« Reactie #5 Gepost op: 2025/11/24, 16:13:38 »
ik heb het python programmaatje opniew gemaakt maar nu in pyqt6.

Eerst wordt er gecheckt of er een qemu VM draait. Als dit het geval is komt er een popupmelding dat de vm eerst gesloten moet worden en het shutdown programma wordt gestopt.
Als er geen VM draait dan verschijnt een window met de keuzeopties Shutdown, Reboot en Logout. Tevens is er een teller die na 30 seconden de gekozen optie uitvoert.

De VM-check en de 30 seconden terminn waren voor mij de reden om dit shutdownprogrammaatje te maken.
Hier is het shutdown programma:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Nov 22 13:31:32 2025

@author: peer
"""

import psutil, sys, subprocess
from PyQt6.QtWidgets import (QApplication, QMessageBox, QWidget, QGridLayout,
                             QListWidget, QListWidgetItem, QPushButton,  QLabel)
from PyQt6.QtCore import Qt, QTimer


# check if VM is running (vmIsRunning = True/False)
vmIsRunning = False
for process in psutil.process_iter(['pid', 'name']):
    if "qemu-system-x86_64" in process.name():
        vmIsRunning = True

#show message if vm is running and exit
if vmIsRunning == True:
    app = QApplication(sys.argv)
    title = "Error: VM is running"
    text = "\nA Qemu VM is still running.\nClose the VM before shutting down."
    QMessageBox.critical( None, title, text)
    del app, QMessageBox
    sys.exit()
   
   

# start window with listWidget and timer

#constants
MAXTIME = 30

#global variables
selection = 0
isOk = False
counter = MAXTIME
teller = 0

if vmIsRunning == False:

    class MainWindow(QWidget):
       
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
   
            self.setWindowTitle('Shutdown')
            self.setGeometry(100, 100, 240, 160)
   
            layout = QGridLayout(self)
            self.setLayout(layout)
   
            # create listWidget
            self.listWidget = QListWidget(self)
            item0 = QListWidgetItem("Shutdown")
            item1 = QListWidgetItem("Reboot")
            item2 = QListWidgetItem("Logout")
            item0.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            item1.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            item2.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
            self.listWidget.insertItem(0, item0)
            self.listWidget.insertItem(1, item1)
            self.listWidget.insertItem(2, item2)           
            self.listWidget.setCurrentItem(item0)   
             
            # create buttons and label
            self.cancelButton = QPushButton('Cancel')
            self.cancelButton.clicked.connect(self.cancel)
            self.okButton = QPushButton('OK')
            self.okButton.clicked.connect(self.ok)
            self.counterLabel = QLabel(str(MAXTIME))
            self.counterLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
   
            # fill layout
            layout.addWidget(self.listWidget, 0, 0, 1, 3)
            layout.addWidget(self.cancelButton, 1, 0)
            layout.addWidget(self.counterLabel, 1, 1)
            layout.addWidget(self.okButton, 1, 2)
   
            # define timer
            self.timer = QTimer()
            self.timer.timeout.connect(self.timerCheck)
           
            self.timer.start(100)
   
            # show the window
            self.show()
             
        def cancel(self):
            self.close()
   
        def ok(self):
            # close and store isOk and selection
            global isOk,selection
            isOk = True
            selection = self.listWidget.currentRow()
            self.close()
           
        def timerCheck(self):
            global selection, counter, teller
            # teller/count block
            teller += 1         
            if teller == 10:
                counter -= 1
                teller = 0
                self.counterLabel.setText(str(counter))
            # check if selection has changed, update selection and counter   
            if selection != self.listWidget.currentRow():
                selection = self.listWidget.currentRow()
                counter = MAXTIME
                self.counterLabel.setText(str(counter))
            # close window
            if counter == 0:
                self.ok()
   
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = MainWindow()
        #sys.exit(app.exec())
        app.exec()
       

#isOk = True: continu with shutdown
# selection 0 = Shutdown; 1 = Reboot; 2 = Logout
# the actual shutdown, reboot and logout commands
if isOk == True:
    if selection == 0:
        # poweroff shutdown
        bashCommand = "/usr/bin/systemctl poweroff"
    elif selection == 1:
        # poweroff reboot
        bashCommand = "/usr/bin/systemctl reboot"
    elif selection == 2:   
        # logout
        userName = subprocess.run(["whoami"],stdout=subprocess.PIPE, text=True)
        userName = userName.stdout
        bashCommand = "pkill -KILL -u " + userName
    subprocess.run(bashCommand.split())       



Het werkt op mijn pc. Ik weet niet of het ook op andere pc's kan draaien. Het is nog een ruwe versie. Ik moet het nog wat gaan verfijnen.