• 10735阅读
  • 18回复

QThread中的奇怪问题 [复制链接]

上一主题 下一主题
离线紫露霜凝
 
只看楼主 倒序阅读 楼主  发表于: 2010-08-10
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
在QThread建立的线程中使用QFontMetrics中的width(QChar)获取单个字符宽度有问题,同一字号下读取所有字符宽度都是一样的
部分代码如下:
QFontMetrics fm = QFontMetrics::QFontMetrics(font);
    QString s1="iabcomn";
    int size=s1.size();
    int sint;
    for(int i=0;i<size;i++)
    {
        sint=fm.width(s1.at(i));
    }
将此段程序加入run()中时,所有字符宽度一样;倘若加入QThread内与run()无关的函数中则可获取正确的字符宽度。
不知是什么原因引起,也不知怎么解决,期待知情者给予提示,谢谢先。

离线dbzhang800

只看该作者 1楼 发表于: 2010-08-10
很关键的一个问题,两处你用的 font 一样吗? 输出 font.family() 看看
离线紫露霜凝
只看该作者 2楼 发表于: 2010-08-10
回 1楼(dbzhang800) 的帖子
谢谢,我就算是重新的设定family和setPointSize也是有同样的问题
离线dbzhang800

只看该作者 3楼 发表于: 2010-08-10
Re:回 1楼(dbzhang800) 的帖子
引用第2楼紫露霜凝于2010-08-10 17:16发表的 回 1楼(dbzhang800) 的帖子 :
谢谢,我就算是重新的设定family和setPointSize也是有同样的问题

你可以贴段代码出来看看

我下面的测试没发现你说的问题:
结果:
main thread
3 7 7 7 7 11 7
sub thread
3 7 7 7 7 11 7


代码:
  1. import sys
  2. from PyQt4.QtCore import *
  3. from PyQt4.QtGui import *
  4. def fontWidth(font):
  5.     fm = QFontMetrics(font)
  6.     s1 = "iabcomn"
  7.     for i in s1:
  8.         print fm.width(i),
  9.     print ''
  10. class Thread(QThread):
  11.     def __init__(self, parent=None):
  12.         super(Thread, self).__init__(parent)
  13.     def run(self):
  14.         fontWidth(qApp.font())
  15. app = QCoreApplication(sys.argv)
  16. print "main thread"
  17. fontWidth(qApp.font())
  18. print "sub thread"
  19. thread = Thread()
  20. thread.finished.connect(qApp.quit)
  21. thread.start()
  22. app.exec_()

离线紫露霜凝
只看该作者 4楼 发表于: 2010-08-11
回 3楼(dbzhang800) 的帖子
void MessageThread::run() {
    while (!stopped) {
        cerr << qPrintable(msg) << endl;
        QThread::sleep(1);
    }
    QFontMetrics fm = QFontMetrics::QFontMetrics(font);
    QString s1="iabcomn";
    int size=s1.size();
    int sint;
    for(int i=0;i<size;i++)
    {
        sint=fm.width(s1.at(i));
        qDebug()<<sint;
    }
    stopped=false;
}
全部源码附上,其中sint大小同一字号下相同
附件: MessageThread.tar.gz (443 K) 下载次数:5
离线dbzhang800

