QT是主程序,用子进程打开了另外一个QT程序,这个子进程中产生的一个列表如何被引用到主程序QT中?
主程序大概这个样子
```python
def products_info(self):
process = subprocess.Popen("py P_Input_Hiking_02.py", shell=True)
子进程代码如下:
ITEM, ITEM_NAME, PRICE, QTY,HT_PRICE,NW = range(6)
class window(QDialog):
def __init__(self, parent=None):
super(window, self).__init__(parent)
self.resize(600, 860)
self.model = QSqlTableModel(self)
self.model.setTable("reference")
self.model.setSort(ITEM, Qt.AscendingOrder)
self.model.setHeaderData(ITEM, Qt.Horizontal, "产品简写")
self.model.setHeaderData(ITEM_NAME, Qt.Horizontal,"产品名")
self.model.setHeaderData(PRICE, Qt.Horizontal,"价格")
self.model.setHeaderData(QTY, Qt.Horizontal,"数量")
self.model.setHeaderData(HT_PRICE, Qt.Horizontal,"采购价")
self.model.select()
self.view = QTableView(self)
self.view.setModel(self.model)
self.view.setSelectionMode(QTableView.SingleSelection)
self.view.setSelectionBehavior(QTableView.SelectRows)
self.view.setColumnHidden(ITEM, False)
self.view.setColumnWidth(1000, 2000)
buttonBox = QDialogButtonBox()
copyButton = buttonBox.addButton("&复制添加",
QDialogButtonBox.ActionRole)
addButton = buttonBox.addButton("&添加",
QDialogButtonBox.ActionRole)
deleteButton = buttonBox.addButton("&Delete",
QDialogButtonBox.ActionRole)
sortButton = buttonBox.addButton("&Sort",
QDialogButtonBox.ActionRole)
finishButton = buttonBox.addButton("&完成",
QDialogButtonBox.ActionRole)
if not MAC:
addButton.setFocusPolicy(Qt.NoFocus)
deleteButton.setFocusPolicy(Qt.NoFocus)
sortButton.setFocusPolicy(Qt.NoFocus)
menu = QMenu(self)
sortByCategoryAction = menu.addAction("Sort by &Category")
sortByDescriptionAction = menu.addAction("Sort by &Description")
sortByIDAction = menu.addAction("Sort by &ITEM")
sortButton.setMenu(menu)
closeButton = buttonBox.addButton(QDialogButtonBox.Close)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.view)
self.layout.addWidget(buttonBox)
self.setLayout(self.layout)
copyButton.clicked.connect(self.copyRecord)
addButton.clicked.connect(self.addRecord)
finishButton.clicked.connect(self.finishRecord)
deleteButton.clicked.connect(self.deleteRecord)
sortByCategoryAction.triggered.connect(lambda:self.sort(ITEM_NAME))
sortByDescriptionAction.triggered.connect(lambda:self.sort(PRICE))
sortByIDAction.triggered.connect(lambda:self.sort(ITEM))
closeButton.clicked.connect(self.close)
self.setWindowTitle("新程ZXW产品录入表2022-10-25")
self.view.show()
def addRecord(self):
class My_Tk():
def __init__(self):
self.tk=tk.Toplevel()
self.tk.geometry('890x800')
self.orm={}
self.create_button()
self.create_heading()
self.create_tv()
self.insert_tv()
mainloop()
def sort_data(self):
text_num_dict={"ITEM":0,"HS":1,"SUPPLIER":5}
n=text_num_dict[value_label]
print(n)
x=0
items = self.tv.get_children()
[self.tv.delete(item) for item in items]
for child in self.button_frame.winfo_children()[1:]: #第一个构件是label,所以忽略
child.destroy()
#重设tree、button对应关系
self.orm={}
self.vb_dict={}
self.tv.update()
if n==0:
c1=sorted(dic_cl.items())
else:
c1= sorted(dic_cl.items(),key=lambda x: x[1][n])
for i,v in c1:
x=x+1
tv_item=self.tv.insert('', x, value=[i,v[0],v[8],1,v[10],v[1],v[5]],tags=('oddrow'))#item默认状态tags
import tkinter
ck_button = tkinter.Checkbutton(self.button_frame,variable=IntVar())
ck_button['command']=lambda item=tv_item:self.select_button(item)
ck_button.pack()
self.orm[tv_item]=[ck_button]
self.vb_dict[ck_button]=[tv_item] #改变排序 需要改进
def sort_value_get0(self,menu):
global value_label
value_label= menu.entrycget(0, "label")
self.sort_data()
def sort_value_get1(self,menu):
global value_label
value_label= menu.entrycget(1, "label")
self.sort_data()
def sort_value_get2(self,menu):
global value_label
value_label= menu.entrycget(2, "label")
self.sort_data()
def create_button(self):
Button(self.tk,text='选中',command=self.all_content_select).pack()
menu1 = Menu(self.tk, tearoff=0) #1的话多了一个虚线,如果点击的话就会发现,这个菜单框可以独立出来显示
menu1.add_command(label="ITEM",command=lambda: self.sort_value_get0(menu1))
menu1.add_command(label="HS",command=lambda: self.sort_value_get1(menu1))
menu1.add_command(label="SUPPLIER",command=lambda: self.sort_value_get2(menu1))
mebubar = Menu(self.tk)
mebubar.add_cascade(label="排序", menu=menu1)
self.tk.config(menu=mebubar)
def create_heading(self,):
'''重新做一个treeview的头,不然滚动滚动条,看不到原先的头!!!'''
heading_frame=Frame(self.tk)
heading_frame.pack(fill=X)
#填充用
button_frame=Label(heading_frame,width=1)
button_frame.pack(side=LEFT,)
#全选按钮
self.all_buttonvar = IntVar()
self.all_button = Checkbutton(heading_frame, text='',variable=self.all_buttonvar, command=self.select_all)
self.all_button.pack(side=LEFT)
self.all_buttonvar.set(0)
self.columns = ['产品缩写', '产品全称', '价格', '数量', '采购价','HS','采购商']
self.widths = [65, 325, 60, 80,80,130,95]
#重建tree的头
for i in range(len(self.columns)):
Label(heading_frame,text=self.columns[i],width=int(self.widths[i]*0.14),anchor='center',relief=GROOVE).pack(side=LEFT)
def create_tv(self):
#放置 canvas、滚动条的frame
canvas_frame=Frame(self.tk,width=865,height=700)
canvas_frame.pack(fill=X)
#只剩Canvas可以放置treeview和按钮,并且跟滚动条配合
self.canvas=Canvas(canvas_frame,width=865,height=700,scrollregion=(0,0,865,700))
self.canvas.pack(side=LEFT,fill=BOTH,expand=1)
#滚动条
ysb = Scrollbar(canvas_frame, orient=VERTICAL, command=self.canvas.yview)
self.canvas.configure(yscrollcommand=ysb.set)
ysb.pack(side=RIGHT, fill=Y)
#!!!!=======重点:鼠标滚轮滚动时,改变的页面是canvas 而不是treeview
self.canvas.bind("<MouseWheel>",lambda event:self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units"))
#想要滚动条起效,得在canvas创建一个windows(frame)!!# bind_all是application_wise绑定,使用window-wise绑定
tv_frame=Frame(self.canvas)
self.tv_frame=self.canvas.create_window(0, 0, window=tv_frame, anchor='nw',width=865,height=700)#anchor该窗口在左上方
#放置button的frame
self.button_frame=Frame(tv_frame)
self.button_frame.pack(side=LEFT, fill=Y)
Label(self.button_frame,width=3).pack() #填充用
#创建treeview
self.tv = Treeview(tv_frame, height=30, columns=self.columns, show='headings')#height好像设定不了行数,实际由插入的行数决定
self.tv.pack(expand=1, side=LEFT, fill=BOTH) #show='headings'改成
#设定每一列的属性
for i in range(len(self.columns)):
self.tv.column(self.columns[i], width=0, minwidth=self.widths[i], anchor='center', stretch=True)
#设定treeview格式
# import tkinter.font as tkFont
# ft = tkFont.Font(family='Fixdsys', size=20, weight=tkFont.BOLD)
self.tv.tag_configure('oddrow', font='Arial 12') #设定treeview里字体格式font=ft
self.tv.tag_configure('select', background='SkyBlue',font='Arial 14')#当对应的按钮被打勾,那么对于的行背景颜色改变!
self.rowheight=27 #很蛋疼,好像tkinter里只能用整数!
Style().configure('Treeview', rowheight=self.rowheight) #设定每一行的高度
# 设定选中的每一行字体颜色、背景颜色 (被选中时,没有变化)
Style().map("Treeview",
foreground=[ ('focus', 'black'), ],
background=[ ('active', 'white')]
)
self.tv.bind('<<TreeviewSelect>>', self.select_tree) #绑定tree选中时的回调函数
def insert_tv(self):
#清空tree、checkbutton #展示商品这里调试
items = self.tv.get_children()
[self.tv.delete(item) for item in items]
self.tv.update()
for child in self.button_frame.winfo_children()[1:]: #第一个构件是label,所以忽略
child.destroy()
#重设tree、button对应关系
self.orm={}
self.vb_dict={}
x=0
for i,v in sorted(dic_cl.items()):
x=x+1
tv_item=self.tv.insert('', x, value=[i,v[0],v[8],1,v[10],v[1],v[5]],tags=('oddrow'))#item默认状态tags
import tkinter
ck_button = tkinter.Checkbutton(self.button_frame,variable=IntVar())
ck_button['command']=lambda item=tv_item:self.select_button(item)
ck_button.pack()
self.orm[tv_item]=[ck_button]
self.vb_dict[ck_button]=[tv_item]
#每次点击插入tree,先设定全选按钮不打勾,接着打勾并且调用其函数
self.all_buttonvar.set(0)
#self.all_button.invoke()
#更新canvas的高度
height = (len(self.tv.get_children()) + 1) * self.rowheight # treeview实际高度
self.canvas.itemconfigure(self.tv_frame, height=height) #设定窗口tv_frame的高度
self.tk.update()
self.canvas.config(scrollregion=self.canvas.bbox("all"))#滚动指定的范围
self.all_content_select()
def select_all(self):
'''全选按钮的回调函数
作用:所有多选按钮打勾、tree所有行都改变底色(被选中)'''
for item,[button] in self.orm.items():
#print(item)
#print([button])
if self.all_buttonvar.get()==1:
button.select()
self.tv.item(item, tags='select')
else:
button.deselect()
self.tv.item(item, tags='oddrow')
def select_button(self,item):
'''多选按钮的回调函数
作用:1.根据按钮的状态,改变对应item的底色(被选中)
2.根据所有按钮被选的情况,修改all_button的状态'''
button=self.orm[item][0]
button_value=button.getvar(button['variable'])
if button_value=='1':
self.tv.item(item,tags='select')
print('选中了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。')
else:
self.tv.item(item, tags='oddrow')
self.all_button_select()#根据所有按钮改变 全选按钮状态
def select_tree(self,event):
'''tree绑定的回调函数
作用:根据所点击的item改变 对应的按钮'''
select_item=self.tv.focus()
button = self.orm[select_item][0]
button.invoke() #改变对应按钮的状态,而且调用其函数
def all_button_select(self):
'''根据所有按钮改变 全选按钮状态
循环所有按钮,当有一个按钮没有被打勾时,全选按钮取消打勾'''
for [button] in self.orm.values():
button_value = button.getvar(button['variable'])
if button_value=='0':
self.all_buttonvar.set(0)
break
else:
self.all_buttonvar.set(1)
def all_content_select(self):
'''根据所有按钮改变 全选按钮状态
循环所有按钮,当有一个按钮没有被打勾时,全选按钮取消打勾'''
global content_list
content_list=[]
for [button] in self.orm.values():
button_value = button.getvar(button['variable'])
if button_value=='1':
a_key=self.vb_dict[button]
item_text = self.tv.item(a_key, "values")
print('产品列表:'+str(item_text) )
content_list.append(item_text)
else:
pass
self.num_ch=int(len(content_list))
if self.num_ch<1:
pass
else:
self.exit_105()
# 定义退出函数
def exit_105(self):
a = tk.messagebox.askquestion(title='提示窗', message='你真的要退出么?')
if a == 'yes':
self.tk.quit()
self.tk.destroy()
project1= My_Tk()
con = sqlite3.connect(database='reference.db')
for m in content_list:
cur=con.cursor()
ITEM,ITEM_NAME,PRICE,QTY,HT_PRICE,NW=m[0],m[1],m[2],m[3],m[4],dic_cl[m[0]][2]
cur.execute("INSERT INTO reference(ITEM,ITEM_NAME,PRICE,QTY,HT_PRICE,NW) VALUES ('{}','{}','{}','{}','{}','{}')".format(ITEM,ITEM_NAME,PRICE,QTY,HT_PRICE,NW))
cur.close()
con.commit()
con.close()
self.view.close()
self.model = QSqlTableModel(self)
self.model.setTable("reference")
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
self.model.select()
self.view = QTableView(self)
self.view.setModel(self.model)
self.view.setSelectionMode(QTableView.SingleSelection)
self.view.setSelectionBehavior(QTableView.SelectRows)
self.view.setColumnWidth(200, 300)
self.view.show()
self.layout.addWidget(self.view)
content_list.clear()
def finishRecord(self):
self.model.submitAll()
con = sqlite3.connect(database='reference.db')
cur=con.cursor()
sql='select * from reference'
cur.execute(sql)
global product_info_list
product_info_list=[]
for all in cur.fetchall():
product_info_list.append([all[0],all[1],'',all[2],all[3],all[4],all[5]])
print(product_info_list)
def copyRecord(self):
rows = [index.row() for index in self.view.selectionModel().selectedIndexes()]
print(rows)
record=[]
n=-1
try:
for row in rows:
n+=1
index = self.view.model().index(row, n)
data=index.data()
record.append(data)
print(record)
except:
pass
con = sqlite3.connect(database='reference.db')
m=record
cur=con.cursor()
ITEM,ITEM_NAME,PRICE,QTY,HT_PRICE,NW=m[0]+'复制',m[1],m[2],m[3],m[4],m[5]
cur.execute("INSERT INTO reference(ITEM,ITEM_NAME,PRICE,QTY,HT_PRICE,NW) VALUES ('{}','{}','{}','{}','{}','{}')".format(ITEM,ITEM_NAME,PRICE,QTY,HT_PRICE,NW))
con.commit()
con.close()
self.view.close()
self.model = QSqlTableModel(self)
self.model.setTable("reference")
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
self.model.select()
self.view = QTableView(self)
self.view.setModel(self.model)
self.view.setSelectionMode(QTableView.SingleSelection)
self.view.setSelectionBehavior(QTableView.SelectRows)
self.view.setColumnWidth(200, 300)
self.view.show()
self.layout.addWidget(self.view)
def deleteRecord(self):
index = self.view.currentIndex()
if not index.isValid():
return
record = self.model.record(index.row())
category = record.value(ITEM_NAME)
desc = record.value(PRICE)
if (QMessageBox.question(self, "Reference Data",
("Delete {0} from category {1}?"
.format(desc,category)),
QMessageBox.Yes|QMessageBox.No) ==
QMessageBox.No):
return
self.model.removeRow(index.row())
self.model.submitAll()
self.model.select()
def sort(self, column):
self.model.setSort(column, Qt.AscendingOrder)
self.model.select()
def main():
app = QApplication(sys.argv)
filename = os.path.join(os.path.dirname(__file__), "reference.db")
create = not QFile.exists(filename)
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(filename)
if not db.open():
QMessageBox.warning(None, "Reference Data",
"Database Error: {0}".format(db.lastError().text()))
sys.exit(1)
if create:
print('添加数据。。。。。。。。。。。。。。。。。。')
con = sqlite3.connect(database='reference.db')
QApplication.processEvents()
cur=con.cursor()
sql2="DROP TABLE IF EXISTS reference;"
cur.execute(sql2)
sql=("""CREATE TABLE IF NOT EXISTS reference (
ITEM VARCHAR(80) NOT NULL,
ITEM_NAME VARCHAR(300) NOT NULL,
PRICE VARCHAR(300) NOT NULL,
QTY VARCHAR(300) NOT NULL,
HT_PRICE VARCHAR(300) NOT NULL,
NW VARCHAR(300))
""")
cur.execute(sql)
cur.close()
con.commit()
form = window()
form.show()
app.exec_()
if __name__ == '__main__':
main()
```QT程序如下
子进程结束后我想把它生成的列表 product_info_list引用到主程序中有用!