Python Forum
[PyGUI] From comand line to GUI
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGUI] From comand line to GUI
#1
Command line to GUI!
Hi! I am working as a teacher in a school in Sweden. I have created a simpel program that takes a date and then calculates the next date. The dates are in a list and very simple takes the tenth date and prints it out in console. I would like to have a more usable program, GUI for this task, but i am struggeling to make it funktione.
#A list with possible dates for a visit  

 
visit2 = ["2019-10-14","2019-10-15","2019-10-16","2019-10-17","2019-10-18","2019-10-21","2019-10-22","2019-10-23","2019-10-24","2019-10-25","2019-11-07","2019-11-08","2019-11-14","2019-11-15","2019-11-21","2019-11-28","2019-11-29","2019-12-05","2019-12-06","2019-12-12","2019-12-13","2019-12-16","2019-12-17","2019-12-18","2019-12-19","2020-01-15","2020-01-16","2020-01-23","2020-01-24","2020-01-30","2020-01-31","2020-02-06","2020-02-07","2020-02-13","2020-02-14","2020-02-17","2020-02-18","2020-02-19","2020-02-20","2020-02-21","2020-03-02","2020-03-03","2020-03-04","2020-03-05","2020-03-06","2020-03-09","2020-03-10","2020-03-11","2020-03-12","2020-03-13","2020-03-19","2020-03-20","2020-03-26","2020-03-27","2020-04-02","2020-04-03","2020-04-09","2020-04-24","2020-04-30","2020-05-07","2020-05-08","2020-05-15","2020-05-25","2020-05-26","2020-05-27","2020-05-28","2020-05-29","2020-06-01","2020-06-02","2020-06-03","2020-06-04","2020-06-05"]


date = (input("When was the last visit?: Use YYYY-MM-DD syntax: ")) 
print() 

#When you done a visit and you done the input, next visit prints out in console , it should be aproximative every 10 day


print("Well the next visit should be at: "+visit2[visit2.index(date)+10])
The nerest i have come today whith tkinter and Qt is
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 10 19:05:50 2019

