小部件上的 PyQt 标签定位
PyQt label positioning on widget
我创建了一个简单的 arduino 项目。我的项目的主要目的是根据 PIN 状态(1 或 0)在 LCD 屏幕上显示文本。
为此,我创建了一个简单的表单并在其上添加了一个标签。启动时它显示默认文本,但是当我按下菜单按钮(模拟 PIN =1)时,文本更改为 "WARNING_TEXT"
这是我的 Python 代码(这是我的应用程序的入口点):
import sys
from forms import MainForm2
import os
from PyQt4.QtGui import *
def main():
app, window = MainForm2.init()
p = app.desktop().availableGeometry().center()
window.move(p.x()-window.width()*0.5,p.y()-window.height()*0.5)
window.setWindowTitle('Monitor') #<=Nazvanie app
window.showMaximized()
sys.exit(app.exec_())
if __name__ =="__main__":
main()
MainForm2代码(所有应用逻辑都在这里):
# -*- coding: utf-8 -*-
from PyQt4 import QtGui,QtCore
from PyQt4.QtGui import QSizePolicy,QColor
import sys
import time
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class QMainWindow(QtGui.QMainWindow):
defaultStyle ='color:green;font-size:240px'
warningStyle ='color:red;text-align: justify;font-size:{0}px'
def __init__(self,parent=None):
super(QtGui.QMainWindow,self).__init__(parent)
self.cnfVacant = "Default text"
self.cnfBusy = "Warning text"
self.setupUi()
def setupUi(self):
self.thread=QMyThread()
#timer
self.timer = QtCore.QTimer()
self.timer.setInterval(1000)
self.timer.timeout.connect(self.displayTime)
self.main = QtGui.QWidget(self)
self.main.setAutoFillBackground(True)
p = self.main.palette()
p.setColor(self.main.backgroundRole(),QColor.fromRgb(0,0,0,255))
self.main.setPalette(p)
self.setCentralWidget(self.main)
self.menubar = QtGui.QMenuBar(self)
self.menubar.setGeometry(QtCore.QRect(0,0,559,25))
#trigger
self.menu_file_exit =QtGui.QAction(self.main)
self.menu_file_exit.setText("Exit")
self.menu_file_start = QtGui.QAction(self.main)
self.menu_file_start.setText("Start")
layout = QtGui.QGridLayout(self.main)
self.label = QtGui.QLabel("",self.main)
self.label.setText(_fromUtf8(self.cnfVacant.replace(" ","\n")))
self.label.setStyleSheet(self.defaultStyle)
self.label.setSizePolicy (QSizePolicy.Fixed,QSizePolicy.Expanding)
self.label.setSizePolicy (QSizePolicy.Fixed,QSizePolicy.Expanding)
layout.addWidget(self.label,10,10)
layout.addWidget(self.lbl,50,50)
self.connect(self.menu_file_exit, QtCore.SIGNAL('triggered()'), sys.exit)
self.connect(self.menu_file_start,QtCore.SIGNAL('triggered()'),self.thread.run)
QtCore.QObject.connect(self.thread,QtCore.SIGNAL('log(QString)'),self.tmp)
self.menu_file = self.menubar.addMenu("File")
self.menu_file.addAction(self.menu_file_start)
self.menu_file.addAction(self.menu_file_exit)
self.setMenuBar(self.menubar)
def tmp(self,s):
self.label.setText(_fromUtf8(self.cnfBusy))
self.label.setWordWrap(True)
self.label.setStyleSheet(self.warningStyle)
self.label.setStyleSheet(self.warningStyle.format(self.cnfWarning[0]))
print 'Hello sub {0}'.format(s)
def displayTime(self):
mDate=QtCore.QDateTime.currentDateTime().toString("dd.MM.yyyy")
mTime=QtCore.QDateTime.currentDateTime().toString("HH:mm:ss")
self.lbl.setText("{0} \n {1}".format(mDate,mTime))
class QMyThread(QtCore.QThread):
def __init__(self,parent=None):
super(QtCore.QThread,self).__init__(parent)
def run(self):
i=0
while True:
i=i+1
if(i==10):
self.setLog("Hello from thread")
time.sleep(0.3)
break
def setLog(self,text):
self.emit(QtCore.SIGNAL('log(QString)'),QtCore.QString(text))
def init():
app = QtGui.QApplication(sys.argv)
MainWindow =QMainWindow()
MainWindow.show()
return app, MainWindow
使用这段代码,我只得到一个以表格为中心的标签,但我遇到了两个问题:
长文本显示不正确。类似于“bla bla blabla blablabla bla”
如何获取表格右下角的第二个标签?
我想得到类似的图片:
谁能指点我,怎么做?
在解决问题之前,我将指出您的代码可以进行的改进:
- 不要使用旧的连接方式,检查new style。
- 如果您不打算修改继承的class,则无需编写构造函数。
- 不应该直接调用
QThread
的run()
方法,否则任务会运行在主线程上,显然不是必须发送,必须调用 start()
方法,这会在内部创建线程,并且 run()
方法将在该线程上执行。请记住 QThread
不是线程,它是线程处理程序。
- 不要使用与您继承的 class 相同的名称,这会给您带来以后难以调试的问题。
说到重点,只需要使用布局建立第一个 QLabel
,然后使用 setAlignment()
将其居中,传递它 QtCore.Qt.AlignCenter
告诉它水平聚焦和垂直。
另一个 QLabel
显示您必须在几何体中手动移动它的时间,每次修改 QLabel
时都必须这样做,所以我们使用 resizeEvent
和更新文本的方法。
# -*- coding: utf-8 -*-
import sys
import time
from PyQt4 import QtGui, QtCore
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
defaultStyle ='color:green;font-size: 60px'
warningStyle ='color:red;text-align: justify;font-size:{0}px'
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
widget = QtGui.QWidget()
self.setCentralWidget(widget)
self.label = QtGui.QLabel("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vitae laoreet erat. Donec eleifend erat sapien. Morbi velit est, pellentesque vel fringilla eget, rhoncus nec sem. Curabitur rutrum sodales luctus. Nulla vel aliquam leo. Pellentesque non ante at nisl pulvinar posuere vel vel orci.")
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setWordWrap(True)
self.label.setStyleSheet(defaultStyle)
pal = widget.palette()
pal.setColor(widget.backgroundRole(), QtGui.QColor.fromRgb(0,0,0,255))
widget.setPalette(pal)
widget.setAutoFillBackground(True)
self.lbl = QtGui.QLabel(widget)
self.lbl.setStyleSheet("*{color:green; font-size:48px}")
timer = QtCore.QTimer(self)
timer.timeout.connect(self.displayTime)
timer.start(1000)
self.displayTime()
menubar = QtGui.QMenuBar()
self.setMenuBar(menubar)
menu_file = menubar.addMenu("File")
menu_file_exit = menu_file.addAction("Exit")
menu_file_start = menu_file.addAction("Start")
menu_file_exit.triggered.connect(self.close)
self.mthread = QMyThread(self)
self.mthread.log.connect(self.fun)
menu_file_start.triggered.connect(self.mthread.start)
lay = QtGui.QVBoxLayout(widget)
lay.addWidget(self.label)
def fun(self, s):
self.label.setStyleSheet(warningStyle.format(100))
self.label.setText(s)
def displayTime(self):
text = QtCore.QDateTime.currentDateTime().toString("dd.MM.yyyy \n HH:mm:ss")
self.lbl.setText(_fromUtf8(text))
self.lbl.adjustSize()
self.adjustLabel()
def adjustLabel(self):
p = self.lbl.parent().rect().bottomRight() - self.lbl.rect().bottomRight()
self.lbl.move(p)
def resizeEvent(self, event):
QtGui.QMainWindow.resizeEvent(self, event)
self.adjustLabel()
class QMyThread(QtCore.QThread):
log = QtCore.pyqtSignal(QtCore.QString)
def run(self):
i=0
while True:
i+= 1
if i==10:
self.setLog("Hello from thread")
time.sleep(0.3)
break
def setLog(self,text):
self.log.emit(QtCore.QString(text))
def init():
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
return app, w
我创建了一个简单的 arduino 项目。我的项目的主要目的是根据 PIN 状态(1 或 0)在 LCD 屏幕上显示文本。
为此,我创建了一个简单的表单并在其上添加了一个标签。启动时它显示默认文本,但是当我按下菜单按钮(模拟 PIN =1)时,文本更改为 "WARNING_TEXT"
这是我的 Python 代码(这是我的应用程序的入口点):
import sys
from forms import MainForm2
import os
from PyQt4.QtGui import *
def main():
app, window = MainForm2.init()
p = app.desktop().availableGeometry().center()
window.move(p.x()-window.width()*0.5,p.y()-window.height()*0.5)
window.setWindowTitle('Monitor') #<=Nazvanie app
window.showMaximized()
sys.exit(app.exec_())
if __name__ =="__main__":
main()
MainForm2代码(所有应用逻辑都在这里):
# -*- coding: utf-8 -*-
from PyQt4 import QtGui,QtCore
from PyQt4.QtGui import QSizePolicy,QColor
import sys
import time
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class QMainWindow(QtGui.QMainWindow):
defaultStyle ='color:green;font-size:240px'
warningStyle ='color:red;text-align: justify;font-size:{0}px'
def __init__(self,parent=None):
super(QtGui.QMainWindow,self).__init__(parent)
self.cnfVacant = "Default text"
self.cnfBusy = "Warning text"
self.setupUi()
def setupUi(self):
self.thread=QMyThread()
#timer
self.timer = QtCore.QTimer()
self.timer.setInterval(1000)
self.timer.timeout.connect(self.displayTime)
self.main = QtGui.QWidget(self)
self.main.setAutoFillBackground(True)
p = self.main.palette()
p.setColor(self.main.backgroundRole(),QColor.fromRgb(0,0,0,255))
self.main.setPalette(p)
self.setCentralWidget(self.main)
self.menubar = QtGui.QMenuBar(self)
self.menubar.setGeometry(QtCore.QRect(0,0,559,25))
#trigger
self.menu_file_exit =QtGui.QAction(self.main)
self.menu_file_exit.setText("Exit")
self.menu_file_start = QtGui.QAction(self.main)
self.menu_file_start.setText("Start")
layout = QtGui.QGridLayout(self.main)
self.label = QtGui.QLabel("",self.main)
self.label.setText(_fromUtf8(self.cnfVacant.replace(" ","\n")))
self.label.setStyleSheet(self.defaultStyle)
self.label.setSizePolicy (QSizePolicy.Fixed,QSizePolicy.Expanding)
self.label.setSizePolicy (QSizePolicy.Fixed,QSizePolicy.Expanding)
layout.addWidget(self.label,10,10)
layout.addWidget(self.lbl,50,50)
self.connect(self.menu_file_exit, QtCore.SIGNAL('triggered()'), sys.exit)
self.connect(self.menu_file_start,QtCore.SIGNAL('triggered()'),self.thread.run)
QtCore.QObject.connect(self.thread,QtCore.SIGNAL('log(QString)'),self.tmp)
self.menu_file = self.menubar.addMenu("File")
self.menu_file.addAction(self.menu_file_start)
self.menu_file.addAction(self.menu_file_exit)
self.setMenuBar(self.menubar)
def tmp(self,s):
self.label.setText(_fromUtf8(self.cnfBusy))
self.label.setWordWrap(True)
self.label.setStyleSheet(self.warningStyle)
self.label.setStyleSheet(self.warningStyle.format(self.cnfWarning[0]))
print 'Hello sub {0}'.format(s)
def displayTime(self):
mDate=QtCore.QDateTime.currentDateTime().toString("dd.MM.yyyy")
mTime=QtCore.QDateTime.currentDateTime().toString("HH:mm:ss")
self.lbl.setText("{0} \n {1}".format(mDate,mTime))
class QMyThread(QtCore.QThread):
def __init__(self,parent=None):
super(QtCore.QThread,self).__init__(parent)
def run(self):
i=0
while True:
i=i+1
if(i==10):
self.setLog("Hello from thread")
time.sleep(0.3)
break
def setLog(self,text):
self.emit(QtCore.SIGNAL('log(QString)'),QtCore.QString(text))
def init():
app = QtGui.QApplication(sys.argv)
MainWindow =QMainWindow()
MainWindow.show()
return app, MainWindow
使用这段代码,我只得到一个以表格为中心的标签,但我遇到了两个问题:
长文本显示不正确。类似于“bla bla blabla blablabla bla”
如何获取表格右下角的第二个标签?
我想得到类似的图片:
谁能指点我,怎么做?
在解决问题之前,我将指出您的代码可以进行的改进:
- 不要使用旧的连接方式,检查new style。
- 如果您不打算修改继承的class,则无需编写构造函数。
- 不应该直接调用
QThread
的run()
方法,否则任务会运行在主线程上,显然不是必须发送,必须调用start()
方法,这会在内部创建线程,并且run()
方法将在该线程上执行。请记住QThread
不是线程,它是线程处理程序。 - 不要使用与您继承的 class 相同的名称,这会给您带来以后难以调试的问题。
说到重点,只需要使用布局建立第一个 QLabel
,然后使用 setAlignment()
将其居中,传递它 QtCore.Qt.AlignCenter
告诉它水平聚焦和垂直。
另一个 QLabel
显示您必须在几何体中手动移动它的时间,每次修改 QLabel
时都必须这样做,所以我们使用 resizeEvent
和更新文本的方法。
# -*- coding: utf-8 -*-
import sys
import time
from PyQt4 import QtGui, QtCore
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
defaultStyle ='color:green;font-size: 60px'
warningStyle ='color:red;text-align: justify;font-size:{0}px'
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
widget = QtGui.QWidget()
self.setCentralWidget(widget)
self.label = QtGui.QLabel("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vitae laoreet erat. Donec eleifend erat sapien. Morbi velit est, pellentesque vel fringilla eget, rhoncus nec sem. Curabitur rutrum sodales luctus. Nulla vel aliquam leo. Pellentesque non ante at nisl pulvinar posuere vel vel orci.")
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setWordWrap(True)
self.label.setStyleSheet(defaultStyle)
pal = widget.palette()
pal.setColor(widget.backgroundRole(), QtGui.QColor.fromRgb(0,0,0,255))
widget.setPalette(pal)
widget.setAutoFillBackground(True)
self.lbl = QtGui.QLabel(widget)
self.lbl.setStyleSheet("*{color:green; font-size:48px}")
timer = QtCore.QTimer(self)
timer.timeout.connect(self.displayTime)
timer.start(1000)
self.displayTime()
menubar = QtGui.QMenuBar()
self.setMenuBar(menubar)
menu_file = menubar.addMenu("File")
menu_file_exit = menu_file.addAction("Exit")
menu_file_start = menu_file.addAction("Start")
menu_file_exit.triggered.connect(self.close)
self.mthread = QMyThread(self)
self.mthread.log.connect(self.fun)
menu_file_start.triggered.connect(self.mthread.start)
lay = QtGui.QVBoxLayout(widget)
lay.addWidget(self.label)
def fun(self, s):
self.label.setStyleSheet(warningStyle.format(100))
self.label.setText(s)
def displayTime(self):
text = QtCore.QDateTime.currentDateTime().toString("dd.MM.yyyy \n HH:mm:ss")
self.lbl.setText(_fromUtf8(text))
self.lbl.adjustSize()
self.adjustLabel()
def adjustLabel(self):
p = self.lbl.parent().rect().bottomRight() - self.lbl.rect().bottomRight()
self.lbl.move(p)
def resizeEvent(self, event):
QtGui.QMainWindow.resizeEvent(self, event)
self.adjustLabel()
class QMyThread(QtCore.QThread):
log = QtCore.pyqtSignal(QtCore.QString)
def run(self):
i=0
while True:
i+= 1
if i==10:
self.setLog("Hello from thread")
time.sleep(0.3)
break
def setLog(self,text):
self.log.emit(QtCore.QString(text))
def init():
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
return app, w