简体   繁体   English

使用PyQt5,QWidget不会出现在QMainWindow中

[英]QWidget does not appear in the QMainWindow using PyQt5

What I want is an interface which opens windows under a SINGLE window, that is, I do NOT want the interface to open extra windows. 我想要的是一个在单个窗口下打开窗口的界面,也就是说,我不希望该界面打开其他窗口。 I will guide you to my error. 我将指导您解决我的错误。 When I run my code I get a home page, from there I click on View/Edit --> View/Edit Processed Slices. 运行代码时,我得到一个主页,从那里单击View / Edit-> View / Edit Processed Slices。 At this point this is what you should get in the MAIN WINDOW: 此时,您应该在主窗口中看到以下内容:

PICTURE 1 图片1 在此处输入图片说明

What I want the interface to do is to see the window in picture 2 whenever I click the blue rectangle. 我希望界面执行的操作是每当我单击蓝色矩形时都看到图2中的窗口。 I want it to open the new widget IN THE SAME MAIN WINDOW 我希望它在相同的主窗口中打开新的小部件

PICTURE 2 图片2 在此处输入图片说明

However, when I click it a new window opens and the previous window remains open (PICTURE 3). 但是,当我单击它时,将打开一个新窗口,并且先前的窗口保持打开状态(图3)。 This is what I want to avoid, I want only 1 window not 2. 这是我要避免的事情,我只需要1个窗口而不是2个窗口。

PICTURE 3 图片3 在此处输入图片说明

Here is the code: 这是代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import cv2
import numpy as np
"""
    MAIN WINDOW
"""
class CancerSegWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'Cancer Segmentation GUI               '
        self.initUI()


    def initUI(self):               

        self.central = HOME()
        self.setCentralWidget(self.central)

        ##
        # ACTIONS
        ##

        ##File
            #Exit
        exitAct = QAction(QIcon('E:\BEATSON_PROJECT\python\GUI\exit.png'), 'Exit', self)    # QAction is an abstraction for actions performed with a menubar, toolbar, or with a custom keyboard shortcut
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')                                            # Status tip at the bottom
        exitAct.triggered.connect(self.close)                                               # Triggered signal is emitted. The signal is connected to the close() method of the QMainWindow widget.

            #Home
        HomeAct = QAction(QIcon('E:\BEATSON_PROJECT\python\GUI\home.png'), 'Home', self)    
        HomeAct.setStatusTip('Go Home')                                            
        HomeAct.triggered.connect(self.Home) 

        ## View and Edit

            # Slices

                # Processed Slices
        ProcessedAct = QAction('View / Edit Processed Slices', self)  
        ProcessedAct.triggered.connect(self.Processed_Slices)

        self.statusBar().showMessage('Home')                   # First call statusBar creates a status bar at the bottom
                                                                # Subsequent calls return the statusbar object
        ##
        # main MENU bar 
        ##

        menubar = self.menuBar()                # create a menubar

        # File

        fileMenu = menubar.addMenu('File')              # File  (menu)
        fileMenu.addAction(exitAct)                         # Exit

        # View and Edit                                 

        veMenu = menubar.addMenu('View / Edit')       # View and Edit (menu)
        vesMenu = QMenu('View / Edit Slices',self)            # Slices
        vesMenu.addAction(ProcessedAct)                             # Processed
        veMenu.addMenu(vesMenu)

        ##
        # ICONS
        ##
        toolbar = self.addToolBar('Exit')         
        toolbar.addAction(exitAct)

        toolbarHome = self.addToolBar('Home')
        toolbarHome.addAction(HomeAct)
        ##
        # WINDOW
        ##
        self.setGeometry(0, 30, 1366, 697) 
        self.setWindowTitle(self.title)
        self.setWindowIcon(QIcon('E:\BEATSON_PROJECT\python\GUI\medicine.png'))
        self.show()

    def Home (self):
        self.central = HOME()
        self.setCentralWidget(self.central)

    def Processed_Slices (self):
        self.statusBar().showMessage('Displaying Processed Slices. Click on one Slice to View and Edit it individually') 
        self.central = ProcessedSlices()
        self.setCentralWidget(self.central)
        self.setWindowTitle(self.title + self.central.title)

    def Pre_Edit_Processed (self, SliceNo=1):
        self.statusBar().showMessage('Displaying Automatic Processed Slice' + str(SliceNo) + ' You can redraw it manually or modify the existing contour') 
        self.central = PreEditProcessed(SliceNo)
        self.setCentralWidget(self.central)
        self.setWindowTitle(self.title + self.central.title)

"""
    HOME WINDOW
"""
class HOME (QWidget):
    def __init__(self):
        super().__init__()
        #self.central = QPixmap("E:\BEATSON_PROJECT\python\GUI\Home_.png") 
        self.lbl1 = QLabel(self)
        #self.lbl1.setPixmap(self.central)

