WxPython import widgets from other classes - python

I'm a beginner in WxPython and I've tried experimenting splitting up the code to make it organized and look neater. I've tried it with simple code but it doesn't work. Can anyone please give me a hand?
The code I've tried:
import wx
class text_ctrl ( wx.Panel ):
def __init ( self, parent ):
wx.Panel.__init__ ( self, parent = parent )
text = wx.TextCtrl ( self, pos = ( 100, 100 ) )
class Window ( wx.Frame ):
def __init__ ( self ):
super().__init__ ( parent = None, title = "Learn - Tab TextBox" )
panel = wx.Panel()
text_ctrl ( self )
self.Show()
if __name__ == "__main__":
app = wx.App()
window = Window()
app.MainLoop()
Problem: Textbox doesn't show up ( which is supposed to be the main point ).

For want of a nail the kingdom was lost
You are missing a __
Without the init, nothing occurs when you call text_ctrl
import wx
class text_ctrl ( wx.Panel ):
#def __init ( self, parent ):
def __init__ ( self, parent ):
wx.Panel.__init__ ( self, parent = parent )
text = wx.TextCtrl ( self, pos = ( 100, 100 ) )
class Window ( wx.Frame ):
def __init__ ( self ):
super().__init__ ( parent = None, title = "Learn - Tab TextBox" )
# panel = wx.Panel()
text_ctrl ( self )
self.Show()
if __name__ == "__main__":
app = wx.App()
window = Window()
app.MainLoop()

Related

Insert a Widget into another Window

I have googled for a long time and I could'nt find a solution to my problem.
I am trying to create a window in which you can display multiple instances of another widget, just like you can see in the picture. The widgets are supposed to be different uploads you can manage with them. This is the code I wrote and
self.UploadArea.addWidget(uic.loadUi('gui_files/module.ui'))
is supposed to open the Widget inside a QWidget called "UploadArea" it probably is coded like garbage and does not make any sense but it would be nice if you could tell me an elegant answer to my problem.
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args):
super(MainWindow, self).__init__(*args)
uic.loadUi('gui_files/mainWindow.ui', self)
self.upload.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print("Test")
self.UploadArea.addWidget(uic.loadUi('gui_files/module.ui'))
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Widget and MainWindow
How it is supposed to look
Thank you for your help
Lennard
You are close - you can create multiple instances of a QWidget and then add these to your QMainWindow. Here is a minimal working example:
from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
class SubWidget( QWidget ) :
def __init__ ( self, parent = None ) :
super( SubWidget, self ).__init__( parent )
button = QPushButton( 'toggle' )
checkbox = QCheckBox( 'check' )
button.clicked.connect( checkbox.toggle )
hLayout = QHBoxLayout( self )
hLayout.addWidget( button )
hLayout.addWidget( checkbox )
self.setLayout( hLayout )
class Window( QMainWindow ) :
def __init__ ( self, parent = None ) :
super( Window, self ).__init__( parent )
# loadUi( 'main-something.ui', self )
button = QPushButton( 'add' )
button.clicked.connect( self.add )
self.vLayout = QVBoxLayout( self )
self.vLayout.addWidget( button )
centralWidget = QWidget()
centralWidget.setLayout( self.vLayout )
self.setCentralWidget( centralWidget )
def add ( self ) :
self.vLayout.addWidget( SubWidget( self ) )
# self.vLayout.addWidget( loadUi( 'sub-something.ui', self ) )
if __name__ == "__main__" :
app = QApplication( [] )
w = Window()
w.show()
app.exec_()
You migth be mistaken by using addWidget() on a QWidget and not a QLayout. Easiest fix on that part, would be adding a layout to your widget:
vLayout = QVBoxLayout ()
UploadArea.setLayout( vLayout )
vLayout.addWidget( loadUi( 'your_file.ui' ) )
please give us feedback, and if something fails, show us the traceback-print

wx Python subclass Dialog

