绳绳不息David 2023-01-17 17:22 采纳率: 33.3%
浏览 52
已结题

QT子进程结束后生成的变量如何被引用到QT主程序中

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引用到主程序中有用!

  • 写回答

4条回答 默认 最新

  • churuxu 2023-01-17 17:51
    关注

    不同进程的变量是没法直接访问的。

    方案一,网上搜进程间通信,可以找代码参考,在合适的时候子进程发送内容给父进程

    方案二(简单方式),如果你需要的模式是:A进程打开B进程,B进程上操作完成后退出,A进程取得B进程的操作结果
    B进程把内容保存到文件
    A进程在B进程退出后读文件

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月17日
  • 修改了问题 1月17日
  • 修改了问题 1月17日
  • 请提交代码 1月17日
  • 展开全部

悬赏问题

  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置