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

时间:2015-11-25 18:54:32

标签: python pyqt window buttonclick

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

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()

这是我的第二个窗口,我想用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()

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

1 个答案:

答案 0 :(得分:5)

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

if __name__ == '__main__':
    runNewLib()

否则,每次尝试导入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()

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

new_lib_btn.clicked.connect(self.create_new_library_window)

工作示例

此示例创建一个带有一个大按钮的主窗口,单击该按钮将打开第二个窗口。它使用两个继承自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_()

__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_()

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