@author: Mats
"""

import tkinter
from tkinter import *

root=Tk()
root.title('mats')
sizex = 400
sizey = 300

root.wm_geometry("%dx%d" % (sizex, sizey))

F1 = tkinter.Frame()


s = tkinter.Scrollbar(F1)
L = tkinter.Listbox(F1)

s.pack(side=tkinter.RIGHT, fill=tkinter.Y)
L.pack(side=tkinter.LEFT, fill=tkinter.Y)

s['command'] = L.yview
L['yscrollcommand'] = s.set



itemsforlistbox=['2019-10-14','2019-10-15','2019-10-16','2019-10-17','2019-10-18','2019-10-21','2019-10-22','2019-10-23','2019-10-24','2019-10-25','2019-11-07','2019-11-08','2019-11-14','2019-11-15','2019-11-21','2019-11-28','2019-11-29','2019-12-05','2019-12-06','2019-12-12','2019-12-13','2019-12-16','2019-12-17','2019-12-18','2019-12-19','2020-01-15','2020-01-16','2020-01-23','2020-01-24','2020-01-30','2020-01-31','2020-02-06','2020-02-07','2020-02-13','2020-02-14','2020-02-17','2020-02-18','2020-02-19','2020-02-20','2020-02-21','2020-03-02','2020-03-03','2020-03-04','2020-03-05','2020-03-06','2020-03-09','2020-03-10','2020-03-11','2020-03-12','2020-03-13','2020-03-19','2020-03-20','2020-03-26','2020-03-27','2020-04-02','2020-04-03','2020-04-09','2020-04-24','2020-04-30','2020-05-07','2020-05-08','2020-05-15','2020-05-25','2020-05-26','2020-05-27','2020-05-28','2020-05-29','2020-06-01','2020-06-02','2020-06-03','2020-06-04','2020-06-05']



for items in itemsforlistbox:
    L.insert(END,items)





F1.pack(side=tkinter.TOP)

F2 = tkinter.Frame()
mats = tkinter.Label(F2)

def poll():
    mats.after(200, poll)
    sel = L.curselection()

   
    mats.config(text=str(sel))
   
    

mats.pack()
F2.pack(side=tkinter.TOP)

poll()
root.mainloop()
And something similar with Qt
import sys

from PyQt5.QtWidgets import QWidget, QListWidget, QMessageBox, QApplication

class MyWindow(QWidget):
    """Main Window class for our application"""

    def __init__(self):
        """Class konstruktor"""
        super().__init__()

        self.init_gui()

    def init_gui(self):
        """Skapa gränssnitt"""

        # Sätt fönsteregenskaper

        self.resize(400,200)
        self.move(50,50)
        self.setWindowTitle("APL-Besök")

        # Skapa listkontroll

        self.list_box = QListWidget(self)
        self.list_box.move(20,20)
        self.list_box.resize(100,100)

        # Lägg till alternativ i listan

        itemsforlistbox=['2019-10-14','2019-10-15','2019-10-16','2019-10-17','2019-10-18','2019-10-21','2019-10-22','2019-10-23','2019-10-24','2019-10-25','2019-11-07','2019-11-08','2019-11-14','2019-11-15','2019-11-21','2019-11-28','2019-11-29','2019-12-05','2019-12-06','2019-12-12','2019-12-13','2019-12-16','2019-12-17','2019-12-18','2019-12-19','2020-01-15','2020-01-16','2020-01-23','2020-01-24','2020-01-30','2020-01-31','2020-02-06','2020-02-07','2020-02-13','2020-02-14','2020-02-17','2020-02-18','2020-02-19','2020-02-20','2020-02-21','2020-03-02','2020-03-03','2020-03-04','2020-03-05','2020-03-06','2020-03-09','2020-03-10','2020-03-11','2020-03-12','2020-03-13','2020-03-19','2020-03-20','2020-03-26','2020-03-27','2020-04-02','2020-04-03','2020-04-09','2020-04-24','2020-04-30','2020-05-07','2020-05-08','2020-05-15','2020-05-25','2020-05-26','2020-05-27','2020-05-28','2020-05-29','2020-06-01','2020-06-02','2020-06-03','2020-06-04','2020-06-05']

        for items in itemsforlistbox:
             self.list_box.addItem(items)



      #  for i in range(100):
       #     self.list_box.addItem("Alternativ %d" % i)

        # Sätt standardalternativet till rad 0

        self.list_box.setCurrentRow(0)

        # Koppla en händelsemetod till signal

        self.list_box.currentRowChanged.connect(self.on_current_row_changed)

    def on_current_row_changed(self, curr):
        """Hantera signalen currentRowChanged"""

        QMessageBox.information(self, "Meddelande", "Senaste besöket: " + str(curr))
        QMessageBox.information(self, "Meddelande", "Nästa besök: " + self.list_box.currentItem().text())
        

"""
    def CurSelet(event):
        widget = event.widget
        selection=widget.curselection()
        picked = widget.get(selection[0]+10)
        print(picked)
