我正在尝试使用 PySimpleGUI 构建一个 python GUI 数据库比较器 我在这里遗漏了什么?
I am trying to build a python GUI Database Comparator using PySimpleGUI i missing something here?
我正在尝试构建一个分为两个布局的 GUI 数据库比较器 window。
- 从用户那里获取数据库详细信息并测试连接
- 获取一个 Excel 文件,其中包含将在 DB 上执行的 SQL 语句,并使用 Datacompy 比较将显示给用户。
我现在面临的问题是
- 数据库详细信息应在顶部,输出框应在其下方,反之亦然
- 在输入(数据库详细信息)后,当我单击 DB Test1 按钮时,应用程序自行关闭,但未显示出了什么问题(无代码错误,刚刚关闭)
我是 PySimpleGUI 的新手,可能犯了一些愚蠢的错误,请指导我解决我需要重新输入的错误和语句。
这是第一个布局的代码 window :
import PySimpleGUI as sg
import re
import datacompy
import cx_Oracle
import pandas as pd
def read_query(connection, query):
cursor = connection.cursor()
try:
cursor.execute( query )
header = [ x[0] for x in cursor.description]
rows = cursor.fetchall()
return header, rows
finally:
if cursor is not None:
cursor.close()
def createCon(uname,passw,hname,portnum,sname):
dsn_str = cx_Oracle.makedsn(host=hname,
port=portnum,
service_name = sname)
con = cx_Oracle.connect(user = uname,
password = passw,
dsn = dsn_str)
if con == True:
return con
else:
return 0
DB_creds_one = [
[
sg.Text("UserName"),
sg.In(size=(30, 2), enable_events=True, key="-uname_db1-")
],
[
sg.Text("Password"),
sg.In(size=(30, 1), enable_events=True, key="-pword_db1-")
],
[
sg.Text("Hostname"),
sg.In(size=(30, 1), enable_events=True, key="-hname_db1-")
],
[
sg.Text("Service Name"),
sg.In(size=(30, 1), enable_events=True, key="-sname_db1-")
],
[
sg.Text("Port"),
sg.In(size=(30, 1), enable_events=True, key="-port_db1-")
],
[
sg.Button('Test Con1', key='B1')
],
]
DB_creds_two = [
[
sg.Text("UserName"),
sg.In(size=(25, 1), enable_events=True, key="-uname_db2-")
],
[
sg.Text("Password"),
sg.In(size=(25, 1), enable_events=True, key="-pword_db2-")
],
[
sg.Text("Hostname"),
sg.In(size=(25, 1), enable_events=True, key="-hname_db2-")
],
[
sg.Text("Service Name"),
sg.In(size=(25, 1), enable_events=True, key="-sname_db2-")
],
[
sg.Text("Port"),
sg.In(size=(25, 1), enable_events=True, key="-port_db2-")
],
[
sg.Button('Test Con2',key='B2')
],
]
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
]
window = sg.Window("DB Comparator", layoutprefile)
while True: # The Event Loop
event, values = window.read()
# print(event, values) # debug
if event in (None, 'Exit', 'Cancel'):
secondwindow = 0
break
elif event == 'B1':
# Test DB Connection 1 return Test_DB1
uname_d1 = window.FindElement('-uname_db1-')
pword_d1 = window.FindElement('-pword_db1-')
hname_d1 = window.FindElement('-hname_db1-')
sname_d1 = window.FindElement('-sname_db1-')
port_d1 = window.FindElement('-port_db1-')
if uname_d1 and pword_d1 and hname_d1 and sname_d1 and port_d1 == "":
print("ENter values")
else:
Test_DB1 = createCon(uname_d1,pword_d1,hname_d1,sname_d1,port_d1)
elif event == 'B2':
# Test DB Connection 2 return Test_DB2
uname_d2 = window.FindElement('-uname_db2-')
pword_d2 = window.FindElement('-pword_db2-')
hname_d2 = window.FindElement('-hname_db2-')
sname_d2 = window.FindElement('-sname_db2-')
port_d2 = window.FindElement('-port_db2-')
if uname_d2 and pword_d2 and hname_d2 and sname_d2 and port_d2 == "":
print("ENter values")
else:
Test_DB2 = createCon(uname_d2,pword_d2,hname_d2,sname_d2,port_d2)
if event == 'Proceed':
if (Test_DB1 and Test_DB2 != 'True'):
secondwindow = 0
sg.Popup("Incorrect Database Details Please Verify the Connection Again")
else:
window.close()
secondwindow = 1
break
if secondwindow != 1:
exit()
我不知道这段代码是如何工作的。它给我的消息是布局有误 []
- 可能因为这个我在 window 中没有 sg.Output
。但它仍在使用,所有错误消息都发送到 sg.Output
,您看不到错误。
正确的布局
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
],
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
现在它在 window 的底部显示我 sg.Output
。所有 print()
和错误消息都会发送到此小部件。但最好删除 Output
一段时间以在正常控制台中查看所有错误。
您还有其他问题
它应该与 or
和 == ""
一起用于所有变量 - 检查是否至少有一个元素为空
if uname_d1 == '' or pword_d1 == '' or hname_d1 == '' or sname_d1 == '' or port_d1 == '':
或者您可以将其检查为
if '' in (uname_d1, pword_d1, hname_d1, sname_d1, port_d1):
最终你可以使用空字符串被视为 False
的事实
if not all([uname_d2, pword_d2, hname_d2, sname_d2, port_d2]):
但是还有其他问题。使用 window.FindElement('-uname_db1-')
获取小部件,并从需要 .get()
的小部件中获取文本,或者您应该使用 values[..]
uname_d1 = window.FindElement('-uname_db1-').get()
uname_d1 = values['-uname_db1-']
然后你可以使用.strip()
因为有人可能会放空格
uname_d1 = window.FindElement('-uname_db1-').get().strip()
uname_d1 = values['-uname_db1-'].strip()
你检查Test_DB1
和Test_DB2
的方式也有误。需要
(Test_DB1 != True) and (Test_DB2 != True)
或更好
if (Test_DB1 is not True) and (Test_DB2 is not True):
if (Test_DB1 is False) and (Test_DB2 is False):
if (not Test_DB1) and (not Test_DB2):
您可以在第二个 window 中使用 True/False
而不是 1/0
。
并且在while
循环之前设置默认值会更好
secondwindow = True
Test_DB1 = False
Test_DB2 = False
如果你不指定然后直接点击 Process
然后你会得到错误 name 'Test_DB1' is not defined
因为它还没有 运行 Test_DB1 = createCon(...)
。
import PySimpleGUI as sg
import re
import datacompy
import cx_Oracle
import pandas as pd
def read_query(connection, query):
cursor = connection.cursor()
try:
cursor.execute( query )
header = [x[0] for x in cursor.description]
rows = cursor.fetchall()
return header, rows
finally:
if cursor is not None:
cursor.close()
def create_con(user_name, password, host_name, port_number, service_name):
dsn_str = cx_Oracle.makedsn(host=host_name,
port=port_number,
service_name=service_name)
con = cx_Oracle.connect(user=user_name, password=password, dsn=dsn_str)
return con
# --- main ---
DB_creds_one = [
[
sg.Text("UserName"),
sg.In(size=(30, 2), enable_events=True, key="-uname_db1-")
],
[
sg.Text("Password"),
sg.In(size=(30, 1), enable_events=True, key="-pword_db1-")
],
[
sg.Text("Hostname"),
sg.In(size=(30, 1), enable_events=True, key="-hname_db1-")
],
[
sg.Text("Service Name"),
sg.In(size=(30, 1), enable_events=True, key="-sname_db1-")
],
[
sg.Text("Port"),
sg.In(size=(30, 1), enable_events=True, key="-port_db1-")
],
[
sg.Button('Test Con1', key='B1')
],
]
DB_creds_two = [
[
sg.Text("UserName"),
sg.In(size=(25, 1), enable_events=True, key="-uname_db2-")
],
[
sg.Text("Password"),
sg.In(size=(25, 1), enable_events=True, key="-pword_db2-")
],
[
sg.Text("Hostname"),
sg.In(size=(25, 1), enable_events=True, key="-hname_db2-")
],
[
sg.Text("Service Name"),
sg.In(size=(25, 1), enable_events=True, key="-sname_db2-")
],
[
sg.Text("Port"),
sg.In(size=(25, 1), enable_events=True, key="-port_db2-")
],
[
sg.Button('Test Con2',key='B2')
],
]
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
],
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
window = sg.Window("DB Comparator", layoutprefile)
# default values at start
secondwindow = True
Test_DB1 = False
Test_DB2 = False
while True: # The Event Loop
event, values = window.read()
# print(event, values) # debug
if event in (None, 'Exit', 'Cancel'):
secondwindow = False
break
elif event == 'B1':
# Test DB Connection 1 return Test_DB1
uname_d1 = values['-uname_db1-'].strip()
pword_d1 = values['-pword_db1-'].strip()
hname_d1 = values['-hname_db1-'].strip()
sname_d1 = values['-sname_db1-'].strip()
port_d1 = values['-port_db1-'].strip()
print()
#if uname_d1 == '' or pword_d1 == '' or hname_d1 == '' or sname_d1 == '' and port_d1 == '':
#if not all([uname_d1, pword_d1, hname_d1, sname_d1, port_d1]):
if '' in (uname_d1, pword_d1, hname_d1, sname_d1, port_d1):
print("Enter values")
else:
Test_DB1 = create_con(uname_d1, pword_d1, hname_d1, sname_d1, port_d1)
elif event == 'B2':
# Test DB Connection 2 return Test_DB2
uname_d2 = values['-uname_db2-'].strip()
pword_d2 = values['-pword_db2-'].strip()
hname_d2 = values['-hname_db2-'].strip()
sname_d2 = values['-sname_db2-'].strip()
port_d2 = values['-port_db2-'].strip()
#if uname_d2 == '' or pword_d2 == '' or hname_d2 == '' or sname_d2 == '' and port_d1 == '':
#if not all([uname_d2, pword_d2, hname_d2, sname_d2, port_d2]):
if '' in (uname_d2, pword_d2, hname_d2, sname_d2, port_d2):
print("Enter values")
else:
Test_DB2 = create_con(uname_d2, pword_d2, hname_d2, sname_d2, port_d2)
if event == 'Proceed':
if not Test_DB1 and not Test_DB2:
sg.Popup("Incorrect Database Details Please Verify the Connection Again")
else:
window.close()
break
# if not secondwindow:
exit()
您的代码看起来格式不正确。
这里列出了一些问题,
- 布局错误
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
]
如果需要水平布局
layout = [
[sg.Button("Hello1"), sg.VerticalSeparator(), sg.Button("Hello2")],
]
或垂直布局
layout = [
[sg.Button("Hello1")],
[sg.HorizontalSeparator()],
[sg.Button("Hello2")],
]
- 获取 sg.Input
值的方法错误
uname_d1 = window.FindElement('-uname_db1-') # It can be window['-uname_db1-']
它只是获取元素sg.input
的元素。获取 sg.Input
的值
uname_d1 = values['-uname_db1-']
- 如果
Test_DB1
和Test_DB2
的两个值在下面的逻辑语句中都会得到错误的结果
if (Test_DB1 and Test_DB2 != 'True'):
也许应该
if not (Test_DB1 and Test_DB2):
- 函数
create_con
调用时的参数顺序错误。
# def createCon(uname, passw, hname, portnum, sname):
Test_DB1 = createCon(uname_d1,pword_d1,hname_d1,sname_d1,port_d1)
portnum
可能会在传递给函数 createCon
之前转换为整数
我正在尝试构建一个分为两个布局的 GUI 数据库比较器 window。
- 从用户那里获取数据库详细信息并测试连接
- 获取一个 Excel 文件,其中包含将在 DB 上执行的 SQL 语句,并使用 Datacompy 比较将显示给用户。
我现在面临的问题是
- 数据库详细信息应在顶部,输出框应在其下方,反之亦然
- 在输入(数据库详细信息)后,当我单击 DB Test1 按钮时,应用程序自行关闭,但未显示出了什么问题(无代码错误,刚刚关闭)
我是 PySimpleGUI 的新手,可能犯了一些愚蠢的错误,请指导我解决我需要重新输入的错误和语句。
这是第一个布局的代码 window :
import PySimpleGUI as sg
import re
import datacompy
import cx_Oracle
import pandas as pd
def read_query(connection, query):
cursor = connection.cursor()
try:
cursor.execute( query )
header = [ x[0] for x in cursor.description]
rows = cursor.fetchall()
return header, rows
finally:
if cursor is not None:
cursor.close()
def createCon(uname,passw,hname,portnum,sname):
dsn_str = cx_Oracle.makedsn(host=hname,
port=portnum,
service_name = sname)
con = cx_Oracle.connect(user = uname,
password = passw,
dsn = dsn_str)
if con == True:
return con
else:
return 0
DB_creds_one = [
[
sg.Text("UserName"),
sg.In(size=(30, 2), enable_events=True, key="-uname_db1-")
],
[
sg.Text("Password"),
sg.In(size=(30, 1), enable_events=True, key="-pword_db1-")
],
[
sg.Text("Hostname"),
sg.In(size=(30, 1), enable_events=True, key="-hname_db1-")
],
[
sg.Text("Service Name"),
sg.In(size=(30, 1), enable_events=True, key="-sname_db1-")
],
[
sg.Text("Port"),
sg.In(size=(30, 1), enable_events=True, key="-port_db1-")
],
[
sg.Button('Test Con1', key='B1')
],
]
DB_creds_two = [
[
sg.Text("UserName"),
sg.In(size=(25, 1), enable_events=True, key="-uname_db2-")
],
[
sg.Text("Password"),
sg.In(size=(25, 1), enable_events=True, key="-pword_db2-")
],
[
sg.Text("Hostname"),
sg.In(size=(25, 1), enable_events=True, key="-hname_db2-")
],
[
sg.Text("Service Name"),
sg.In(size=(25, 1), enable_events=True, key="-sname_db2-")
],
[
sg.Text("Port"),
sg.In(size=(25, 1), enable_events=True, key="-port_db2-")
],
[
sg.Button('Test Con2',key='B2')
],
]
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
]
window = sg.Window("DB Comparator", layoutprefile)
while True: # The Event Loop
event, values = window.read()
# print(event, values) # debug
if event in (None, 'Exit', 'Cancel'):
secondwindow = 0
break
elif event == 'B1':
# Test DB Connection 1 return Test_DB1
uname_d1 = window.FindElement('-uname_db1-')
pword_d1 = window.FindElement('-pword_db1-')
hname_d1 = window.FindElement('-hname_db1-')
sname_d1 = window.FindElement('-sname_db1-')
port_d1 = window.FindElement('-port_db1-')
if uname_d1 and pword_d1 and hname_d1 and sname_d1 and port_d1 == "":
print("ENter values")
else:
Test_DB1 = createCon(uname_d1,pword_d1,hname_d1,sname_d1,port_d1)
elif event == 'B2':
# Test DB Connection 2 return Test_DB2
uname_d2 = window.FindElement('-uname_db2-')
pword_d2 = window.FindElement('-pword_db2-')
hname_d2 = window.FindElement('-hname_db2-')
sname_d2 = window.FindElement('-sname_db2-')
port_d2 = window.FindElement('-port_db2-')
if uname_d2 and pword_d2 and hname_d2 and sname_d2 and port_d2 == "":
print("ENter values")
else:
Test_DB2 = createCon(uname_d2,pword_d2,hname_d2,sname_d2,port_d2)
if event == 'Proceed':
if (Test_DB1 and Test_DB2 != 'True'):
secondwindow = 0
sg.Popup("Incorrect Database Details Please Verify the Connection Again")
else:
window.close()
secondwindow = 1
break
if secondwindow != 1:
exit()
我不知道这段代码是如何工作的。它给我的消息是布局有误 []
- 可能因为这个我在 window 中没有 sg.Output
。但它仍在使用,所有错误消息都发送到 sg.Output
,您看不到错误。
正确的布局
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
],
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
现在它在 window 的底部显示我 sg.Output
。所有 print()
和错误消息都会发送到此小部件。但最好删除 Output
一段时间以在正常控制台中查看所有错误。
您还有其他问题
它应该与 or
和 == ""
一起用于所有变量 - 检查是否至少有一个元素为空
if uname_d1 == '' or pword_d1 == '' or hname_d1 == '' or sname_d1 == '' or port_d1 == '':
或者您可以将其检查为
if '' in (uname_d1, pword_d1, hname_d1, sname_d1, port_d1):
最终你可以使用空字符串被视为 False
if not all([uname_d2, pword_d2, hname_d2, sname_d2, port_d2]):
但是还有其他问题。使用 window.FindElement('-uname_db1-')
获取小部件,并从需要 .get()
的小部件中获取文本,或者您应该使用 values[..]
uname_d1 = window.FindElement('-uname_db1-').get()
uname_d1 = values['-uname_db1-']
然后你可以使用.strip()
因为有人可能会放空格
uname_d1 = window.FindElement('-uname_db1-').get().strip()
uname_d1 = values['-uname_db1-'].strip()
你检查Test_DB1
和Test_DB2
的方式也有误。需要
(Test_DB1 != True) and (Test_DB2 != True)
或更好
if (Test_DB1 is not True) and (Test_DB2 is not True):
if (Test_DB1 is False) and (Test_DB2 is False):
if (not Test_DB1) and (not Test_DB2):
您可以在第二个 window 中使用 True/False
而不是 1/0
。
并且在while
循环之前设置默认值会更好
secondwindow = True
Test_DB1 = False
Test_DB2 = False
如果你不指定然后直接点击 Process
然后你会得到错误 name 'Test_DB1' is not defined
因为它还没有 运行 Test_DB1 = createCon(...)
。
import PySimpleGUI as sg
import re
import datacompy
import cx_Oracle
import pandas as pd
def read_query(connection, query):
cursor = connection.cursor()
try:
cursor.execute( query )
header = [x[0] for x in cursor.description]
rows = cursor.fetchall()
return header, rows
finally:
if cursor is not None:
cursor.close()
def create_con(user_name, password, host_name, port_number, service_name):
dsn_str = cx_Oracle.makedsn(host=host_name,
port=port_number,
service_name=service_name)
con = cx_Oracle.connect(user=user_name, password=password, dsn=dsn_str)
return con
# --- main ---
DB_creds_one = [
[
sg.Text("UserName"),
sg.In(size=(30, 2), enable_events=True, key="-uname_db1-")
],
[
sg.Text("Password"),
sg.In(size=(30, 1), enable_events=True, key="-pword_db1-")
],
[
sg.Text("Hostname"),
sg.In(size=(30, 1), enable_events=True, key="-hname_db1-")
],
[
sg.Text("Service Name"),
sg.In(size=(30, 1), enable_events=True, key="-sname_db1-")
],
[
sg.Text("Port"),
sg.In(size=(30, 1), enable_events=True, key="-port_db1-")
],
[
sg.Button('Test Con1', key='B1')
],
]
DB_creds_two = [
[
sg.Text("UserName"),
sg.In(size=(25, 1), enable_events=True, key="-uname_db2-")
],
[
sg.Text("Password"),
sg.In(size=(25, 1), enable_events=True, key="-pword_db2-")
],
[
sg.Text("Hostname"),
sg.In(size=(25, 1), enable_events=True, key="-hname_db2-")
],
[
sg.Text("Service Name"),
sg.In(size=(25, 1), enable_events=True, key="-sname_db2-")
],
[
sg.Text("Port"),
sg.In(size=(25, 1), enable_events=True, key="-port_db2-")
],
[
sg.Button('Test Con2',key='B2')
],
]
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
],
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
window = sg.Window("DB Comparator", layoutprefile)
# default values at start
secondwindow = True
Test_DB1 = False
Test_DB2 = False
while True: # The Event Loop
event, values = window.read()
# print(event, values) # debug
if event in (None, 'Exit', 'Cancel'):
secondwindow = False
break
elif event == 'B1':
# Test DB Connection 1 return Test_DB1
uname_d1 = values['-uname_db1-'].strip()
pword_d1 = values['-pword_db1-'].strip()
hname_d1 = values['-hname_db1-'].strip()
sname_d1 = values['-sname_db1-'].strip()
port_d1 = values['-port_db1-'].strip()
print()
#if uname_d1 == '' or pword_d1 == '' or hname_d1 == '' or sname_d1 == '' and port_d1 == '':
#if not all([uname_d1, pword_d1, hname_d1, sname_d1, port_d1]):
if '' in (uname_d1, pword_d1, hname_d1, sname_d1, port_d1):
print("Enter values")
else:
Test_DB1 = create_con(uname_d1, pword_d1, hname_d1, sname_d1, port_d1)
elif event == 'B2':
# Test DB Connection 2 return Test_DB2
uname_d2 = values['-uname_db2-'].strip()
pword_d2 = values['-pword_db2-'].strip()
hname_d2 = values['-hname_db2-'].strip()
sname_d2 = values['-sname_db2-'].strip()
port_d2 = values['-port_db2-'].strip()
#if uname_d2 == '' or pword_d2 == '' or hname_d2 == '' or sname_d2 == '' and port_d1 == '':
#if not all([uname_d2, pword_d2, hname_d2, sname_d2, port_d2]):
if '' in (uname_d2, pword_d2, hname_d2, sname_d2, port_d2):
print("Enter values")
else:
Test_DB2 = create_con(uname_d2, pword_d2, hname_d2, sname_d2, port_d2)
if event == 'Proceed':
if not Test_DB1 and not Test_DB2:
sg.Popup("Incorrect Database Details Please Verify the Connection Again")
else:
window.close()
break
# if not secondwindow:
exit()
您的代码看起来格式不正确。
这里列出了一些问题,
- 布局错误
layoutprefile = [
[
sg.Column(DB_creds_one),
sg.VSeperator(),
sg.Column(DB_creds_two),
[sg.Output(size=(61, 5), key='-output-')],
[sg.Submit('Proceed'), sg.Cancel('Exit')]
]
]
如果需要水平布局
layout = [
[sg.Button("Hello1"), sg.VerticalSeparator(), sg.Button("Hello2")],
]
或垂直布局
layout = [
[sg.Button("Hello1")],
[sg.HorizontalSeparator()],
[sg.Button("Hello2")],
]
- 获取 sg.Input 值的方法错误
uname_d1 = window.FindElement('-uname_db1-') # It can be window['-uname_db1-']
它只是获取元素sg.input
的元素。获取 sg.Input
uname_d1 = values['-uname_db1-']
- 如果
Test_DB1
和Test_DB2
的两个值在下面的逻辑语句中都会得到错误的结果
if (Test_DB1 and Test_DB2 != 'True'):
也许应该
if not (Test_DB1 and Test_DB2):
- 函数
create_con
调用时的参数顺序错误。
# def createCon(uname, passw, hname, portnum, sname):
Test_DB1 = createCon(uname_d1,pword_d1,hname_d1,sname_d1,port_d1)
portnum
可能会在传递给函数createCon
之前转换为整数