简体   繁体   English

如何将组合框中的选定元素保存为 PyQt5 中的变量?

[英]How to save selected element from combobox as variable in PyQt5?

I'm interested in how to save a selected value from my combobox as variable, so when I press eg B then I want it to be saved as SelectedValueCBox = selected value, which would be B in this case.我对如何将组合框中的选定值保存为变量很感兴趣,因此当我按例如 B 时,我希望将其保存为 SelectedValueCBox = selected value,在这种情况下为 B。 Thank you for your help感谢您的帮助

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class App(QMainWindow): 
    def __init__(self): 
        super().__init__() 
        self.title = "PyQt5 - StockWindow"
        self.left = 0
        self.top = 0
        self.width = 200
        self.height = 300
        self.setWindowTitle(self.title) 
        self.setGeometry(self.left, self.top, self.width, self.height) 
        self.tab_widget = MyTabWidget(self) 
        self.setCentralWidget(self.tab_widget) 
        self.show() 

class MyTabWidget(QWidget): 
    def __init__(self, parent): 
        super(QWidget, self).__init__(parent) 
        self.layout = QVBoxLayout(self)
        #self.layout = QGridLayout(self) 
        self.tabs = QTabWidget() 
        self.tab1 = QWidget() 
        self.tabs.resize(300, 200) 
        self.tabs.addTab(self.tab1, "Stock-Picker") 
        self.tab1.layout = QGridLayout(self)

        button = QToolButton()
        self.tab1.layout.addWidget(button, 1,1,1,1)

        d = {'AEX':['A','B','C'], 'ATX':['D','E','F'], 'BEL20':['G','H','I'], 'BIST100':['J','K','L']}

        def callback_factory(k, v):
           return lambda: button.setText('{0}_{1}'.format(k, v))

        menu = QMenu()
        self.tab1.layout.addWidget(menu, 1,1,1,1)
        for k, vals in d.items():
            sub_menu = menu.addMenu(k)
            for v in vals:
                action = sub_menu.addAction(str(v))
                action.triggered.connect(callback_factory(k, v))
            button.setMenu(menu)
      
        self.tab1.setLayout(self.tab1.layout)
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Since you're already returning a lambda for the connection, the solution is to use a function instead.由于您已经为连接返回了 lambda,因此解决方案是改用函数。

class MyTabWidget(QWidget):
    def __init__(self, parent):
        # ...
        def callback_factory(k, v):
            def func():
                self.selectedValueCBox = v
                button.setText('{0}_{1}'.format(k, v))
            return func

        # ...
        self.selectedValueCBox = None

Note that your code also has many issues.请注意,您的代码也有很多问题。

First of all, you should not add the menu to the layout: not only it doesn't make any sense (the menu should pop up, while adding it to a layout makes it "embed" into the widget, and that's not good), but it also creates graphical issues especially because you added the menu to the same grid "slot" (1, 1, 1, 1) which is already occupied by the button.首先,您不应该将菜单添加到布局中:不仅没有任何意义(菜单应该弹出,同时将其添加到布局使其“嵌入”到小部件中,这不好) ,但它也会产生图形问题,特别是因为您将菜单添加到已被按钮占用的相同网格“插槽”(1,1,1,1)。

Creating a layout with a widget as argument automatically sets the layout to that widget.使用小部件作为参数创建布局会自动将布局设置为该小部件。 While in your case it doesn't create a big issue (since you've already set the layout) you should not create self.tab1.layout with self .虽然在您的情况下它不会造成大问题(因为您已经设置了布局),但您不应使用self创建self.tab1.layout Also, since you've already set the QVBoxLayout (due to the parent argument), there's no need to call setLayout() again.此外,由于您已经设置了QVBoxLayout (由于父参数),因此无需再次调用setLayout()

A widget container makes sense if you're actually going to add more than one widget.如果您实际上要添加多个小部件,则小部件容器是有意义的。 You're only adding a QTabWidget to its layout, so it's almost useless, and you should just subclass from QTabWidget instead.你只是在它的布局中添加了一个 QTabWidget,所以它几乎没用,你应该只是从 QTabWidget 子类化。

Calling resize on a widget that is going to be added on a layout is useless, as the layout will take care of the resizing and the previous resize call will be completely ignored.在将要添加到布局上的小部件上调用resize是没有用的,因为布局将负责调整大小,而之前的调整大小调用将被完全忽略。 resize() makes only sense for top level widgets (windows) or the rare case of widgets not managed by a layout. resize()仅适用于顶级小部件(窗口)或不由布局管理的小部件的罕见情况。

self.layout() is an existing property of all QWidgets, you should not overwrite it. self.layout()是所有 QWidget 的现有属性,您不应该覆盖它。 The same with self.width() and self.height() you used in the App class.与您在App类中使用的self.width()self.height()相同。

App should refer to an application class, but you're using it for a QMainWindow. App应该引用一个应用程序类,但您将它用于 QMainWindow。 They are radically different types of classes.它们是完全不同类型的类。

Finally, you have no combobox in your code.最后,您的代码中没有组合框。 A combobox is widget that is completely different from a drop down menu like the one you're using.组合框是一种与您正在使用的下拉菜单完全不同的小部件。 I suggest you to be more careful with the terminology in the future, otherwise your question would result very confusing, preventing people to actually being able to help you.我建议您以后对术语要更加小心,否则您的问题会导致非常混乱,使人们无法真正为您提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM