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. At this point this is what you should get in the MAIN WINDOW:
What I want the interface to do is to see the window in picture 2 whenever I click the blue rectangle. I want it to open the new widget IN THE SAME MAIN WINDOW
However, when I click it a new window opens and the previous window remains open (PICTURE 3). This is what I want to avoid, I want only 1 window not 2.
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:
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)
.
The best way is use pyqtSignal()
.
You have to declare the pyqtSignal(int)
in ProcessedSlices
class:
class ProcessedSlices(QWidget):
#here declare signal
signal = pyqtSignal(int)
def __init__(self):
# more code....
And emit the signal in your 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()
:
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)