"""








if __name__ == '__main__':

    app = QApplication(sys.argv)

    window = MyWindow()
    window.show()

    sys.exit(app.exec_())
Instead of the index, I want the value that is indexed.
Reply
#2
An improvement for your date-finder.

def get_next_date(visit_dates, visit_after, next_visit=10):
    # this could convert visit_dates and visit_after from
    # iso8601 timestamp (str) to date objects
    # visit_dates = [datetime.date.fromisoformat(d) for d in visit_dates]
    # visit_after = datetime.date.fromisoformat(visit_after)
    try:
        # Exception 1: Item not in visit_dates -> ValueError
        #              The date was not in the list
        # Exception 2: Index > than length of list -> IndexError
        #              In this case, it comes from + 1
        #              Date was found, but no date after
        return visit_dates[visit_dates.index(visit_after) + next_visit]
        # If no Exception happens, it will return the result
    except (ValueError, IndexError):
        # Catching this two Exceptions
        pass
    # raise an ValueError instead of returning None or something else
    # Catch the ValueError Exception on the caller side.
    raise ValueError(f'No visit date after {visit_after}')
If you handle with workdays, repeating dates etc. you should look for dateutil
A tool to handle timezones: pendulum
Previous I used pytz, but I got the tip from here that pendulum is easier to use.

I did not look for the GUI-Code, but with a function you can handle it more dynamic.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
Okay if I understood your question this would be what you were looking for -- note I cleaned up the code and made it more Pythonic and Qt-ish and added a few explanations why some things were changed
USE_PYSIDE2 = False
if USE_PYSIDE2:
    from PySide2.QtCore    import Signal, Slot
    from PySide2.QtWidgets import QApplication, QVBoxLayout
    from PySide2.QtWidgets import QListWidget, QMessageBox
else:
    from PyQt5.QtCore    import pyqtSignal as Signal
    from PyQt5.QtCore    import pyqtSlot   as Slot
    from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
    from PyQt5.QtWidgets import QListWidget, QMessageBox
 
class MyWindow(QWidget):
    def __init__(self):
      # Do not use Super( ) it was made to handle a specific issue that 
      # rarely occurs and if you are not experiencing that rather specific
      # issue you are adding more potential issues by using Super( ) and
      # making your program more complex than it needs to be
        QWidget.__init__(self)
 
        Top = 150;Left = 200;Width=400;Hight=200
        self.setGeometry(Top,Left,Width,Hight)
        self.setWindowTitle('APL-Besök')
 
        # Skapa listkontroll
        self.lstDates = QListWidget(self)
        # Lägg till alternativ i listan
        ItemsForListBox = self.GetDateList()
        self.lstDates.addItems(ItemsForListBox)
        # Sätt standardalternativet till rad 0
        self.lstDates.setCurrentRow(0)
        # Koppla en händelsemetod till signal
        self.lstDates.currentRowChanged.connect(self.OnCurrentRowChanged)
        
        VBox = QVBoxLayout()
        VBox.addWidget(self.lstDates)
        
        self.setLayout(VBox)

  # While you can get away with not using the Slot decorator it can cause
  # issues and not using it is just lazy coding
    @Slot(int)
    def OnCurrentRowChanged(self, RowNum):
      # If doing simple debugging or proof of concept prints are simpler
        print('Meddelande : Senaste besöket : [',RowNum,']')
        print('Meddelande : Nästa besök : [',self.lstDates.currentItem().text(),']')
        print('Using the RowNum to Get Item Value [',self.lstDates.item(RowNum).text(),']')
      # Hantera signalen currentRowChanged
      #  Using str(Curr) might not get you want you want to know -- best to always just print
      #  the raw value (as done above) so you know exactly what you are getting
      #   QMessageBox.information(self, "Meddelande", "Senaste besöket: " + str(Curr))
      #   QMessageBox.information(self, "Meddelande", "Nästa besök: " + self.list_box.currentItem().text())

    def GetDateList(self):
      # Doing it this way so that how this List gets generated can be done as needed
      # without affecting the basic flow of the program
        DateList = ['2019-10-14','2019-10-15','2019-10-16','2019-10-17','2019-10-18','2019-10-21','2019-10-22','2019-10-23','2019-10-24','2019-10-25','2019-11-07','2019-11-08','2019-11-14','2019-11-15','2019-11-21','2019-11-28','2019-11-29','2019-12-05','2019-12-06','2019-12-12','2019-12-13','2019-12-16','2019-12-17','2019-12-18','2019-12-19','2020-01-15','2020-01-16','2020-01-23','2020-01-24','2020-01-30','2020-01-31','2020-02-06','2020-02-07','2020-02-13','2020-02-14','2020-02-17','2020-02-18','2020-02-19','2020-02-20','2020-02-21','2020-03-02','2020-03-03','2020-03-04','2020-03-05','2020-03-06','2020-03-09','2020-03-10','2020-03-11','2020-03-12','2020-03-13','2020-03-19','2020-03-20','2020-03-26','2020-03-27','2020-04-02','2020-04-03','2020-04-09','2020-04-24','2020-04-30','2020-05-07','2020-05-08','2020-05-15','2020-05-25','2020-05-26','2020-05-27','2020-05-28','2020-05-29','2020-06-01','2020-06-02','2020-06-03','2020-06-04','2020-06-05']

        return DateList.copy()
 
if __name__ == '__main__':
  # If not using Command Line arguments then you do not need sys.argv
  # and if using Command Line arguments use argparser library instead
    MainEventThread = QApplication([])

    MainApp = MyWindow()
    MainApp.show()

  # This is the Qt5 way of handling it now
    MainEventThread.exec()
Reply
#4
Thank's Denni!
That will do the trick!
There are something that i am trying to achieve. I want the
 print('Meddelande : Nästa besök : [',self.lstDates.currentItem().text(),']')
to print out
next_visit = DateList[DateList.index('CurrentRowChanged')+10]
So that the program take the input(currentrowchanged)and return 10 steps forward in the list.
I have used this very simple program
#A list with possible dates for a visit  

 
visit_dates = ["2019-10-14","2019-10-15","2019-10-16","2019-10-17","2019-10-18","2019-10-21","2019-10-22","2019-10-23","2019-10-24","2019-10-25","2019-11-07","2019-11-08","2019-11-14","2019-11-15","2019-11-21","2019-11-28","2019-11-29","2019-12-05","2019-12-06","2019-12-12","2019-12-13","2019-12-16","2019-12-17","2019-12-18","2019-12-19","2020-01-15","2020-01-16","2020-01-23","2020-01-24","2020-01-30","2020-01-31","2020-02-06","2020-02-07","2020-02-13","2020-02-14","2020-02-17","2020-02-18","2020-02-19","2020-02-20","2020-02-21","2020-03-02","2020-03-03","2020-03-04","2020-03-05","2020-03-06","2020-03-09","2020-03-10","2020-03-11","2020-03-12","2020-03-13","2020-03-19","2020-03-20","2020-03-26","2020-03-27","2020-04-02","2020-04-03","2020-04-09","2020-04-24","2020-04-30","2020-05-07","2020-05-08","2020-05-15","2020-05-25","2020-05-26","2020-05-27","2020-05-28","2020-05-29","2020-06-01","2020-06-02","2020-06-03","2020-06-04","2020-06-05"]


date = (input("When was the last visit?: Use YYYY-MM-DD syntax: ")) 
print() 

#When you done a visit and you done the input, next visit prints out in console , it should be aproximative every 10 day


print("Well the next visit should be at: "+visit_dates[visit_dates.index(date)+10])
The next step in my program would be to return "next_visit" in a popup window
Big Grin
Reply
#5
After a little work, I think I solved the first issues i've had, thanks Denni!
Soon I might start fishing myself Wink
USE_PYSIDE2 = False
if USE_PYSIDE2:
    from PySide2.QtCore    import Signal, Slot
    from PySide2.QtWidgets import QApplication, QVBoxLayout
    from PySide2.QtWidgets import QListWidget, QMessageBox
else:
    from PyQt5.QtCore    import pyqtSignal as Signal
    from PyQt5.QtCore    import pyqtSlot   as Slot
    from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
    from PyQt5.QtWidgets import QListWidget, QMessageBox
  
class MyWindow(QWidget):
    def __init__(self):
      # Do not use Super( ) it was made to handle a specific issue that 
      # rarely occurs and if you are not experiencing that rather specific
      # issue you are adding more potential issues by using Super( ) and
      # making your program more complex than it needs to be
        QWidget.__init__(self)
  
        Top = 150;Left = 200;Width=250;Hight=200
        self.setGeometry(Top,Left,Width,Hight)
        self.setWindowTitle('APL-Besök')
  
        # Skapa listkontroll
        self.lstDates = QListWidget(self)
        # Lägg till alternativ i listan
        ItemsForListBox = self.GetDateList()
        self.lstDates.addItems(ItemsForListBox)
        # Sätt standardalternativet till rad 0
        self.lstDates.setCurrentRow(2)
        # Koppla en händelsemetod till signal
        self.lstDates.currentRowChanged.connect(self.OnCurrentRowChanged)
        
         
        VBox = QVBoxLayout()
        VBox.addWidget(self.lstDates)
         
        self.setLayout(VBox)
        
        
       
        
        
       
 
  # While you can get away with not using the Slot decorator it can cause
  # issues and not using it is just lazy coding
    @Slot(int)
    def OnCurrentRowChanged(self, RowNum, next_visit=10):
      # If doing simple debugging or proof of concept prints are simpler
      # Messagebox that returns next visit
      
        NextVisit = self.GetDateList()
      
        QMessageBox.information(self, "APL-nästa :", " Nästa besök    " +str(NextVisit[NextVisit.index(self.lstDates.item(RowNum).text())+10] ))
       
        print('Meddelande : Senaste besöket : ',RowNum,)
        print('Meddelande : Nästa besök : ',self.lstDates.currentItem().text())
        print('Using the RowNum to Get Item Value ',self.lstDates.item(RowNum).text())

      # Hantera signalen currentRowChanged
      #  Using str(Curr) might not get you want you want to know -- best to always just print
      #  the raw value (as done above) so you know exactly what you are getting
      #   QMessageBox.information(self, "Meddelande", "Senaste besöket: " + str(Curr))
      #   QMessageBox.information(self, "Meddelande", "Nästa besök: " + self.list_box.currentItem().text())




    def GetDateList(self):
      # Doing it this way so that how this List gets generated can be done as needed
      # without affecting the basic flow of the program
        DateList = ['2019-10-14','2019-10-15','2019-10-16','2019-10-17','2019-10-18','2019-10-21','2019-10-22','2019-10-23','2019-10-24','2019-10-25','2019-11-07','2019-11-08','2019-11-14','2019-11-15','2019-11-21','2019-11-28','2019-11-29','2019-12-05','2019-12-06','2019-12-12','2019-12-13','2019-12-16','2019-12-17','2019-12-18','2019-12-19','2020-01-15','2020-01-16','2020-01-23','2020-01-24','2020-01-30','2020-01-31','2020-02-06','2020-02-07','2020-02-13','2020-02-14','2020-02-17','2020-02-18','2020-02-19','2020-02-20','2020-02-21','2020-03-02','2020-03-03','2020-03-04','2020-03-05','2020-03-06','2020-03-09','2020-03-10','2020-03-11','2020-03-12','2020-03-13','2020-03-19','2020-03-20','2020-03-26','2020-03-27','2020-04-02','2020-04-03','2020-04-09','2020-04-24','2020-04-30','2020-05-07','2020-05-08','2020-05-15','2020-05-25','2020-05-26','2020-05-27','2020-05-28','2020-05-29','2020-06-01','2020-06-02','2020-06-03','2020-06-04','2020-06-05']
 
        return DateList.copy()
		
	
    
    
    
  
if __name__ == '__main__':
  # If not using Command Line arguments then you do not need sys.argv
  # and if using Command Line arguments use argparser library instead
    MainEventThread = QApplication([])
 
    MainApp = MyWindow()
    MainApp.show()
 
  # This is the Qt5 way of handling it now
    MainEventThread.exec()
Reply
#6
Glad to hear that @elmatte and I think I got your friend request -- bit slow on responding US holidays here
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020