I have a source file containing the following:
class Dialog1 ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Hello", pos = wx.DefaultPosition, size = wx.Size( 342,253 ), style = wx.DEFAULT_DIALOG_STYLE )
Im trying to instantiate this in another source file like so:
dlg = Dialog1(wx.Dialog).__init__(self, None)
However, I get the following error:
Traceback (most recent call last):
File "scripts\motors\motors.py", line 281, in onListOption
dlg = Dialog1(wx.Dialog).__init__(self, None)
File "...",
line 21, in __init__
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Hello", pos = wx.DefaultPosition, size = wx.Size( 342,253 ), style = wx.DEFAULT_DIALOG_STYLE )
File "c:\Python27\lib\site-packages\wx-3.0-msw\wx\_windows.py", line 734, in __init__
_windows_.Dialog_swiginit(self,_windows_.new_Dialog(*args, **kwargs))
TypeError: in method 'new_Dialog', expected argument 1 of type 'wxWindow *'
Any idea why this is happening? I have tried passing wx.Window to the Dialog init but it doesnt make a difference. Can't someon explain why this is happening?
dlg = Dialog1(parent_window)
is the way to go. Where parent_window will be the parent of the dialog. See classes in Python.
Quoting from the link:
When a class defines an init() method, class instantiation
automatically invokes init() for the newly-created class instance.
Here is a working minimal code snippet:
import wx
class Dialog1 ( wx.Dialog ):
def __init__( self, parent ):
wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Hello",
pos = wx.DefaultPosition, size = wx.Size( 342,253 ),
style = wx.DEFAULT_DIALOG_STYLE )
app = wx.App()
dlg = Dialog1(None)
dlg.Show()
app.MainLoop()

Send text to textbox from arbitrary object (Python and Qt)

I need to be able to send text from class "node" in node.py:
import datetime
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class node( QGraphicsItem ):
def __init__( self, position, scene ):
super( node, self ).__init__( None, scene )
self.setFlags( QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable )
self.rect = QRectF( -30, -30, 120, 60 )
self.setPos( position )
scene.clearSelection()
def sendFromNodeToBox( self, text ):
# how do i send text from here to textBox?
pass
def boundingRect( self ):
return self.rect
def paint( self, painter, option, widget ):
painter.setRenderHint( QPainter.Antialiasing )
pen = QPen( Qt.SolidLine )
pen.setColor( Qt.black )
pen.setWidth( 3 )
if option.state & QStyle.State_Selected:
#####################
self.sendFromNodeToBox( 'node selected' )
#####################
self.setZValue( 1 )
pen.setWidth( 4 )
pen.setColor( Qt.green )
else:
pen.setWidth( 3 )
self.setZValue( 0 )
painter.setPen( pen )
painter.setBrush( QColor( 200, 0, 0 ) )
painter.drawRoundedRect( self.rect, 10.0, 10.0 )
to statusBox in mainWindow.ui, which is being loaded by mainWindow.py
import os, sip, sys, subprocess, platform
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.uic import *
from PyQt4.QtOpenGL import *
from src.node import *
app = None
class mainWindow( QMainWindow ):
def __init__( self, parent = None ):
super( mainWindow, self ).__init__( parent )
self.currentPlatform = platform.system()
if self.currentPlatform == "Windows":
self.ui = loadUi( r'ui\mainWindow.ui', self )
elif self.currentPlatform == "Darwin":
self.ui = loadUi( r'ui/mainWindow.ui', self )
else:
print 'platform not supported'
quit()
# Scene view
self.scene = SceneView()
self.nodeDropGraphicsView.setViewport( QGLWidget( QGLFormat( QGL.SampleBuffers ) ) )
self.nodeDropGraphicsView.setScene( self.scene )
self.sendTextToBox( 'this text comes from mainWindow class, line 37 and 38.\n' )
self.sendTextToBox( 'press right mouse button.\n' )
def sendTextToBox( self, text ):
cursorBox = self.statusBox.textCursor()
cursorBox.movePosition(cursorBox.End)
cursorBox.insertText( str( text ) )
self.statusBox.ensureCursorVisible()
class SceneView( QGraphicsScene ):
def __init__( self, parent=None ):
super( SceneView, self ).__init__( parent )
text = self.addText( 'title' )
def mousePressEvent( self, event ):
pos = event.scenePos()
if event.button() == Qt.MidButton:
pass
elif event.button() == Qt.RightButton:
newNode = node( pos, self )
super( SceneView, self ).mousePressEvent( event )
def mouseReleaseEvent( self, event ):
print 'mouseReleaseEvent'
self.line = None
super( SceneView, self ).mouseReleaseEvent( event )
if __name__ == "__main__":
app = QApplication( sys.argv )
screenSize = QApplication.desktop().availableGeometry()
window = mainWindow()
window.resize( int( screenSize.width() ), int( screenSize.height() ) )
window.show()
app.exec_()
App runs on win and osx. Linux not tested yet.
Python 2.7 and Qt 4.8 required.
Any suggestions?
The full source is here:
https://www.dropbox.com/sh/lcetrurnemr2cla/AAD-Z6ijgTrG0qVU_cum5viua?dl=0
Help is being much appreciated.
One way to do this would be to define a custom signal on the SceneView class, and then the graphics item can emit the text via its scene:
class node( QGraphicsItem ):
...
def sendFromNodeToBox( self, text ):
self.scene().textMessage.emit(text)
class SceneView( QGraphicsScene ):
textMessage = pyqtSignal(str)
class mainWindow( QMainWindow ):
def __init__( self, parent = None ):
...
self.scene = SceneView()
self.scene.textMessage.connect(self.sendTextToBox)

How can i set labels of QHeaderView in PyQt?

In Pyqt, I am trying to make the QHeaderView of a QTableWidget respond to right mouse clicks.
I have subclassed QHeaderView and i have overloaded the mousePressEvent.
Then i can set it as as the header of my custom QTableWidget, the DataTable class. However i don't understand how to set the labels of the header.
Thanks for helping!
Here is some code.
class Header( QtGui.QHeaderView ):
def __init__ ( self, parent ):
QtGui.QHeaderView.__init__( self, QtCore.Qt.Vertical, parent=parent )
def mousePressEvent( self, event ):
if event.button() == QtCore.Qt.RightButton:
do_stuff()
class DataTable( QtGui.QTableWidget ):
def __init__ ( self ):
QtGui.QTableWidget.__init__( self )
self.setShowGrid(True)
self.header = Header( parent = self )
self.header.setClickable(True)
self.setHorizontalHeader( self.header )
def set_header( self, labels ):
???
This sample code should be useful:
import sys
import string
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Header(QHeaderView):
def __init__(self, parent=None):
super(Header, self).__init__(Qt.Horizontal, parent)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.ctxMenu)
self.hello = QAction("Hello", self)
self.hello.triggered.connect(self.printHello)
self.currentSection = None
def printHello(self):
data = self.model().headerData(self.currentSection, Qt.Horizontal)
print data.toString()
def ctxMenu(self, point):
menu = QMenu(self)
self.currentSection = self.logicalIndexAt(point)
menu.addAction(self.hello)
menu.exec_(self.mapToGlobal(point))
class Table(QTableWidget):
def __init__(self, parent=None):
super(Table, self).__init__(parent)
self.setHorizontalHeader(Header(self))
self.setColumnCount(3)
self.setHorizontalHeaderLabels(['id', 'name', 'username'])
self.populate()
def populate(self):
self.setRowCount(10)
for i in range(10):
for j,l in enumerate(string.letters[:3]):
self.setItem(i, j, QTableWidgetItem(l))
if __name__ == '__main__':
app = QApplication(sys.argv)
t = Table()
t.show()
app.exec_()
sys.exit()
Short answer:
The QTableWidget has a function called "setHorizontalHeaderLabels", simply supply your headers to it. Like so:
your_table_widget.setHorizontalHeaderLabels(["name", "phone number", "email"])
I would have added this as a comment to pedrotech, but I don't have enough rep for comments.

PyQt4 Gui designing

I just started to lear the PyQt, but I got some problem. Here is my code:
class GUI( QtGui.QMainWindow ):
'''
classdocs
'''
"""**********************************************************************"""
""" Constructor """
"""**********************************************************************"""
def __init__( self, parent = None ):
self.app = QtGui.QApplication( sys.argv )
QtGui.QMainWindow.__init__( self )
"""******************************************************************"""
""" Settintg up the windows """
"""******************************************************************"""
self.resize( 1024, 756 )
self.setWindowTitle( 'Windscanner - Core Module' )
self.setWindowIcon( QtGui.QIcon( 'icons/Windsock.png' ) )
""" Text Area """
self.messageField = QtGui.QTextEdit() # Alternative: QTextEdit
self.messageField.setReadOnly( True )
""" Input """
self.inputLine = QtGui.QLineEdit()
""" Send Button """
sendButton = QtGui.QPushButton( 'TCP: Send' )
sendButton.setStatusTip( 'Send manually inserted message via TCP' )
sendButton.setToolTip( 'Send manually inserted message via TCP' )
self.connect( sendButton, QtCore.SIGNAL( 'clicked()' ), self.f_sendbutton )
sendButton.setGeometry( 300, 300, 250, 150 );
""" Layout """
mainLayout = QtGui.QGridLayout()
mainLayout.addWidget( self.messageField )
mainLayout.addWidget( self.inputLine )
mainLayout.addWidget( sendButton )
""" Widget """
mainWidget = QtGui.QWidget()
mainWidget.setLayout( mainLayout )
self.setCentralWidget( mainWidget )
self.show()
sys.exit( self.app.exec_() )
My question is how can I define the size and geometry of the textarea and the button?
I tryed to use the
setGeometry()
but it not really working.
You can use:
sendButton.setMinimumSize()
and
mainLayout.setRowMinimumHeight()

Categories