如何显示我的标签并激活pyqt5中的各自的快捷方式?

发布于 2025-02-13 09:03:23 字数 1126 浏览 0 评论 0原文

这是我的代码,如何显示我的标签并激活相应的qshortCut?想要显示我的标签(两种实例),并为标签分配相应的快捷键并激活它。

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

class Create_workingDict(QWidget):
    def __init__(self,lblname,lblscut):
        super(). __init__()

        self.lblname = lblname
        self.lblscut = lblscut

        lbl_1 = QLabel()
        lbl_1.setText(self.lblname)
        lbl_2 = QLabel()
        lbl_2.setText(self.lblscut)

        vbox = QVBoxLayout()
        vbox.addWidget(lbl_1)
        vbox.addWidget(lbl_2)
        self.setLayout(vbox)

        self.msgSc = QShortcut(QKeySequence(f'{self.lblscut}'), self)
        self.msgSc.activated.connect(lambda: QMessageBox.information(self,'Message', 'Ctrl + M initiated'))


class Mainclass(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Sample Window")
        x = Create_workingDict("Accounts","Alt+A")
        y = Create_workingDict("Inventory", "Ctrl+B")


def main():
    app = QApplication(sys.argv)
    ex = Mainclass()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Here is my code, How to show My Labels and activate respective QShortcut?. Want to show my labels(both instances) and assign respective shortcut keys to labels and activate it.

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

class Create_workingDict(QWidget):
    def __init__(self,lblname,lblscut):
        super(). __init__()

        self.lblname = lblname
        self.lblscut = lblscut

        lbl_1 = QLabel()
        lbl_1.setText(self.lblname)
        lbl_2 = QLabel()
        lbl_2.setText(self.lblscut)

        vbox = QVBoxLayout()
        vbox.addWidget(lbl_1)
        vbox.addWidget(lbl_2)
        self.setLayout(vbox)

        self.msgSc = QShortcut(QKeySequence(f'{self.lblscut}'), self)
        self.msgSc.activated.connect(lambda: QMessageBox.information(self,'Message', 'Ctrl + M initiated'))


class Mainclass(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Sample Window")
        x = Create_workingDict("Accounts","Alt+A")
        y = Create_workingDict("Inventory", "Ctrl+B")


def main():
    app = QApplication(sys.argv)
    ex = Mainclass()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落花浅忆 2025-02-20 09:03:23

基于父窗口小部件的上下文(和可见性)的快捷方式工作:只要父级可见并且上下文是兼容的,它们将被触发,否则甚至不会考虑它们。

请注意,可见性是父母小部件的 s (请注意复数)是强制性的,无论上下文:qt具有 no api用于“全局”快捷方式,不仅是应用程序外部,而且在其中:没有任何快捷方式可以自动 在应用程序中的任何地方工作,如果(任何一个)它的父母是隐藏。上下文仅确保只有在活动 widget是应用程序的一部分(applicationsHortCut)的情况下才能激活快捷方式(windowshortcut),如果任何grand [...]父窗口小部件具有焦点(widgetwithwithChildrensHortCut)或当前 parent拥有它(widgetShortCut)。

长话短说:如果捷径的父母不可见(在任何级别上),则它将 都不会触发。

不仅。在您的代码中,xy可能是收集垃圾(它们不是由于lambda范围避免遭到破坏的事实,但这只是“ sheer heer Dumb运气”),因此,如果激活的信号将已连接到实例方法,则代码实际上很容易失败。

如果您希望它们可在可见窗口中可用,即使未显示它们,您也必须将其父窗口添加到该窗口中。否则,只需将快捷方式添加到该窗口。

例如:

class Mainclass(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Sample Window")
        x = Create_workingDict("Accounts","Alt+A")
        y = Create_workingDict("Inventory", "Ctrl+B")
        layout = QVBoxLayout(self)
        layout.addWidget(x)
        layout.addWidget(y)

和自动方法访问应用程序的任何 window>的全局应用程序快捷方式是创建一个Qkey序列应用程序上安装的事件过滤器。

这是一种可能的,但粗略的实施,因此,按原样考虑并考虑其后果:

class ShortCutFilter(QObject):
    triggered = pyqtSignal(QKeySequence)
    def __init__(self, shortcuts=None):
        super().__init__()
        self.shortcuts = {}

    def addShortcut(self, shortcut, slot=None):
        if isinstance(shortcut, str):
            shortcut = QKeySequence(shortcut)
        slots = self.shortcuts.get(shortcut)
        if not slots:
            self.shortcuts[shortcut] = slots = []
        if slot is not None:
            slots.append(slot)
        return shortcut

    def eventFilter(self, obj, event):
        if event.type() == event.KeyPress:
            keyCode = event.key()
            mods = event.modifiers()
            if mods & Qt.ShiftModifier:
                keyCode += Qt.SHIFT
            if mods & Qt.MetaModifier:
                keyCode += Qt.META
            if mods & Qt.ControlModifier:
                keyCode += Qt.CTRL
            if mods & Qt.ALT:
                keyCode += Qt.ALT
            for sc, slots in self.shortcuts.items():
                if sc == QKeySequence(keyCode):
                    self.triggered.emit(sc)
                    for slot in slots:
                        try:
                            slot()
                        except Exception as e:
                            print(type(e), e)
                    return True
        return super().eventFilter(obj, event)


def main():
    app = QApplication(sys.argv)
    shortcutFilter = ShortCutFilter()
    app.installEventFilter(shortcutFilter)

    shortcutFilter.addShortcut('alt+b', lambda: 
        QMessageBox.information(None, 'Hello', 'How are you'))
    shortcutFilter.triggered.connect(lambda sc:
        print('triggered', sc.toString())

    ex = Mainclass()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

这显然意味着 任何 键新闻事件将通过已知的Python瓶颈。一个更好的解决方案是将全局Qactions和addaction()创建到可以接受它的任何最高级别窗口。

尽管这种方法似乎更复杂,但它具有好处。例如,您可以对快捷方式的上下文进行更多控制:在上面的情况下,您可以从 aish aish 窗口中触发 alt+b 包括先前触发它后显示的那个,这显然不是一件好事。

Shortcuts work based on the context (and visibility) of the parent widget: as long as the parent is visible and the context is compatible, they will be triggered, otherwise they will not even be considered.

Be aware that the visibility is of the parent widgets (note the plural) is mandatory, no matter of the context: Qt has no API for a "global" shortcut, not only external to the application, but also within it: there is no shortcut that can automatically work anywhere in the app if (any of) its parent(s) is hidden. The context only ensures that the shortcut can only be activated if the active widget is part of the application (ApplicationShortcut), if the current active window is an ancestor of the shortcut parent (WindowShortcut), if any of the grand[...]parent widgets has focus (WidgetWithChildrenShortcut) or the current parent has it (WidgetShortcut).

Long story short: if the shortcut's parent is not visible (at any level), it will not be triggered.

Not only. In your code, both x and y are potentially garbage collected (they are not due to the fact that the lambda scope avoids destruction, but that's just "sheer dumb luck"), so that code would be actually prone to fail anyway if the activated signal would have been connected to an instance method.

If you want them to be available to the visible window, you must add their parent widgets to that window, even if they're not shown. Otherwise, just add the shortcuts to that window.

For instance:

class Mainclass(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Sample Window")
        x = Create_workingDict("Accounts","Alt+A")
        y = Create_workingDict("Inventory", "Ctrl+B")
        layout = QVBoxLayout(self)
        layout.addWidget(x)
        layout.addWidget(y)

The only and automatic way to access a global application shortcut from any window of the application is to create a QKeySequence that is checked within an event filter installed on the application.

This is a possible, but crude implementation, so, take it as it is and consider its consequences:

class ShortCutFilter(QObject):
    triggered = pyqtSignal(QKeySequence)
    def __init__(self, shortcuts=None):
        super().__init__()
        self.shortcuts = {}

    def addShortcut(self, shortcut, slot=None):
        if isinstance(shortcut, str):
            shortcut = QKeySequence(shortcut)
        slots = self.shortcuts.get(shortcut)
        if not slots:
            self.shortcuts[shortcut] = slots = []
        if slot is not None:
            slots.append(slot)
        return shortcut

    def eventFilter(self, obj, event):
        if event.type() == event.KeyPress:
            keyCode = event.key()
            mods = event.modifiers()
            if mods & Qt.ShiftModifier:
                keyCode += Qt.SHIFT
            if mods & Qt.MetaModifier:
                keyCode += Qt.META
            if mods & Qt.ControlModifier:
                keyCode += Qt.CTRL
            if mods & Qt.ALT:
                keyCode += Qt.ALT
            for sc, slots in self.shortcuts.items():
                if sc == QKeySequence(keyCode):
                    self.triggered.emit(sc)
                    for slot in slots:
                        try:
                            slot()
                        except Exception as e:
                            print(type(e), e)
                    return True
        return super().eventFilter(obj, event)


def main():
    app = QApplication(sys.argv)
    shortcutFilter = ShortCutFilter()
    app.installEventFilter(shortcutFilter)

    shortcutFilter.addShortcut('alt+b', lambda: 
        QMessageBox.information(None, 'Hello', 'How are you'))
    shortcutFilter.triggered.connect(lambda sc:
        print('triggered', sc.toString())

    ex = Mainclass()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

This, obviously, means that any key press event will pass through the known python bottleneck. A better solution would be to create global QActions and addAction() to any possible top level window that could accept it.

While this approach might seem more complex, it has its benefits; for instance, you have more control on the context of the shortcut: in the case above, you could trigger Alt+B from any window, including the one shown after previously triggering it, which is clearly not a good thing.

陌若浮生 2025-02-20 09:03:23

将布局添加到主小部件中。

然后将布局传递到创建标签的函数,然后将其添加到布局中。

以下是修改的代码。

在下面的代码中找到作为注释的详细信息。

您的主窗口类

class Mainclass(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Sample Window")

        #CREATE THE LAYOUT HERE IN MAIN WINDOW
        vbox = QVBoxLayout()

        x = Create_workingDict("Accounts","Alt+A",vbox) #PASS THE LAYOUT OBJECT (vbox) AS AN ARGUMENT
        y = Create_workingDict("Inventory", "Ctrl+B",vbox) #PASS THE LAYOUT OBJECT (vbox) AS AN ARGUMENT

        #SET THE LAYOUT TO MAIN WINDOW
        self.setLayout(vbox)

您的功能在创建标签的位置。
观察函数vbox = qvboxlayout() and self.sef.SetLayout(vbox)被移出此功能到主窗口。

class Create_workingDict(QWidget):
    def __init__(self,lblname,lblscut,vbox): #RECEIVE LAYOUT (vbox) ARGUMENT
        super(). __init__()

        self.lblname = lblname
        self.lblscut = lblscut

        lbl_1 = QLabel()
        lbl_1.setText(self.lblname)
        lbl_2 = QLabel()
        lbl_2.setText(self.lblscut)
       
        vbox.addWidget(lbl_1)
        vbox.addWidget(lbl_2)        

        self.msgSc = QShortcut(QKeySequence(f'{self.lblscut}'), self)
        self.msgSc.activated.connect(lambda: QMessageBox.information(self,'Message', 'Ctrl + M initiated'))

Add the layout in main widget.

Then pass the layout to the function where you are creating labels and add them to layout.

Below is the modified code.

Find the details as comments in below code.

Your main window class

class Mainclass(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Sample Window")

        #CREATE THE LAYOUT HERE IN MAIN WINDOW
        vbox = QVBoxLayout()

        x = Create_workingDict("Accounts","Alt+A",vbox) #PASS THE LAYOUT OBJECT (vbox) AS AN ARGUMENT
        y = Create_workingDict("Inventory", "Ctrl+B",vbox) #PASS THE LAYOUT OBJECT (vbox) AS AN ARGUMENT

        #SET THE LAYOUT TO MAIN WINDOW
        self.setLayout(vbox)

Your function where labels created.
Observe that the functions vbox = QVBoxLayout() and self.setLayout(vbox) are moved out of this function to main window.

class Create_workingDict(QWidget):
    def __init__(self,lblname,lblscut,vbox): #RECEIVE LAYOUT (vbox) ARGUMENT
        super(). __init__()

        self.lblname = lblname
        self.lblscut = lblscut

        lbl_1 = QLabel()
        lbl_1.setText(self.lblname)
        lbl_2 = QLabel()
        lbl_2.setText(self.lblscut)
       
        vbox.addWidget(lbl_1)
        vbox.addWidget(lbl_2)        

        self.msgSc = QShortcut(QKeySequence(f'{self.lblscut}'), self)
        self.msgSc.activated.connect(lambda: QMessageBox.information(self,'Message', 'Ctrl + M initiated'))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文