Как создать новое окно в tkinter, позволяя paget сохранить функциональность - PullRequest
0 голосов
/ 16 апреля 2020

Я пишу программу базы данных для своего уровня A, у меня есть серия страниц tkinter, которые предназначены для связи одной центральной страницей. Функции поиска, удаления и обновления успешно выполняют SQL запросы самостоятельно, но теряют свою функциональность при вызове с главной страницы, я не получаю видимых сообщений об ошибках. Я использую SQLite 3.11.2 и Python 3.7.3

Ниже приведен код, необходимый для главной страницы.

from tkinter import *
import tkinter.messagebox
import AttendancePage
import NEA_SQL_IIII

class Student:

   def __init__ (self,root):
       self.root =root
       self.root.title("ODIN")
       self.root.geometry("1350x750+0+0")
       self.root.config(bg="ghost white")

       def ap():
           AttendancePage.Attendance(Tk())

       MainFrame = Frame(self.root, bg="Ghost White")
       MainFrame.grid()

       TitFrame = Frame(MainFrame, bd=2, padx=54, pady=8, bg="Ghost White", relief = RIDGE)
       TitFrame.pack(side=TOP)

       self.lblTit = Label(TitFrame ,font=('ariel', 47,'bold'),text="Welcome to the ODIN main page",bg="Ghost White")
       self.lblTit.grid()

       CallButtonFrame = Frame(MainFrame, bd=2, width=1350, height=70, padx=18, pady=10, bg="blue2", relief = RIDGE)
       CallButtonFrame.pack(side=TOP)

       self.btnAttend = Button(CallButtonFrame, text = 'Attendance page',height=5,width=15, bd=4,command = ap)
       self.btnAttend.grid(row=0, column=0)



Ниже приведен код страницы посещаемости

import tkinter as tk
from tkinter import*
import tkinter.messagebox
import NEA_SQL_IIII

class Attendance:

   def __init__ (self,root):
       self.root =root
       self.root.title("ODIN Attendance Page")
       self.root.geometry("1350x750+0+0")
       self.root.config(bg="ghost white")
#These are all the entry widgets, where the values will be added
       Absent = BooleanVar()
       AbsenceNote = BooleanVar()
       TotalAbsences = IntVar()
       StudentName = StringVar()
       StudentID = StringVar()
       should_auto = BooleanVar()

       #function
       #This is the section that will give the buttons their functionality
       def Clear():
           self.entStudentID.delete(0,END)
           self.entStudentName.delete(0,END)
           self.chkAbsent.deselect()
           self.chkAbsenceNote.deselect()
           self.entTotalAbsences.delete(0,END)


       def Exit():
           Exit = tk.messagebox.askyesno("ODIN","Do you wish to exit?")
           if Exit > 0:
               root.destroy()
               return

       def searchDatabase():
           attendanceList.delete(0,END)
           for row in NEA_SQL_IIII.searchA(StudentID.get(),StudentName.get()):
               attendanceList.insert(END,row,str(""))


       def viewData():
           attendanceList.delete(0,END)
           for row in NEA_SQL_IIII.displayA():
               attendanceList.insert(END,row,str(""))

       def deleteData():
           if(len(StudentName.get())!=0):
              NEA_SQL_IIII.DeleteDataA(sd[0])
              Clear()
              viewData()

       def AttendRec(event):
           global sd
           searchAttend = attendanceList.curselection()[0]
           sd = attendanceList.get(searchAttend)

           self.entStudentID.delete(0,END)
           self.entStudentID.insert(END,sd[0])
           self.entStudentName.delete(0,END)
           self.entStudentName.insert(END,sd[1])
           self.chkAbsent.deselect()
           self.chkAbsent.select()
           self.chkAbsenceNote.deselect()
           self.chkAbsenceNote.select()
           self.entTotalAbsences.delete(0,END)
           self.entTotalAbsences.insert(END,sd[4])

       def Update():
           if(len(StudentID.get())!=0):
               NEA_SQL_IIII.DeleteDataA(sd[0])
           if(len(StudentID.get())!=0):
               NEA_SQL_IIII.addStudentA(StudentID.get(),StudentName.get(),Absent.get(),AbsenceNote.get(),TotalAbsences.get())
               attendanceList.delete(0,END)
               attendanceList.insert(END,(StudentID.get(),StudentName.get(),Absent.get(),AbsenceNote.get(),TotalAbsences.get()))


       #Frames
       #These will define all the different frames

       MainFrame = Frame(self.root, bg="Ghost White")
       MainFrame.grid()

       TitFrame = Frame(MainFrame, bd=2, padx=54, pady=8, bg="Ghost White", relief = RIDGE)
       TitFrame.pack(side=TOP)

       self.lblTit = Label(TitFrame ,font=('ariel', 47,'bold'),text="ODIN Attendance Page",bg="Ghost White")
       self.lblTit.grid()

       ButtonFrame = Frame(MainFrame, bd=2, width=1350, height=70, padx=18, pady=10, bg="blue2", relief = RIDGE)
       ButtonFrame.pack(side=BOTTOM)

       DataFrame = Frame(MainFrame, bd=1, width=1300, height=400, padx=20, pady=20, bg="ghost white", relief = RIDGE)
       DataFrame.pack(side=BOTTOM)

       #DataFrameTOP = LabelFrame(DataFrame, bd=1, width=1000, height=300, padx=20, pady=4, relief = RIDGE,  bg="Ghost White", font=('ariel', 20,'bold'), text = "Student Info\n")
       #DataFrameTOP.pack(side=TOP)

       DataFrameLEFT = LabelFrame(DataFrame, bd=1, width=450, height=200, padx=20,pady=3, bg="Ghost White", relief = RIDGE, font=('ariel', 20,'bold'), text = "Student Info\n")
       DataFrameLEFT.pack(side=LEFT)

       DataFrameRIGHT = LabelFrame(DataFrame, bd=1, width=450, height=200, padx=31,pady=3, bg="Ghost White", relief = RIDGE, font=('ariel', 20,'bold'), text = "Student Details\n")
       DataFrameRIGHT.pack(side=RIGHT)