"""
    PROCESSED SLICES WINDOW
"""
class ProcessedSlices(QWidget):
    def __init__(self):
        super().__init__()
        self.title = ('- Processed Slices')
        self.initUI()


    def initUI(self): 

        ##
        #CHECKBOXES
        ##

        # Slice 1 
                                                    #CheckBox
        self.cb1 = QCheckBox('Slice 1', self)              
        self.cb1.move(1270, 115)
        self.cb1.toggle()
        self.cb1.stateChanged.connect(self.OpenSlice1)

                                                 #Pixmap (Image) 1
        pixmap1 = QPixmap(310, 330)         # Contour
        pixmap1.fill(Qt.blue)
        #pixmap1 = QPixmap("E:\BEATSON_PROJECT\python\GUI\Processed_Slice_1.png") 
        self.lbl1 = QLabel(self)
        self.lbl1.setGeometry(QRect(QPoint(10,0),QPoint(310,330))) # 
        self.lbl1.setPixmap(pixmap1)

        ##
        # SET GRID to obtain the mouse position
        ##

        grid = QGridLayout()
        self.text = "x: {0},  y: {1}".format(0, 0)          # display the x and y coordinates of a mouse pointer in a label widget

        self.label = QLabel(self.text, self)                # x and y coordinates are displayd in a QLabel widget
        grid.addWidget(self.label, 0, 1270, Qt.AlignTop)


        self.setLayout(grid)


        ##
        #WINDOW
        ##

        #self.setGeometry(0, 25, 1365, 700)
        #self.setWindowTitle('Processed Slices')
        self.show()


    def OpenSlice1(self, state):
        self.lbl1.setVisible(state == Qt.Checked)


    def mousePressEvent(self, e):                                     # The e is the event object. it contains data about the event that was triggered
        x = e.x()                                                     # in our case, a mouse CLICK                                          
        y = e.y()                                                     #  x() and y() methods we determine the x and y coordinates of the mouse pointer
        text = "None selected x: {0},  y: {1}"

        if ( x >= 10 and x <= 310 and y >= 0 and y <= 330 and self.cb1.isChecked()):
            text = "Slice 1 x: {0},  y: {1}".format(x, y)
            self.close()
            self.CSW = CancerSegWindow()
            self.CSW.Pre_Edit_Processed(1)

        self.label.setText(text)

"""
    PROCESSED SLICES CHECK WINDOW
"""
class PreEditProcessed(QWidget):
    def __init__(self, SliceNo=1):
        super().__init__()
        self.title = ('- Check Processed Slices')
        self._SliceNo = SliceNo
        self.initUI()

    def initUI(self):
        #self.draw = Draw(self)
        #self.draw._windows = 1

        # Button to clear both image and drawing
        self.button = QPushButton('Discard and segment MANUALLY ', self)            
        #self.button.clicked.connect(self.editManually)

        # Button to modify contour
        self.BmodContour = QPushButton('Modify existing contour ', self)            
        #self.BmodContour.clicked.connect(self.modContour)

        # Button to finish and compare
        self.BFinish = QPushButton('Finish ', self)         
        #self.BFinish.clicked.connect(self.Finish)

        # Arrange Layout

        self.layout = QVBoxLayout(self)                         
        #self.layout.addWidget(self.draw)       # Show Slice
        self.layout.addWidget(self.button)      # Manually
        self.layout.addWidget(self.BmodContour) # Modify contour
        self.layout.addWidget(self.BFinish)     # Finish and compare

        self.setGeometry(0, 25, 1365, 700)
        self.setWindowTitle('Check Slices')
        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = CancerSegWindow()
    sys.exit(app.exec_())

Note that the relevant part of the code is inside class ProcessedSlices: 注意,代码的相关部分在类ProcessedSlices中:

def mousePressEvent(self, e):                                     
        x = e.x()                                                     
        y = e.y()                                                     
        text = "None selected x: {0},  y: {1}"

        if ( x >= 10 and x <= 310 and y >= 0 and y <= 330 and self.cb1.isChecked()):
            text = "Slice 1 x: {0},  y: {1}".format(x, y)
            self.close()
            self.CSW = CancerSegWindow()
            self.CSW.Pre_Edit_Processed(1)

Your problem is that you are creating another instance of the class CancerSegWindow() in the function mousePressEvent(self, e) . 您的问题是您要在mousePressEvent(self, e)函数中创建类CancerSegWindow()另一个实例。

The best way is use pyqtSignal() . 最好的方法是使用pyqtSignal()

You have to declare the pyqtSignal(int) in ProcessedSlices class: 您必须在ProcessedSlices类中声明pyqtSignal(int)

class ProcessedSlices(QWidget):
    #here declare signal
    signal = pyqtSignal(int)
    def __init__(self):
    # more code....

And emit the signal in your mousePressEvent(self, e) : 并在mousePressEvent(self, e)发出信号:

def mousePressEvent(self, e):                                     # The e is the event object. it contains data about the event that was triggered
    x = e.x()                                                     # in our case, a mouse CLICK                                          
    y = e.y()                                                     #  x() and y() methods we determine the x and y coordinates of the mouse pointer
    text = "None selected x: {0},  y: {1}"

    if ( x >= 10 and x <= 310 and y >= 0 and y <= 330 and self.cb1.isChecked()):
        text = "Slice 1 x: {0},  y: {1}".format(x, y)
        self.close()
        self.signal.emit(1) # emit signal with SliceNo=1

    self.label.setText(text)

Finally, capture it in your Processed_Slices() : 最后,在您的Processed_Slices()捕获它:

def Processed_Slices (self):
    self.statusBar().showMessage('Displaying Processed Slices. Click on one Slice to View and Edit it individually') 
    self.central = ProcessedSlices()
    self.central.signal.connect(self.Pre_Edit_Processed) #connect signal
    self.setCentralWidget(self.central)
    self.setWindowTitle(self.title + self.central.title)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM