如何防止 PyQt 小部件被掩盖?

Posted

技术标签:

【中文标题】如何防止 PyQt 小部件被掩盖?【英文标题】:How can I prevent a PyQt widget from getting covered-up? 【发布时间】:2015-07-19 16:36:22 【问题描述】:

我正在创建一个界面,该界面由嵌入在 PyQt GUI 中的终端组成,旁边有一些按钮,用于在该终端中运行命令。当我运行我的代码时,我认为部分 GUI 已正确创建,但终端小部件已被掩盖。我怎样才能防止这种情况发生?

import sys
from PyQt4 import QtCore, QtGui

class embedded_terminal(QtGui.QWidget):

    def __init__(self):

        QtGui.QWidget.__init__(self)
        self._processes = []
        self.resize(800, 800)

        # set grid layout

        grid = QtGui.QGridLayout()

        # layout group for buttons

        group_buttons = QtGui.QGroupBox()
        vbox = QtGui.QVBoxLayout()
        # define buttons
        button_list = self.command_button(
            title   = "ls",
            command = "ls"
        )
        button_terminate = QtGui.QPushButton("terminate")
        button_terminate.clicked.connect(lambda: self.terminate())
        # style buttons and add buttons to layout
        buttons = []
        buttons.append(button_list)
        buttons.append(button_terminate)
        for button in buttons:
            self.set_button_style(button)
            vbox.addWidget(button)
        vbox.addStretch(1)
        group_buttons.setLayout(vbox)

        # layout group for terminal

        group_terminal = QtGui.QGroupBox()
        group_terminal.setLayout(vbox)
        vbox = QtGui.QVBoxLayout()
        # terminal
        self.terminal = QtGui.QWidget(self)
        vbox.addWidget(self.terminal)
        vbox.addStretch(1)
        group_terminal.setLayout(vbox)

        # add layout groups to grid layout
        grid.addWidget(group_buttons, 0, 0)
        grid.addWidget(group_terminal, 0, 1)
        self.setLayout(grid)

        self.start_process(
            "xterm",
                [
                    "-fn",
                    "-misc-fixed-*-*-*-*-18-*-*-*-*-*-*-*",
                    "-into",
                    str(self.terminal.winId()),
                    "-e",
                    "tmux",
                    "new",
                    "-s",
                    "session1"
                ]
        )

    def start_process(
        self,
        program,
        options
        ):
        child = QtCore.QProcess()
        self._processes.append(child)
        child.start(program, options)

    def run_command(
        self,
        command = "ls"
        ):
        program = "tmux"
        options = []
        options.extend(["send-keys", "-t", "session1:0"])
        options.extend([command])
        options.extend(["Enter"])
        self.start_process(program, options)

    def command_button(
        self,
        title   = None,
        command = None
        ):
        button = QtGui.QPushButton(title)
        button.clicked.connect(lambda: self.run_command(command = command))
        return button

    def set_button_style(
        self,
        button
        ):
        # Set button style.
        button.setStyleSheet(
            """
            color: #color1;
            background-color: #color2;
            border: 1px solid #color1;
            """.format(
                color1 = "3861aa",
                color2 = "ffffff"
            )
        )
        # Set button dimensions.
        button.setFixedSize(
            300,
            60
        )

    def terminate(self):
        program = "tmux"
        options = []
        options.extend(["send-keys", "-t", "session1:0"])
        options.extend(["killall tmux"])
        options.extend(["Enter"])
        self.start_process(program, options)
        QtGui.QApplication.instance().quit()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    main = embedded_terminal()
    main.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

对不起我的英语。

您有一个错误:在创建布局之前添加布局。因此,您附加到group_terminalvbox 与附加到group_buttonsvbox 相同。

# layout group for terminal
group_terminal = QtGui.QGroupBox()
group_terminal.setLayout(vbox) # <- old one
vbox = QtGui.QVBoxLayout()

此外,Qt 对xterm 窗口的大小一无所知。似乎您必须手动指定它。此代码工作正常:

group_terminal = QtGui.QGroupBox()
vbox = QtGui.QVBoxLayout()
group_terminal.setLayout(vbox)

# terminal
self.terminal = QtGui.QWidget()
self.terminal.setFixedSize(730, 440)

【讨论】:

以上是关于如何防止 PyQt 小部件被掩盖?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PyQt 中的样式表将小部件放在前面?

多个文件中的 PyQt 小部件

Pyqt5 addStretch 在小部件之间?

如何在 PyQt5 中用另一个小部件替换一个小部件

如何在PyQt5中叠加小部件?

在子窗口小部件活动时阻止 QMa​​inWindow ,pyqt