#Label and Entry Widget
#These are the widgets that will allow for labels onto the entry sections


       self.lblStudentID = Label(DataFrameLEFT ,font=('ariel', 11,'bold'),text="Student ID", padx=2, pady=2, bg="Ghost White")
       self.lblStudentID.grid(row=0, column=0, sticky=W)
       self.entStudentID = Entry(DataFrameLEFT ,font=('ariel', 11,'bold'),textvariable=StudentID,  width=39)
       self.entStudentID.grid(row=0, column=1)

       self.lblStudentName = Label(DataFrameLEFT ,font=('ariel', 11,'bold'),text="Student Name", padx=2, pady=2, bg="Ghost White")
       self.lblStudentName.grid(row=1, column=0, sticky=W)
       self.entStudentName = Entry(DataFrameLEFT ,font=('ariel', 11,'bold'),textvariable=StudentName,  width=39)
       self.entStudentName.grid(row=1, column=1)

       self.lblAbsent = Label(DataFrameLEFT ,font=('ariel', 11,'bold'),text="Absent?", padx=2, pady=2, bg="Ghost White")
       self.lblAbsent.grid(row=2, column=0, sticky=W)
       self.chkAbsent = Checkbutton(DataFrameLEFT ,font=('ariel', 11,'bold'),textvariable=Absent, variable = should_auto, onvalue = True, offvalue = False, width=39)
       self.chkAbsent.grid(row=2, column=1)

       self.lblAbsenceNote = Label(DataFrameLEFT ,font=('ariel', 11,'bold'),text="Absence Note?", padx=2, pady=2, bg="Ghost White")
       self.lblAbsenceNote.grid(row=3, column=0, sticky=W)
       self.chkAbsenceNote = Checkbutton(DataFrameLEFT ,font=('ariel', 11,'bold'),textvariable=AbsenceNote,  width=39, onvalue = True, offvalue = False)
       self.chkAbsenceNote.grid(row=3, column=1)

       self.lblTotalAbsences = Label(DataFrameLEFT ,font=('ariel', 11,'bold'),text="Total Absences?", padx=2, pady=2, bg="Ghost White")
       self.lblTotalAbsences.grid(row=4, column=0, sticky=W)
       self.entTotalAbsences = Entry(DataFrameLEFT ,font=('ariel', 11,'bold'),textvariable=TotalAbsences,  width=39)
       self.entTotalAbsences.grid(row=4, column=1)



       #scrollbar

       scrollbar = Scrollbar(DataFrameRIGHT)
       scrollbar.grid(row=0, column=1, sticky = 'ns')

       attendanceList = Listbox(DataFrameRIGHT, width=41, height=16, font=('ariel',12,'bold'), yscrollcommand=scrollbar.set)
       attendanceList.bind('<<ListboxSelect>>',AttendRec)
       attendanceList.grid(row=0, column=0, padx=8)
       scrollbar.config(command = attendanceList.yview)

