30/09/2018, 16:47

Sử dụng Qt Creator làm đồ họa

Đồ án năm nhất của em yêu cầu làm một chương trình biểu diễn đồ họa các thao tác trên danh sách liên kết đơn như thêm node ở đầu, cuối,… Em dùng Qt để làm. Em cũng làm được kha khá, nhưng đang bị bí ở phần duyệt từ đầu đến cuối danh sách, duyệt đến đâu sẽ hiển thị giá trị của node đó. Source code của em như vậy nè, Square được kế thừa từ lớp QGraphicsItem, Node gồm một Square và Node *next:

void Dialog::traverse()
{
    Node *cur = head;
    timer = new QTimer(this);
    while (cur)
    {
        connect(timer, SIGNAL(timeout()), cur->square, SLOT(changeColor()));
        timer->start(3000);
        cur = cur->next;
    }
}

Khi chạy chương trình, thay vì từng hình vuông sẽ đổi màu lần lượt, thì chúng lại đổi màu cùng lúc luôn chứ. Em nghĩ là do hàm update( ) nên đến khi chạy tới event loop thì graphicsView mới vẽ lại. Em tính xài hàm repaint( ), nhưng hàm này không được sử dụng cho QGraphicsItem mới đau chứ. Mấy anh chị giúp em với, em biết ơn nhiều nhiều.

Nguyễn Minh Dũng viết 19:00 ngày 30/09/2018

@nguyenchiemminhvu can you help him?

... viết 19:02 ngày 30/09/2018

Em chưa tìm hiểu về QGraphicItem, nhưng em thấy nếu để timer->start() trong while là nó sẽ bị kích hoạt nhiều lần, thấy hơi có vấn đề ở chổ đó. Em thường chỉ kích hoạt timer 1 lần trong 1 slots riêng hoặc ngay khi khởi tạo thôi.


Thử dùng QTimer::singleShot() trong while xem thế nào
Trung Đặng viết 18:58 ngày 30/09/2018

Em cũng không biết danh sách sẽ có bao nhiêu phần tử nên em dùng vòng lặp while, không biết có sai không nữa. Em thử thêm timer->setSingleShot(true); rồi mà cũng không giải quyết được.

... viết 18:47 ngày 30/09/2018

À dùng singleShot không cần đến timer đâu.
singleShot() là static public function của class QTimer, nên cần dùng thì cứ gọi ví dụ như này:

QTimer::singleShot(600000, &app, SLOT(quit()));

Tác dụng của singleShot là chỉ tác dụng vào SLOT 1 lần duy nhất sau khoảng thời gian ở argument đầu tiên.

Thử thay vào đoạn code nhỏ của bạn thì nó sẽ ra như này:

while (cur)
    {
        //connect(timer, SIGNAL(timeout()), cur->square, SLOT(changeColor()));
        //timer->start(3000);
        QTimer::singleShot(3000,cur-square,SLOT(changeColor()));
        cur = cur->next;
    }

Mình không biết cấu trúc các class bạn tạo ra như thế nào nên mình chỉ biết nói ngang đó thôi.
Trung Đặng viết 18:47 ngày 30/09/2018

Hay mình gửi bạn (hay ai đó rành Qt) source code của mình qua mail, chứ up ở đây thì không tiện lắm. Quá trời nhiều files luôn.

Nguyễn Minh Dũng viết 18:55 ngày 30/09/2018

Hay mình gửi bạn (hay ai đó rành Qt) source code của mình qua mail, chứ up ở đây thì không tiện lắm. Quá trời nhiều files luôn.

Bạn lên stackoverflow xem người ta hỏi cả trăm ngàn câu hỏi, có ai gửi cả project lên để hỏi không? Chọn cái nào mà bạn nghĩ cần thiết, gửi lên cho mọi người xem. Việc gửi một project lớn cho người khác xem là tối kị.

Đừng giận nhé, mình chỉ góp ý sao cho việc thảo luận lập trình tốt hơn thôi.

Nguyen Hai viết 18:51 ngày 30/09/2018

Khi thằng cur-square đổi màu mới thì thằng cur phải đổi màu lại như ban đầu thì mới giống đang duyệt các các node được chứ? nhìn code trên có vẻ chỉ lo đổi màu cho thằng cur-square thôi!
không thì gửi source đây, xem hộ cho

Trung Đặng viết 19:00 ngày 30/09/2018

Mình làm được rồi. Cám ơn mọi người nhiều.

... viết 18:57 ngày 30/09/2018

Bạn có thể chia sẻ cho mọi người biết cách bạn giải quyết được vấn đề không?

Đỗ Mạnh Hà viết 18:54 ngày 30/09/2018

Mình không làm về Qt nà nhưng theo mình thấy thì bạn đã fix cứng 1 khoảng thời gian cố định nó sẽ gọi hàm callback cho nên nó đổi màu cùng 1 lúc là điều hiển nhiên thôi mà bạn. Bạn có thể set time riêng cho từng rect vậy là OK.

Trung Đặng viết 18:49 ngày 30/09/2018

Mình xài QSequentialAnimationGroup class á

Bài liên quan
0