如何使用PyQt从另一个窗口单击按钮打开一个窗口?

Sam*_* L. 0 python window pyqt buttonclick

我正在尝试创建一个应用程序,但我不断被这个"简单"的东西打了一拳,如何通过点击按钮打开一个新窗口?我尝试使用new_lib_btn.clicked.connect(newlib),newlib是包含我的第二个窗口的文件,new_lib_btn是应该打开窗口的按钮,它在我的主窗口中,你可以在这里看到:

mainwindow.py

from PyQt4 import QtCore, QtGui
import newlib
import sys
# Main Window

class Window (QtGui.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        centralwidget = QtGui.QWidget(self)
        self.mainLayout = QtGui.QVBoxLayout(centralwidget)
        self.mainLayout.setAlignment(QtCore.Qt.AlignCenter)
        self.setCentralWidget(centralwidget)

        self.resize(800, 600)
        self.setWindowTitle("Virtual Library")
        self.setStyleSheet("Window {border-image: url(lib.jpg);}")

        # ExitOption
        menu_action1 = QtGui.QAction("Exit", self)
        menu_action1.setShortcut("Ctrl+Q")
        menu_action1.setStatusTip('Exit The App')
        menu_action1.triggered.connect(self.close_application)

        self.statusBar()

        # MenuBar
        main_menu = self.menuBar()
        file_menu = main_menu.addMenu('Options')
        file_menu.addAction(menu_action1)



        self.home()

    def home(self):
        # NewLibrary btn
        new_lib_btn = QtGui.QPushButton("New Library", self)
        new_lib_btn.setGeometry(QtCore.QRect(310, 180, 141, 41))
        new_lib_btn.setStyleSheet("color: black;")

        # AccessLibrary btn
        access_lib_btn = QtGui.QPushButton("Access Library", self)
        access_lib_btn.setGeometry(QtCore.QRect(310, 250, 141, 41))
        access_lib_btn.setStyleSheet("color: black;")

        # FindNewBooks btn
        find_nbooks = QtGui.QPushButton("Find New Books*", self)
        find_nbooks.setGeometry(QtCore.QRect(310, 320, 141, 41))
        find_nbooks.setStyleSheet("color: black;")

        self.mainLayout.addWidget(new_lib_btn)
        self.mainLayout.addWidget(access_lib_btn)
        self.mainLayout.addWidget(find_nbooks_btn)
        self.show()

    def close_application(self):
        choice = QtGui.QMessageBox.question(self, 'Exit',
                                        "Close the application?",
                                        QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
        if choice == QtGui.QMessageBox.Yes:
            sys.exit()
        else:
            pass


def run():
    app = QtGui.QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())


run()
Run Code Online (Sandbox Code Playgroud)

这是我的第二个窗口,我要打开的窗口 new_lib_btn

newlib.py

class NewLibrary (QtGui.QMainWindow):
    def __init__(self):
         super(NewLibrary, self).__init__()

         self.resize(800,600)
         self.setWindowTitle("New Library")
         self.setStyleSheet("NewLibrary {border-image: url(wood.jpg);}")

         # File Options
         file_action1 = QtGui.QAction("New Library", self)
         file_action1.setShortcut("Ctrl+N")
         file_action1.setStatusTip("Creates a new library")

         file_action2 = QtGui.QAction("Exit this!", self)
         file_action2.setShortcut("Ctrl+Q")
         file_action2.setStatusTip("Closes The App")
         file_action2.triggered.connect(self.close_application)

         #File Menu
         main_menu = self.menuBar()
         file_menu = main_menu.addMenu("File")
         file_menu.addAction(file_action1)
         file_menu.addAction(file_action2)
         self.newLib()

         self.newLib()

     def newLib(self):
         centralwidget = QtGui.QWidget(self)
         self.mainLayout = QtGui.QVBoxLayout(centralwidget)
         self.mainLayout.setAlignment(QtCore.Qt.AlignCenter)

         #some useful buttons in the future

         self.setCentralWidget(centralwidget)
         self.show()

     def close_application(self):
         choice = QtGui.QMessageBox.question(self, 'Exit',
                                        "Close the application?",
                                        QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
         if choice == QtGui.QMessageBox.Yes:
             sys.exit()
         else:
             pass
def runNewLib():
    app = QtGui.QApplication(sys.argv)
    gui = NewLibrary()
    sys.exit(app.exec_())
runNewLib()
Run Code Online (Sandbox Code Playgroud)

我搜索了很多关于这个,但我无法理解那些与我的情况有点接近的,所以我求助,看起来很简单,但我没有得到它:/,我该怎么办点击打开第二个窗口new_lib_btn?请帮助.

JCV*_*mme 5

我认为您发布的代码存在一些问题.首先,有两次调用self.newLib()NewLibrary构造函数.其次,您可能希望将该调用放在块后面runNewLib()的底部,如下所示:newlib.pyif __name__...

if __name__ == '__main__':
    runNewLib()
Run Code Online (Sandbox Code Playgroud)

否则,每次尝试导入时newlib.py,它都会尝试将NewLibrary作为单独的应用程序运行.

前往你问的问题,我不认为你真的想呼吁self.show()在任一Window.home()NewLibrary.newLib().更典型的模式是创建一个实例WindowNewLibrary然后调用show()该实例.所以,在你的Window课堂上,你要添加一个函数来创建一个实例NewLibrary然后在其上调用show,就像这样

def create_new_library_window(self):
    self.new_lib = newlib.NewLibrary()
    self.new_lib.show()
Run Code Online (Sandbox Code Playgroud)

请注意,正如ekhumoro指出的那样,你必须保持对new_lib的引用,否则它将在函数退出时收集垃圾.然后在NewLibrary.home()你创建new_lib_btn连接它到这个新函数之后:

new_lib_btn.clicked.connect(self.create_new_library_window)
Run Code Online (Sandbox Code Playgroud)

工作实例

此示例创建一个带有一个大按钮的主窗口,单击该按钮将打开第二个窗口.它使用两个继承自QMainWindow的类,如您的问题所示.首先,在main.py:

from PyQt4 import QtGui
from new_window import NewWindow


class Window(QtGui.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self._new_window = None
        self._button = QtGui.QPushButton('New Window', self)
        self._button.clicked.connect(self.create_new_window)
        self.setCentralWidget(self._button)

    def create_new_window(self):
        self._new_window = NewWindow()
        self._new_window.show()

if __name__ == '__main__':
    app = QtGui.QApplication([])
    gui = Window()
    gui.show()
    app.exec_()
Run Code Online (Sandbox Code Playgroud)

__init__功能创建一个按钮并将其连接到该create_new_window功能.单击按钮时,create_new_window将调用该按钮.在内部create_new_window,我们创建一个实例NewWindow并将其分配给类成员,以维护对窗口的引用并防止它被垃圾回收.然后我们调用show这个新窗口来显示它.

在底部,我们使用通常的if __name__ == '__main__':模式来控制此文件是否运行应用程序.如果从命令行执行此文件(如python main.py),则__name__ == '__main__'计算结果为true,并且将启动GUI应用程序.这样做的好处是允许文件具有双重用途:它可以作为标准python包导入,也可以作为应用程序执行,所有这些都使用相同的文件.

然后在new_window.py:

from PyQt4 import QtGui


class NewWindow(QtGui.QMainWindow):
    def __init__(self):
        super(NewWindow, self).__init__()
        self._new_window = None
        self._label = QtGui.QLabel('Hello, is it me you\'re looking for?')
        self.setCentralWidget(self._label)


if __name__ == '__main__':
    app = QtGui.QApplication([])
    gui = NewWindow()
    gui.show()
    app.exec_()
Run Code Online (Sandbox Code Playgroud)

此文件定义了第二个QMainWindow,它使用标签作为其中心窗口小部件.它也使用了__name__ == '__main__'模式; 此文件也可以作为独立应用程序执行或main.py如上所述导入.

  • `create_new_library_window`不完整.它需要一个`self`参数,并且应该是`Window`类的一个方法.它还需要保持对`new_lib`的引用,否则当窗口返回时,新窗口将被垃圾收集(即`self.new_lib = newlib.NewLibrary(); self.new_lib.show()`). (2认同)