#button
       #self.btnAddDate = Button(ButtonFrame, text='Add New', font=('ariel',20,'bold'),height=1,width=10, bd=4, command=addData)
       #self.btnAddDate.grid(row=0, column=0)

       self.btnDisplay = Button(ButtonFrame, text='Display', font=('ariel',20,'bold'),height=1,width=10, bd=4, command=viewData)
       self.btnDisplay.grid(row=0, column=0)

       self.btnClear = Button(ButtonFrame, text='Clear', font=('ariel',20,'bold'),height=1,width=10, bd=4, command=Clear)
       self.btnClear.grid(row=0, column=1)

       self.btnDelete = Button(ButtonFrame, text='Delete', font=('ariel',20,'bold'),height=1,width=10, bd=4, command = deleteData)
       self.btnDelete.grid(row=0, column=2)

       self.btnSearch = Button(ButtonFrame, text='Search', font=('ariel',20,'bold'),height=1,width=10, bd=4, command = searchDatabase)
       self.btnSearch.grid(row=0, column=3)

       #self.btnUpdate = Button(ButtonFrame, text='Update', font=('ariel',20,'bold'),height=1,width=10, bd=4, command = updateData)
       #self.btnUpdate.grid(row=0, column=4)

       self.btnUpdate = Button(ButtonFrame, text='Update', font=('ariel',20,'bold'),height=1,width=10, bd=4, command = Update)
       self.btnUpdate.grid(row=0, column=4)

       self.btnQuit = Button(ButtonFrame, text='Quit', font=('ariel',20,'bold'),height=1,width=10, bd=4, command=Exit)
       self.btnQuit.grid(row=0, column=5)


if __name__=='__main__':
   root = Tk()
   application = Attendance(root)
   root.mainloop()


И ниже необходим код SQL (NEA_SQL_IIII)

def Attendance():
    con=sqlite3.connect("Attendance.db")
    cur=con.cursor()
    cur.execute("CREATE TABLE IF NOT EXIST Attendance (Absent BOOLEAN, AbsenceNote BOOLEAN, TotalAbsences INTEGER, FOREIGN KEY StudentName REFERENCES StudentRecord(StudentName),FOREIGN KEY StudentID REFERENCES StudentRecord(StudentID), PRIMARY KEY(StudentID)")
    con.commit()
    con.close()

def displayA():
    con=sqlite3.connect("Attendance.db")
    cur=con.cursor()
    cur.execute("SELECT * FROM Attendance")
    rows =cur.fetchall()
    con.close()
    return rows

def DeleteDataA(StudentID):
    con=sqlite3.connect("Attendance.db")
    cur=con.cursor()
    cur.execute("DELETE FROM Attendance WHERE StudentID=?", (StudentID,))
    con.commit()
    return con, cur
    con.close()

def searchA(StudentName="", StudentID=""):
    con=sqlite3.connect("Attendance.db", isolation_level=None)
    cur=con.cursor()
    cur.execute("SELECT * FROM Attendance WHERE StudentName=? OR StudentID=?", (StudentName,StudentID,))
    rows = cur.fetchall()
    con.close()
    return rows

def UpdateDataA(StudentID="", StudentName="", Behaviour="", Achievement="", Detention="", ProgressLevel=""):
    con=sqlite3.connect("StudentRecord.db")
    cur=con.cursor()
    cur.execute("UPDATE StudentRecord SET StudentName=?, Behaviour=?, Achievement=?, Detention=?, ProgressLevel=? WHERE StudentID=? ", (StudentID,StudentName,Behaviour,Achievement,Detention,ProgressLevel))
    con.commit()
    con.close()

Ответы [ 2 ]

1 голос
/ 16 апреля 2020

С вашей проблемой я предполагаю, что вы будете sh создавать множество Tkinter windows, которые работают вместе. В этом случае я бы создал несколько файлов .py и использовал бы один файл, в котором все windows получают свои данные от .

Я понимаю, что это было немного скучно, поэтому позвольте мне объяснить ...

Во-первых, создайте центральный файл .py, который управляет вашим главным окном. Я бы назвал это что-то вроде main.py

Создайте новый файл .py для вашего нового окна.

Создайте файл .txt для всех windows, чтобы централизованно запустить его, вызовите его что-то вроде data.txt.

Добавьте импорт в другую программу, чтобы начать поток данных между программами и создать окно другой программы. Затем установите ожидание в значение True.

Наконец, включите параметр While l oop, пока открыты отдельные окна, и используйте его для постоянной проверки файла data.txt на наличие обновлений. Например:

While waiting == True:
    f = open("data.txt","r")
    recent = f.read() #or do a readline if you want certain data
    if recent == old:
        old = recent
    else:
        old = recent
        #insert what/where you want the data to go after it's updated.
        #you could also add a waiting = False loop if you like, if after the data has been edited you wish the program to stop checking the data.txt file.
        #You can also add code to remotely stop the other window here too if you like.

Надеюсь, это поможет.

0 голосов
/ 16 апреля 2020

Вы не можете запустить несколько tkinter windows одновременно из одного python процесса, так как tkinter не безопасен для потоков, иногда он будет работать частично, но вряд ли так, как вы sh. Если вы хотите запустить несколько страниц, я бы порекомендовал использовать другой GUI инструментарий или запустить tkinter windows из разных процессов, используя:

import subprocess, sys
subprocess.Popen((sys.executable + '/path/to/file.py').split())

Если вам необходимо взаимодействовать между процессами, однако это становится более сложным, и я бы порекомендовал использовать для этого socket.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...