如何正确删除小部件并更新/重新加载小部件
Posted
技术标签:
【中文标题】如何正确删除小部件并更新/重新加载小部件【英文标题】:how to properly remove qwidgets and update/reload that widget 【发布时间】:2019-07-31 01:07:36 【问题描述】:尝试删除一个 qwidget 并用另一个 qwidget 替换它,然后重新加载 qwidget 所属的布局
我已经尝试过 update 和 removeWidget 方法,虽然我可能使用不当
from PyQt5.Qt import *
import sys
validUser = False
app = None
class App(QMainWindow):
def __init__(self):
super().__init__()
screen = app.primaryScreen().size()
self.title = 'Restaurant Application'
width = screen.width()
height = screen.height()
self.left = 0
self.top = 0
self.width = width
self.height = height
self.setMouseTracking(True)
self.table_widget = MyTableWidget(self)
self.setCentralWidget(self.table_widget)
self.initUI()
self.show()
def initUI(self):
# window
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# statusbar
self.statusBar().showMessage('Welcome to el restaurante')
def mousePressEvent(self, event):
print('Mouse coords: ( %d : %d )' % (event.x(), event.y()))
class MyTableWidget(QWidget):
def __init__(self, parent):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
# Initialize tab screen
self.tabs = QTabWidget()
self.login = QWidget()
self.menu = QWidget()
self.checkOut = QWidget()
self.tabs.resize(500, 200)
# Add tabs
self.tabs.addTab(self.login, "Login")
self.tabs.addTab(self.menu, "Menu")
self.tabs.addTab(self.checkOut, "Check out")
# Create login tab
self.login.layout = QVBoxLayout(self)
self.menu.layout = QVBoxLayout(self)
# login text
self.loginPrompt = QLabel("Please provide a valid login")
self.loginPrompt.setFixedSize(315,30)
self.loginPromptFont = QFont("Times", 27, QFont.Bold)
self.loginPrompt.setFont(self.loginPromptFont)
self.login.layout.addWidget(self.loginPrompt)
self.login.setLayout(self.login.layout)
# Create textbox
self.loginTextbox = QLineEdit(self)
self.loginTextbox.returnPressed.connect(self.on_click_login)
self.loginTextbox.setFixedSize(170,20)
# Create a button in the window
self.loginButton = QPushButton('Login button', self)
self.loginButton.clicked.connect(self.on_click_login)
self.loginButton.setFixedSize(100,40)
self.login.layout.addWidget(self.loginTextbox,alignment=Qt.AlignCenter)
self.login.layout.addWidget(self.loginButton,alignment=Qt.AlignCenter)
#widget code i use to decide which widget to add
self.menuInvalidUserLogin = QLabel("Please login in to view")
self.menuValidUserLogin = QLabel("Here's the menu")
if(validUser):
self.menu.layout.addWidget(self.menuValidUserLogin)
else:
self.menu.layout.addWidget(self.menuInvalidUserLogin)
self.menu.setLayout(self.menu.layout)
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
def on_click_login(self):
global validUser
global app
textboxValue = self.loginTextbox.text()
if(textboxValue.lower() == 'pass'):
validUser=True
#the solutions i have been trying
self.menu.layout.removeWidget(self.menuInvalidUserLogin)
self.layout.removeWidget(self.menuInvalidUserLogin)
self.menu.layout.update()
QMessageBox.question(self, 'Response', "Login successful: Welcome", QMessageBox.Ok,QMessageBox.Ok)
else:
validUser=False
QMessageBox.question(self, 'Response', "Login unsuccessful: EXPLAIN YOURSELF", QMessageBox.Ok,QMessageBox.Ok)
self.loginTextbox.setText("")
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
预期的结果应该是删除旧的小部件,添加新的小部件,然后刷新这些小部件所属的布局
【问题讨论】:
【参考方案1】:这是你所期待的吗?
另外,您在课堂上使用全局变量是否有特定原因?这是不好的做法,您应该让他们成为班级成员。
from PyQt5 import QtWidgets, QtCore, QtGui
import sys
class App(QtWidgets.QMainWindow):
def __init__(self):
super(App,self).__init__()
app = QtWidgets.QApplication.instance()
screen = app.primaryScreen().size()
self.title = 'Restaurant Application'
width = screen.width()
height = screen.height()
self.left = 0
self.top = 0
self.width = width
self.height = height
self.setMouseTracking(True)
self.table_widget = MyTableWidget(self)
self.setCentralWidget(self.table_widget)
self.initUI()
self.show()
def initUI(self):
# window
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# statusbar
self.statusBar().showMessage('Welcome to el restaurante')
def mousePressEvent(self, event):
print('Mouse coords: ( %d : %d )' % (event.x(), event.y()))
class MyTableWidget(QtWidgets.QWidget):
def __init__(self, parent):
super(MyTableWidget, self).__init__(parent)
self.layout = QtWidgets.QVBoxLayout()
self.validUser = False
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.login = QtWidgets.QWidget()
self.menu = QtWidgets.QWidget()
self.checkOut = QtWidgets.QWidget()
self.tabs.resize(500, 200)
# Add tabs
self.tabs.addTab(self.login, "Login")
self.tabs.addTab(self.menu, "Menu")
self.tabs.addTab(self.checkOut, "Check out")
# Create login tab
self.login.layout = QtWidgets.QVBoxLayout()
self.menu.layout = QtWidgets.QVBoxLayout()
# login text
self.loginPrompt = QtWidgets.QLabel("Please provide a valid login")
self.loginPrompt.setFixedSize(315,30)
self.loginPromptFont = QtGui.QFont("Times", 27, QtGui.QFont.Bold)
self.loginPrompt.setFont(self.loginPromptFont)
self.login.layout.addWidget(self.loginPrompt)
self.login.setLayout(self.login.layout)
# Create textbox
self.loginTextbox = QtWidgets.QLineEdit()
self.loginTextbox.returnPressed.connect(self.on_click_login)
self.loginTextbox.setFixedSize(170,20)
# Create a button in the window
self.loginButton = QtWidgets.QPushButton('Login button')
self.loginButton.clicked.connect(self.on_click_login)
self.loginButton.setFixedSize(100,40)
self.login.layout.addWidget(self.loginTextbox,alignment=QtCore.Qt.AlignCenter)
self.login.layout.addWidget(self.loginButton,alignment=QtCore.Qt.AlignCenter)
#widget code i use to decide which widget to add
self.menuInvalidUserLogin = QtWidgets.QLabel("Please login in to view")
self.menuValidUserLogin = QtWidgets.QLabel("Here's the menu")
if(self.validUser):
self.menu.layout.addWidget(self.menuValidUserLogin)
else:
self.menu.layout.addWidget(self.menuInvalidUserLogin)
self.menu.setLayout(self.menu.layout)
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
def on_click_login(self):
textboxValue = self.loginTextbox.text()
if(textboxValue.lower() == 'pass'):
self.validUser=True
for i in reversed(range(self.menu.layout.count())):
widgetToRemove = self.menu.layout.itemAt(i).widget()
self.menu.layout.removeWidget(widgetToRemove)
widgetToRemove.deleteLater()
self.menu.layout.addWidget(self.menuValidUserLogin)
QtWidgets.QMessageBox.question(self, 'Response', "Login successful: Welcome", QtWidgets.QMessageBox.Ok,QtWidgets.QMessageBox.Ok)
self.tabs.setCurrentIndex(1)
else:
self.validUser=False
QtWidgets.QMessageBox.question(self, 'Response', "Login unsuccessful: EXPLAIN YOURSELF", QtWidgets.QMessageBox.Ok,QtWidgets.QMessageBox.Ok)
self.loginTextbox.setText("")
def main():
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
【讨论】:
是的,这行得通!你能解释一下代码对 setParent(None) 的作用吗?代码如何知道在没有“update()”方法的情况下调用用于菜单选项卡的方法。你知道为什么 removeWidget 方法不起作用吗?而且我还收到有关“QLayout:尝试将 QLayout”添加到 MyTableWidget“”的警告,它已经有一个布局” @ShahrozImtiaz 我更新了代码以从布局列表和 GUI 中删除小部件。从技术上讲,您并没有删除只是将其设置为***小部件的对象。更新后的代码是否仍会向您发出有关 QLayout 的警告?另外,它在哪里抛出这个错误? @ShahrozImtiaz removeWidget 只是从布局中删除小部件,但实际上并没有删除对象,它使布局不再使用它,但对象仍然存在。 @ShahrozImtiaz 如果我的回答解决了您的问题,请点赞并标记为已解决。 是的,警告会打印到控制台,所以我不知道是哪里/是什么原因造成的以上是关于如何正确删除小部件并更新/重新加载小部件的主要内容,如果未能解决你的问题,请参考以下文章