I created a class containing a method to position a window anywhere on the screen. I am using PyQt4 for GUI programming. I wrote following class:
from PyQt4 import QtGui
class setWindowPosition:
def __init__(self, xCoord, yCoord, windowName, parent = None):
self.x = xCoord
self.y = yCoord
self.wName = windowName;
def AdjustWindow(self):
screen = QtGui.QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
This code needs correction. Any file that imports this class will pass three parameters: desired_X_Position, desired_Y_position and its own name to this class. The method AdjustWindow should accept these three parameters and position the calling window to the desired coordinates.
In the above code, though I have passed the parameters, but not following how to modify the AdjustWindow method.
It is not entirely clear what you are trying to ask, But, you access the values in the method the same way you set them in the constructor.
from PyQt4 import QtGui
class setWindowPosition:
def __init__(self, xCoord, yCoord, windowName, parent = None):
self.x = xCoord
self.y = yCoord
self.wName = windowName;
def AdjustWindow(self):
print self.x, self.y, self.wName //See Here
//now use them how you want
screen = QtGui.QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)
EDIT:
I found this page which seems to be where you grabbed the code from.
Your class is not inheriting from QtGui.QWidget so calls to geometry() and move() are going to fail. Once you do that, it looks like it the code would be:
def AdjustWindow(self):
self.move(self.x, self.y)
However, you still need to figure out how to have your class as the one that controls the window with windowName. It seems like this package is for making GUIs and not controlling external windows. I could be wrong as I have only read enough to make this answer.
Related
I have taken this code from a larger program, and stripped out almost everything so as to illustrate the core of the problem.
The program is used to create multiple "rooms" that initially have the same attributes, but are later changed such that they are two separate objects.
To create two completely independent Room objects, I have tried to use copy.deepcopy(), but this gives: "TypeError: cannot pickle '_curses.window' object"
import curses
from curses import wrapper
import copy
def main(stdscr):
bg = Background(100, 237)
test_room = Room(10, 15, bg)
new_room = copy.deepcopy(test_room)
print("Test deepcopy: ", new_room.height, new_room.width) ### See if attributes copied successfully
class Background():
def __init__(self, height, width):
self.height = height
self.width = width
self.pad = curses.newpad(self.height, self.width)
class Room():
def __init__(self, height, width, background):
self.height = height
self.width = width
self.bg = background.pad
self.pad = background.pad.subpad(self.height, self.width)
### def __deepcopy__(self, memo)
###return self
while True:
curses.wrapper(main)
I see that the problem is with the self.bg and self.pad lines in the Room class; if these are commented out it works in all other respects, but obviously I need these lines for it to do what I need it to do. I tried defining my own deepcopy method (see commented out in Room class below), but I don't really understand how to use it properly and it doesn't appear to solve the problem.
I get that I am probably making multiple mistakes. What am I doing wrong, and what would be a better solution?
I'm attempting to create Conway's Game of Life in Pyqt5 and am unsure how to update my grid to change the color of a particular cell.
My program has a GUI class, board class, and a class for the Lifeform. This method is in the class with the lifeforms. Should I create another paintevent outside of my GUI class? Do I make some object for the GUI that I should reference instead (this approach doesn't make sense when I say it to myself because making an object for the GUI referenced outside the GUI seems like bad design but idk) I posted my method below because I feel my question may not be complicated and I'm just missing something.
def paintWhite(self): #LifeForm Class
screensize = QDesktopWidget().screenGeometry()
cellwidth = screensize.width()//GLOBAL_N #GlobalN x GlobalN grid
cellheight = screensize.height()//GLOBAL_N
paintObject = QPainter()
paintObject.setPen(QPen(Qt.white, 5, Qt.SolidLine))
paintObject.setBrush(QColor(255,255,255))
paintObject.drawRect(cellwidth * self.row, cellheight * self.col, cellwidth,cellheight)
#Seperate Code Snippets
def paintEvent(self,e): #Gui Class
paintObject = QPainter(self)
paintObject.setPen(QPen(Qt.black, 5, Qt.SolidLine))
paintObject.setBrush(QColor(0,0,0))
n=50
for i in range(n):
for j in range(n):
x = paintObject.drawRect(self.width//n*i, self.height//n*j, self.width//n,self.height//n)
There is just no color change. Thank you for any help.
I'm using Qt's Graphics View Framework to display a large number of images, and implementing it using PyQt4 and Python 2.7. I instantiate a number of QPixmapItem objects and add them to my QGraphicsScene. It all works as I'd expect it to until I exit the application, and the program crashes instead of exiting normally.
class ImgDisplay(QtGui.QWidget):
NUM_ITEMS = 5000
VIEW_WIDTH,VIEW_HEIGHT = 400, 400
def __init__(self):
super(ImgDisplay, self).__init__()
self.scene = QtGui.QGraphicsScene(QtCore.QRectF(0,0,ImgDisplay.VIEW_WIDTH,ImgDisplay.VIEW_HEIGHT))
self.view = QtGui.QGraphicsView(self.scene)
self.view.setParent(self)
#Load the texture
self.texture = QtGui.QPixmap('image.png')
self.populateScene()
def populateScene(self):
for i in range(0, ImgDisplay.NUM_ITEMS-1):
item = QtGui.QGraphicsPixmapItem(self.texture)
self.scene.addItem(item)
I'm thinking that all those PixMapItems I'm creating aren't being cleaned up properly, or maybe I need to free the texture that I load (there doesn't seem to be a method to free it, so I assumed it happened in the background).
I've tried calling self.scene.clear in a destructor to delete the PixmapItems, but it didn't help.
Any suggestions on how I can fix this problem?
*I'm aware that the posted code just puts the images all on top of each other, my actual program assigns them random positions and rotations, but I wanted to reduce this to the minimal problem.
OK, understood. Problem is QtGui.QGraphicsPixmapItem can't clear itself your have to manual just like you says, but not destructor. I recommend doing after have signal close program by using closeEvent, like this;
def closeEvent (self, eventQCloseEvent):
self.scene.clear() # Clear QGraphicsPixmapItem
eventQCloseEvent.accept() # Accept to close program
and this implemented you code;
import sys
from PyQt4 import QtCore, QtGui
class ImgDisplay (QtGui.QWidget):
NUM_ITEMS = 5000
VIEW_WIDTH,VIEW_HEIGHT = 400, 400
def __init__ (self):
super(ImgDisplay, self).__init__()
self.scene = QtGui.QGraphicsScene(QtCore.QRectF(0,0,ImgDisplay.VIEW_WIDTH,ImgDisplay.VIEW_HEIGHT))
self.view = QtGui.QGraphicsView(self.scene)
self.view.setParent(self)
#Load the texture
self.texture = QtGui.QPixmap('image.png')
self.populateScene()
def populateScene (self):
for i in range(0, ImgDisplay.NUM_ITEMS-1):
item = QtGui.QGraphicsPixmapItem(self.texture)
self.scene.addItem(item)
def closeEvent (self, eventQCloseEvent):
self.scene.clear()
eventQCloseEvent.accept()
app = QtGui.QApplication([])
window = ImgDisplay()
window.show()
sys.exit(app.exec_())
I use PyQt4 (Windows 7).
And this useful to implement close event, Hope is helps;
QWidget Close Event Reference : http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html#closeEvent
LAST EDITED : 8 / 11 / 2014 01:51
If your want to control your parent & child widget to delete together, I have to implement destructor method (As your say). By use safe delete method QObject.deleteLater (self), Like this;
import sys
from PyQt4 import QtCore, QtGui
class ImgDisplay (QtGui.QWidget):
NUM_ITEMS = 5000
VIEW_WIDTH, VIEW_HEIGHT = 400, 400
def __init__ (self, parent = None):
super(ImgDisplay, self).__init__(parent)
self.scene = QtGui.QGraphicsScene(QtCore.QRectF(0,0,ImgDisplay.VIEW_WIDTH,ImgDisplay.VIEW_HEIGHT), parent = self)
self.view = QtGui.QGraphicsView(self.scene, parent = self)
#Load the texture
self.texture = QtGui.QPixmap('image.png')
self.populateScene()
def populateScene (self):
for i in range(0, ImgDisplay.NUM_ITEMS-1):
item = QtGui.QGraphicsPixmapItem(self.texture)
self.scene.addItem(item)
def __del__ (self):
self.deleteLater() # Schedules this object for deletion
app = QtGui.QApplication([])
window = ImgDisplay()
window.show()
sys.exit(app.exec_())
Warning : Don't forget set parent in your widget ! (Because some time It can't be delete itself.)
deleteLater Reference : http://pyqt.sourceforge.net/Docs/PyQt4/qobject.html#deleteLater
Regards,
I would like to highlight Josh's answer in the comments.
If you create the scene by setting the QGraphicsView as parent the crash will automatically go away.
self.view = QtGui.QGraphicsView(parent = self)
self.scene = QtGui.QGraphicsScene(QtCore.QRectF(0,0,ImgDisplay.VIEW_WIDTH,ImgDisplay.VIEW_HEIGHT), parent = self.view)
self.view.setScene(self.scene)
I want to draw a frame around my borderless dialog while it gets resized interactively but it seems like QDialog.setSizeGripEnabled(True) and QWidget.resizeEvent doen't work well together. The dialog can't be resized interactively, is this a known problem ?
class MyDialog(QtGui.QDialog):
def __init__(self,x,y):
QtGui.QDialog.__init__(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setGeometry(x,y,250,300)
self.setSizeGripEnabled(True)
self.frame = QtGui.QFrame(self)
self.frame.setGeometry(self.rect())
self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
self.frame.setFrameShadow(QtGui.QFrame.Plain)
etc...
def resizeEvent( self, event ):
r = self.rect()
s = event.size()
self.frame.setGeometry( r.x(), r.y(), s.width(), s.height() )
The problem here is, that you override the resizeEvent without passing it on, this seems to break the functionality of the generated size grip.
The simplest solution would be to call:
super(MyDialog, self).resizeEvent(event)
in your event handler. Another option is to add your own QResizeGrip to your frame:
class MyDialog(QtGui.QDialog):
def __init__(self,x,y):
# [...]
self.frame.setLayout(QtGui.QVBoxLayout())
self.sizeGrip = QtGui.QSizeGrip(self.frame)
self.frame.layout().addWidget(self.sizeGrip, 0,
QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom)
self.setStyleSheet("QSizeGrip {background-color: #202020}") # make it visible
# [...]
This has the advantage that you can arrange the size grip freely.
I have the following outline of a Python program (using PyQt4):
class Polygon( QtGui.QGraphicsItem ):
def __init__(self):
super(Polygon, self).__init__()
def addpoint( self, point ):
if last_point:
# trying to add auto-save here
class MainWidget(QtGui.QWidget):
openFileName = ""
list_of_polygons = []
def __init__(self):
super(MainWidget, self).__init__()
def openFile( self ):
call dialog
self.openFileName = ...
def saveFile( self ):
# needs to access a couple something with self.variables, like self.openFileName
def main():
app = QtGui.QApplication(sys.argv)
ex = MainWidget()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Functionality is an image viewer where I'm creating polygons to tag object. I'd like to call an auto-save once a polygon has been created.
So for saving a polygon I need to call it from the saveFile function MainWidget class. My problem is that the saving functionality is implemented in the MainWidget class, and I don't know how to access them from inside the Polygon class.
What would be the best idea to do this? Should I make saveFile global? If yes, then how do I access the self. variables of the MainWidget?
You probably need to pass the widget object to the Polygon when you create it so that it knows what its "parent" widget object is:
class Polygon( QtGui.QGraphicsItem ):
def __init__(self, parent):
self.parent = parent
# ...
(and then foo = Polygon(your_widget) when you create it).
Then you can just call self.parent.saveFile(...) or whatnot.