只看该作者 5楼 发表于: 2010-08-11
Re:回 3楼(dbzhang800) 的帖子
引用第4楼紫露霜凝于2010-08-11 10:11发表的 回 3楼(dbzhang800) 的帖子 :
void MessageThread::run() {
    while (!stopped) {
        cerr << qPrintable(msg) << endl;
        QThread::sleep(1);
    }
.......

看了一下,感觉前面的话有点白说了,你的font 竟然没指定任何字体,而是采用的QFont的默认构造函数(你如何保证这个不是等宽字体?)。

在你的线程的构造函数内,添加下面的代码试试
qDebug()<<font.family();
font.setFamily("Helvetica");
qDebug()<<font.family();
离线紫露霜凝
只看该作者 6楼 发表于: 2010-08-11
回 5楼(dbzhang800) 的帖子
QFont font;
font.setFamily(QString::fromLocal8Bit("Wenquanyi Bitmap Song"));
  font.setPointSize(11);
加上设定字体也是一样的效果,应该不可能是等宽字体,因为如果不在run()获取,就不会有这种错误。你用我附上的程序改改,看看是不是我什么地方弄错了
离线dbzhang800

只看该作者 7楼 发表于: 2010-08-11
Re:回 5楼(dbzhang800) 的帖子
引用第6楼紫露霜凝于2010-08-11 11:06发表的 回 5楼(dbzhang800) 的帖子 :
QFont font;
font.setFamily(QString::fromLocal8Bit("Wenquanyi Bitmap Song"));
  font.setPointSize(11);
加上设定字体也是一样的效果,应该不可能是等宽字体,因为如果不在run()获取,就不会有这种错误。你用我附上的程序改改,看看是不是我什么地方弄错了

加上我前面的那三行代码,贴出运行结果看看
离线紫露霜凝
只看该作者 8楼 发表于: 2010-08-11
Re:Re:回 5楼(dbzhang800) 的帖子
引用第7楼dbzhang800于2010-08-11 11:21发表的 Re:回 5楼(dbzhang800) 的帖子 :
加上我前面的那三行代码,贴出运行结果看看



代码:
qDebug()<<font.family();
    font.setFamily("Helvetica");
    qDebug()<<font.family();
    QFontMetrics fm = QFontMetrics(font);

    QString s1="abciomn";
    int size=s1.size();
    int sint;
    for(int i=0;i<size;i++)
    {
        sint=fm.width(s1.at(i));
        qDebug()<<sint;
    }
运行结果:

离线dbzhang800

只看该作者 9楼 发表于: 2010-08-11
Re:Re:Re:回 5楼(dbzhang800) 的帖子
引用第8楼紫露霜凝于2010-08-11 11:43发表的 Re:Re:回 5楼(dbzhang800) 的帖子 :
代码:
qDebug()<<font.family();
    font.setFamily("Helvetica");
.......

其实我想看到的是,你能拿出证据证明:你的同一个字体,在主线程和次线程中的表现是一样还是不一样。

就想我我那段PyQt代码所写的,同一个字体:QApplication::font()返回的字体。在主次线程分别输出结果对比。

如果二者不一致,说明Qt的bug。如果二者一致,说明Qt没问题,最大可能就是你自己在系统字体搞乱了(比如:自己调整过字体,进行过美化一类的)。

我在Windows xp xp3, 及 Ubuntu 10.04 下,都没发现你提到的问题。
离线紫露霜凝
只看该作者 10楼 发表于: 2010-08-11
回 9楼(dbzhang800) 的帖子
主线程和次线程是同一个字体,我用的也是ubuntu啊
离线紫露霜凝
只看该作者 11楼 发表于: 2010-08-11
回 9楼(dbzhang800) 的帖子
能给我传一个在你那运行没这个问题的简单实例吗?谢谢拉
离线ieasylive

只看该作者 12楼 发表于: 2010-08-11
  1. #include <iostream>
  2. #include <QtGui>
  3. #include <QApplication>
  4. int main(int argc, char *argv[])
  5. {
  6.     QApplication app(argc, argv);
  7.     QFont font("Sreif");
  8.     QFontMetrics fontM(font);
  9.     QString s = "iabcomn";
  10.     for(int i = 0; i < s.length(); i++)
  11.         std::cout<<i<<"\t"<<fontM.width(s.at(i))<<std::endl;
  12.     return app.exec();
  13. }
离线dbzhang800

只看该作者 13楼 发表于: 2010-08-11
Re:回 9楼(dbzhang800) 的帖子
引用第11楼紫露霜凝于2010-08-11 14:13发表的 回 9楼(dbzhang800) 的帖子 :
能给我传一个在你那运行没这个问题的简单实例吗?谢谢拉

好吧,完整的程序。这样的应该是提问者贴的(^_^)

  1. #include <QtGui>
  2. #include <QtCore>
  3. static void fontInfo()
  4. {
  5.     QFont font("Helvetica");
  6.     QFontMetrics fm = QFontMetrics::QFontMetrics(font);
  7.     QString s1 = "iabcomn";
  8.     for(int i=0; i<s1.size(); i++)
  9.     {
  10.         qDebug()<<fm.width(s1.at(i));
  11.     }
  12. }
  13. class Thread : public QThread
  14. {
  15. public:
  16.     Thread(QObject * parent=NULL):QThread(parent)
  17.     {
  18.     }
  19.     void run()
  20.     {
  21.         qDebug()<<"from sub thread:";
  22.         fontInfo();
  23.     }
  24. };
  25. int main(int argc, char** argv)
  26. {
  27.     QApplication app(argc, argv);
  28.     qDebug()<<"from main thread:";
  29.     fontInfo();
  30.     Thread thread;
  31.     QObject::connect(&thread, SIGNAL(finished()), qApp, SLOT(quit()));
  32.     thread.start();
  33.     app.exec();
  34. }

离线紫露霜凝
只看该作者 14楼 发表于: 2010-08-11
回 13楼(dbzhang800) 的帖子
谢谢帮忙,可是怎么还是有问题,以下是运行结果:

from main thread:
3
8
7
7
8
11
8
from sub thread:
15
15
15
15
15
15
15
这到底是什么原因啊,我切换到windows下发现,主次线程宽度是一致的。有的程序也是所有字符宽度都一样,这应该与是否等宽字体有关,最起码一致了;可是在Ubuntu下怎么会宽度不一致了
离线紫露霜凝
只看该作者 15楼 发表于: 2010-08-11
回 12楼(ieasylive) 的帖子
谢谢,我需要的是带有次线程的例子,以验证主次线程在计算字符宽上的一致性
离线紫露霜凝
只看该作者 16楼 发表于: 2010-08-25
问题还没解决,搁置如此长时间,有遇到类似问题或者对这个感兴趣的,能否帮忙解决,真是快崩溃了!
离线jdwx

只看该作者 17楼 发表于: 2011-01-05
估计要好好看看QT的书了,我记得不太详细:QT的类不是所有的都是线程安全的,也就是说一部分类不能用于多线程!
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
离线jdwx

只看该作者 18楼 发表于: 2011-01-06
嗨!没仔细看代码,字体是“文泉雅黑”,windows里没有!哈哈!
代码没问题
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
快速回复
限100 字节
 
上一个 下一个